Creating RSF Simple Tool

Starting with Antranig's RSFHelloWorld, I attemted to create my own version that ran inside of Sakai. This eventually resulted in a package called MJNHelloWorld. the following notes were made to first get RSFHello to work, then later to transform it into an app purely of my own.

Migrating RSFHelloWorld to Sakai

The attempt is made to move RSFHelloWorld into Sakai and replace it's web.xml with a version based on NumberGuess.

RSFHelloWorld is copied to MJNHelloWorld.
The tool registration file was copied from NumberGuess and renamed "sakai.rsf.hello". Internals changed as well.
The web.xml file was edited to refer to "sakai.rsf.hello" in all cases.
Attempted to run maven. Built with out error, however, it didn't do anything. Nothing was built.
Adding the property to deploy as a type WAR caused it to build. Also fixed verison number on the serlvetapi. Brought in sakai-util and sakaisrf packages.
Builds and deploys.
However doesn't run (as before). I captured the error output stream via Cygwin. This is the error:

WARN: missing dispatcher for tool: sakai.rsf.hello (2007-01-12 05:24:47,031 main_org.sakaiproject.tool.impl.ActiveToolComponent)
ERROR: Context initialization failed (2007-01-12 05:24:47,078 main_org.springframework.web.context.ContextLoader)
org.springframework.context.ApplicationContextException: Custom context class org.springframework.web.context.support.XmlWebApplicationContext is not of type ConfigurableWebApplicationContext

The dispatcher is missing, which is not a good sign. That might make a difference. But I think the real problem is custom context class being of the wrong type.
It also looks like the 2.0.1 version of Spring wasn't downloaded and installed in share/lib. Copied spring-2.0.1 into shared/lib by hand from local repository.
Didn't fix any errors. I must have edited the wrong version of web.xml, because it still referred to numberguess for the application id. Changed them to hello.
Missing dispatcher tool warning went away, but spring errors are still present.

Antranig had several recommendations.

  1. Use the OOTB version of spring that Sakai uses. Get rid of the other. Change the dependency to use the right one.
  2. Get rid of any copies of spring in the web app itself. do not apply "war.bundle = true"
  3. Include the sakairsf JAR in your app
  4. Reference the two "sakai" Spring context files from this JAR along with the RSF context files.

He references http://www2.caret.cam.ac.uk/rsfwiki/Wiki.jsp?page=SakaiRSF.
Antranig recommends against using the NumberGuess as an exemlar. Recommends Vancouver TaskList or else "CrudPlus".
Made changes to project.xml and web.xml by comparing to TaskList.

Finally got it to work with help from Antranig (AntranigBasman is screen name). I sent him the zipped project and he tried it out with no errors. This strongly indicated duplicate versions of spring lying around. I found a duplicate in RSFHello, which was problably left over from an early attempt. Also had to deleted a numberguess war directory. So it all works now.

The next step would be to attempt to clone the whole thing into an app of my own. This should be recorded step by step for training purposes.

Making it Unique

The MJNHelloWorld module is still very close to the original RSFHelloWorld. The following documents work to make it unique. In effect, this is a kind of cloning exercise which will be useful to future students of RSF.

Application Name

In keeping with previous examples, I'm going to rename this app to rsf-simple and sakai.rsf.simple1. This leaves room later to add more. Eventually, I will re-write the notes example in RSF as well.

The first step is to change the artifactId, currently named "rsf-test-hello". This occurs in two places, which must be in agreement: in the artifactId of the maven project.xml file, and in a context parameter called "resourceurlbase", that curently has a value of "/rsf-test-hello/". These will be changed to "rsf-simple in both cases.

Used "maven sakai:undeploy" to remove rsf-test-hello since this will create a new deployed artifact.
Changes made, built successfully.
Verified that new artifact is deployed as "rsf-simple" in tomcat/webapps.
Tomcat started up without error. Still present in Mecury as sakai.rsf.hello. Runs correctly.

Next step is to change the Sakai application Id. Currently this is "sakai.rsf.hello." We will change it to "sakai.rsf.simple1".
Change needs to happen in the tool registraiton file first. The name of the file is changed to 'sakai.rsf.simple1.xml". Inside, we change the id parameter to be "sakai.rsf.simple1". In keeping with other training examples, I have added a sample configuration parameter, category, and keyword. The file now looks like this:

<?xml version="1.0"?>
<registration>
<tool id="sakai.rsf.simple1"
title="RSF Simple 1"
description="A simple RSF demonstration tool for Sakai Training.">

<configuration name="rsfsimple.property.msg" value="Message here" />
<category name="sakai.sample" />
<keyword name="rsf-simple" />
</tool>
</registration>

Next, we need to find all the places in web.xml where the Sakai app is referenced. There are two occurrances in the web.xml file: in the servlet-name and servlet-mapping.
Changes were made. Builds and deploys successfully. Tomcat starts without error. The new app id correctly appears in the Sample Tools section of Mercury and can be run correctly.

Object Name Changes

Next up is to change the object names and packages. Since this is intended to be a Sakai training tool, all package names will be changed to "org.sakaiproject.tool.simple". Two sub-directories are needed, one for beans the other for components.
Directory names are changed. Target folder is deleted to avoid any confusion. SVN information stripped out. Object names have been retained, but internal package definitions updated to reflect changes in directory structure. Files build without error. However, more is needed before running it.

These objects are referred to in the two spring context files: applicationContext.xml and requestContext.xml.
First the application context is updated. Package specification for the MainProducer is changed. Other names are left as is. Only the bean class name is changed. This file now looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- Define the component producer for the main view -->
<bean class="org.sakaiproject.tool.simple.components.MainProducer"/>

<!-- Define the bean roots from the request scope file that are accessible
via incoming request URL (not strictly necessary for this app) -->
<bean parent="requestAddressibleParent">
<property name="value" value="hellobean"/>
</bean>
</beans>

Next we change the request context. Again, only the bean class is modified, leaving everything else alone. File now looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="hellobean" class="org.sakaiproject.tool.simple.beans.HelloBean"/>
</beans>

Minor corrections made (package name was mispelled). Application deploys and runs correctly.

Data Changes

In a final pass to make this be a unique application, I will change the data displayed in the browser when run.

First the message in HelloBean is modified to read, "This is the Sakai RSF Simple Tool example."
Secondly, the title in webapp/content/templates/main.html was changed to read, "Sakai RSF Simple Tool" and a section header added in the body. This file now looks like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns:rsf="http://ponder.org.uk/rsf">
<head>
<title>Sakai RSF Simple Tool</title>
</head>
<body>
<h1>Sakai RSF Simple Tool</h1>
<div rsf:id="messagefield">This field will be rewritten by the renderer</div>
</body>
</html>

Perhaps it is no longer the simplest possible RSF application, but it does differientiate this instance from RSFHelloWorld.
Application builds, deploys, and runs correctly. Final application: