Thursday, June 14, 2007

Ethiopian Food in Amsterdam

Had some really nice food in Amsterdam last night, after a drink we ended up at an Ethiopian Restaurant suggested by Adam. I had some Gored Gored but we all ended up sharing as it came on a big plate. Good company and good food.

Loading Resources in Sakai Components

I meant to blog about this a while ago but it has recently come up again and so I though I should write my ideas down. Ok so the problem is that you have a Sakai component which is created by the component manager and it wants to load something from inside the component, in my case it was an iBatis configuration file specified through a spring configuration file. So in my spring config I have something like:
  
<property name="configLocation">
 classpath:/sql-maps-config.xml
</property>
Now the problem is that this property is loaded through a PropertyEditor which sets the property to a ClassPathResource. In Spring the classloading policy is that resources should be loaded through the thread's classloader. When the component manager is starting up and so when my component is create this is caused by the fact that a web application has asked for it so the thread classloader points to the webapp and the resource in your component won't be found.

The solution to this is to have a way to load resources using the standard JVM Class.getResourceAsStream() which will use the classloader used to load the current class. So I created an class:

package org.sakaiproject.util;

import org.springframework.core.io.ClassPathResource;

/**
* Resource implementation for class path resources.
* Loads out of the same classpath as this class was loaded through.
*
* Supports resolution as java.io.File if the class path
* resource resides in the file system, but not for resources in a JAR.
* Always supports resolution as URL.
*
* @author buckett
*/
public class LocalClassPathResource extends ClassPathResource {

 public LocalClassPathResource(String path) {
  super(path, LocalClassPathResource.class.getClassLoader());
 }
}

and put this in my component. I also then change the configuration in my components.xml to use the resource directly:

<property name="configLocation">
<bean class="org.sakaiproject.util.LocalClassPathResource">
 <constructor-arg type="java.lang.String">
  <value>/sql-maps-config.xml</value>
 </constructor-arg>
</bean>
</property>
Now the configuration file gets loaded without any problems. Hopefully future Sakai developments in the component manager will mean this hack isn't needed later on.

Tuesday, June 12, 2007

Safari 3 Beta and FCKEditor

Just saw in the news that Apple has release a Safari 3 Beta but include a Windows build, now this probably isn't going to take on IE and Firefox but does allow developers on Windows so have a better idea about how websites will render on it. Now it also allow people to see that FCKEditor nightly is working reasonably well in Safari.

Saturday, June 09, 2007

Plane on Google Maps

Found a plane on Google Maps today. You can even read the writing on it showing it's an Air Canada plane.

Friday, June 08, 2007

Sakai Maven Plugin Install

Always losing the command to install the Sakai Maven Plugin, Dr Chuck has some instructions but they rely on already having configured your maven repository. The one stop command is:

maven plugin:download -DgroupId=sakaiproject -DartifactId=sakai -Dversion=2.2 -Dmaven.repo.remote=http://source.sakaiproject.org/maven

This only works with maven 1. If nothing else maybe this will give Chucks second post a little more Google karma and push it up in search results.

Thursday, June 07, 2007

Custom Logging in Sakai

If you are debugging something in Sakai and want to setup a custom log configuration you can just edit your sakai.properties. Here's an example of from a sakai.properties file:
log.config.count=2
log.config.1 = DEBUG.org.sakaiproject.portal.charon.handlers.HierarchyHandler
log.config.2 = DEBUG.org.sakaiproject.portal.charon.handlers.SiteHandler

Wednesday, June 06, 2007

Don't forget Resource normally same as Entity

It seems originally org.sakaiproject.entity.api.Entity interface was called Resource and although most things seem to have been updated there are still some references across the codebase to Resources. An example is the org.sakaiproject.event.api.Event#getResource() method which actually returns a Entity reference.

Tuesday, June 05, 2007

Sakai Portal Handlers

Sakai has a reworked portal in 2.4 called the Charon Skinnable Portal and this portal has the concept of handlers which can be used to handle different requests. Most of this code is in portal/portal-impl. The PortalHandler interface has a useful base class called BasePortalHandler and then some of the usable implementations are:
  • PageHandler - Just displays a page which will load the tool in an iframe without anything else by default. URL: /portal/page/placementId
  • WorksiteHandler - Just displays a site with the list of tools but no inter site navigation, supports supplying a additional page reference. URL: /portal/worksite/siteId
  • GalleryHandler - Display the site as well as the inter site navigation but still no logo or login box, supports supplying an additional page reference. URL: /portal/gallery/siteId
  • SiteHandler - Display a normal Sakai screen with site and inter site navigation, including login/logout links.
All the handlers are setup in SkinnableCharonPortal.init() which calls through to the portal service. The list of handlers if configurable at runtime through the portal service. Just posting this as a note for future reference really.

Bash History Expansion

I've alway been quite fond of bash history expansion and in particular !! (previous command) and !$ (last argument of previous command) but today I discovered a new trick, the :h modifier. This takes a word and removes file file name, here I am using it in action.
buckett@oucs-matthewb:~ $ sudo vi /opt/tivoli/tsm/client/ba/bin/incl.excl.SAVE 
buckett@oucs-matthewb:~ $ cd !$:h
cd /opt/tivoli/tsm/client/ba/bin
buckett@oucs-matthewb:/opt/tivoli/tsm/client/ba/bin $ mv incl.excl.SAVE incl.excl
mv: cannot move `incl.excl.SAVE' to `incl.excl': Permission denied
buckett@oucs-matthewb:/opt/tivoli/tsm/client/ba/bin $ sudo !!
sudo mv incl.excl.SAVE incl.excl
Now I just have to remember it for more than a few days for it to seep into my normal usage of the shell.