Mojasef goes into beta at last

Finally, I have got to a point where I reckon Mojasef is nearing a proper numbered stable release. To celebrate this I have updated the version number in the Mojasef source code to 2.0.b1 and made a downloadable release (source and jar) available at Sourceforge.

I strongly encourage anyone interested in shaping the direction, contents and/or timing of the official 2.0.1 release of Mojasef to grab this release, have a play with it, and let me know your comments and suggestions.

I know that it is light on documentation, especially as even the examples on the web site are not quite accurate any more, but that is now very high on my list of priorities.

Stringtree JSON 2.0.9

Along with the latest release of Stringtree I have released a new Stringtree JSON.

The major change is the provision of an extra version of JSONReader.read which takes a CharacterIterator to allow reading of JSON from within a larger body of text.

I’ve also had another try at ensuring that it is Java 1.4 compatible. Please let me know of any problems you encounter, particularly Java1.4 incompatibility issues.

Download from Sourceforge as usual, and the source is in with Stringtree 2.0.9.

Have fun.

Stringtree 2.0.9

It’s been a month or so, so it’s time for another release of Stringtree. Changes in this release include:

  • fixed some broken EasyTemplater constructors
  • added switchable prefixing of attributes in XMLReader
  • added switchable forcing all values to lists in XMLReader
  • added storing cdata from mixed elements as “text()” in XMLReader
  • added extra “read” methods to JSONReader to allow calling with a CharacterIterator
  • XMLReader now skips a DOCTYPE without complaining.
  • tests.Hierarchy renamed to tests.tree
  • small tidyup of object creation to allow reference to context items instead of full class+parameter specifications
  • support a naive view of namespaces in XML parser, include colonprefix in the name
  • some slight improvements to class creation stuff in util to better deal with multiple calls to “init”.
  • added a GUID generator for use in REST-style applications

Download available from Sourceforge as usual

Demo Friki currently out of action

I have just been informed by my hosting provider that they have had to disable the Java support on the server running the example Friki. Apparently this is due to too many applications from different users clogging up the stderr logs. I won’t be able to re-enable Friki until I have ensured that it does not log anything to stderr.

In practice I have not touched the Friki code in ages, and the demo installation was filling up with Wiki spam, so I might take this opportunity to bring Friki into line with current Stringtree practice.

Sorry if you were looking for a demo, but I’ll announce here when it is back again.

Read JSON from a CharacterIterator

I just had a pleasant email exchange with someone who is interested in embedding Stringtree JSON in another project. In this particular case, the basic functionality of the JSONReader is fine, but the calling API was not quite aligned with what they need.

So now, as well as reading JSON from a String, you now have the ability to read JSON from a CharacterIterator. This was a neat changes, as Stringtree JSONReader uses a CharacterIterator internally anyway, so the extra method actually does a bit less than the original one.

For “power users”, there is actually an extra method. When JSONReader starts reading from a CharacterIterator it’s not entirely clear whether it should get its first character by calling current() to get a character already read once, or by calling next() to get the next unread character, or by calling first() to get the first character of the sequence. With this in mind I have provided a read(CharacterIterator ci, int start), where start can be JSONReader.START, JSONReader.NEXT, or JSONReader.CURRENT.

This update is available in sourceforge subversion, and will be included in the next release of Stringtree and Stringtree JSON.

A Mojasef improvement prompted by thoughts of Spring

Following on from my post a couple of days ago I’ve now added a small extra feature to Mojasef which should add a whole range of extra power. One of the things it enables is a much closer integration with Spring, but that’s only a small part of the possibilities.

The way this new feature is used is very simple. If you recall from the Mojasef documentation, the single most important Mojasef configuration is the http.application value. This may be specified as a system parameter or defined in a “spec” file, but the end result is the same :- it’s the object which provides the methods which eventually get called for each incoming HTTP request.

The new feature supports a similar (but optional) configuration http.application.context. If you define such a configuration, and the specified object implements org.stringtree.Fetcher or java.util.Map, it will be treated as an integral part of the common “context” available to all application methods.

One upshot of this is that if you define http.application.context to be an org.stringtree.spring.SpringFetcher, then all your Spring objects will be available as “first class” objects in your Mojasef applications. No more need for a “spring.” prefix in templates, or extra application code to fetch, cast, and eventually use a Spring BeanFactory.

The use of this new feature is not limited to Spring, though. You can supply any Map or Fetcher implementation, which means that you can use any static or dynamic name/value mapping. I haven’t written any implementations of such things yet, but there is no reason in principle that this technique could not be used to integrate diverse sources such as JNDI/LDAP repositories, databases queried by SQL, XML documents queried using XPath or even asking the whole web using a search engine such as Google.

And, don’t forget that you can combine any or all of these either using the built-in Stringtree FallbackFetcher mechanism, or by providing your own aggregating implementations of org.stringtree.Fetcher or java.util.Map.

As a final twist, Mojasef is smart enough to try alternatives if you don’t want to manually specify such a context. It was not an accident that http.application.context starts with http.application. If your http.application object makes available a property named context (typically by providing a getContext() accessor, or by exposing a get(String name) method which returns a non-null value for the name “context”) then Mojasef can use that too.

This code is currently in subversion, and will be included in the next stable Mojasef release. Example JUnit tests for the new feature can be read here and here

Integrating a Spring context with Stringtree

I don’t tend to use it myself (preferring the “spec” mechanism built-in to Stringtree), but today someone asked me if a Mojasef application could work with Spring.

After a bit of thought, some downloading, and a little playing, here is the result. My intention was to allow beans configured in a Spring application context to act as first-class citizens within a Stringtree context, so that they can be used seamlessly inside Mojasef application code and templates.

The implementation was actually pretty simple, essentially consisting of creating a class which implements org.stringtree.Fetcher and provides access to any Spring beans within a Spring context.

package org.stringtree.spring;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.stringtree.Fetcher;

public class SpringFetcher implements Fetcher {

	private BeanFactory factory;

	public SpringFetcher(BeanFactory factory) {
		this.factory = factory;
	}

	public Object getObject(String name) {
		Object ret = null;
		try {
			ret = factory.getBean(name);
		} catch(BeansException e) {
			ret = null;
		}

		return ret;
	}
}

To use this class, you will need to create an instance of it, passing in a Spring BeanFactory or ApplicationContext object to the constructor. Then the SpringFetcher object can be used just as any other Fetcher.

It seems that when using Spring in a Mojasef application, what will likely be needed is a single Mojasef context which provides access to both Mojasef and Spring objects. To achieve this, simply wrap the two Fetchers in a FallbackFetcher:

	Fetcher spring = new SpringFetcher(new XmlBeanFactory(new FileSystemResource("application.xml")));
	Fetcher map = new MapFetcher();
	Fetcher ff = new FallbackFetcher(spring, map);

An example Eclipse project containing the SpringFetcher class, some unit tests, and the jar files to compile and run them is available in sourceforge subversion at https://svn.sourceforge.net/svnroot/stringtree/projects/spring_example/trunk.