Sunday 6 July 2008

Groovy for XML transformation

I have been playing with groovy recently, specifically with the MarkupBuilder, the groovy native support for markup languages. It basically means writing XML using native groovy syntax. Pretty neat.

In my job I have more often than not, have to write software to integrate two or more systems. This, often, means writing code that reads an XML stream onto a Java object for manipulation and eventually writes the result into another XML stream.

This typically involves creating binding objects for the input XML and the output XML and then a sequence of calls to getters on the input object and setters on output object to implement the mapping.

This task is very error prone and tedious. A good solution is using the MarkupBuilder (and, yes, I know about XSLT, but this is not the point here!)

So, suppose that you have the following POJO

public class Contact {
private String id;
private String name;
private String surname;
// ...
}
and you want to serialize the instance

Contact c = new Contact();
c.setId("123");
c.setName("John");
c.setSurname("Bloggs");
into the following XML

<contact>
<key>123</key>
<firstname>John</firstname>
<secondname>Bloggs</secondname>
</contact>


Note the difference between the POJO attribute names and the XML tag names

Using groovy and its MarkupBuilder, the first thing to do is to create a groovy converter, a class with a method that reads the data from the bean and produces the XML. Create a file src/groovy/ContactConverter.groovy with the following code:
class ContactConverter{
def convert(bean){
def writer = new StringWriter();
def xml = new MarkupBuilder();
xml.contact {
firstname(bean.name)
secondname(bean.surname)
}
writer.toString()
}
}

If you execute the code
println new COntactConverter().convert(c)

in a groovy shell, you get the XML shown above.

The next step is then to make this code executable from your Java service.
You can use this class (an adaptation of the code available in the groovy documentation):
public class GroovyConverterInvoker {
public String invoke(String fileName, Object bean){
GroovyObject groovyObject = createObjectFromStreamName(strName);
String result = (String)groovyObject.invokeMethod("convert", new Object[]{bean});
return result;
}

public GroovyObject createObjectFromStreamName(String fileName) {
ClassLoader parent = getClass().getClassLoader();
GroovyClassLoader loader = new GroovyClassLoader(parent);
Class groovyClass;
File f = new File(fileName);
try {
groovyClass = loader.parseClass(f);
return (GroovyObject)groovyClass.newInstance();
} catch (CompilationFailedException e) {
throw new IllegalStateException("Unable to compile " + fileName, e);
} catch (IOException e) {
throw new IllegalStateException("Unable to open file " + fileName, e);
} catch (InstantiationException e) {
throw new IllegalStateException("Unable instantiate object for class in " + fileName, e);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Unable access object of class in " + fileName, e);
}
}
}

You can then invoke the conversion:
public String invokeContactConverter(Object bean){
String fName = "src/groovy/ContactConverter.groovy";
return new GroovyConverterInvoker().invoke(fName, bean);
}

You can now use JAXB/XStream or XmlBeans to parse the result of invokeContactConverter and initialize a new POJO for further use, or send the XML on the wire.

The solution can be generalised and optimised to a point where you only need to write groovy converters and load/modify them dynamically when necessary.

Saturday 5 July 2008

Sicilian as a language

I am randomly browsing the web today. I just finished to read a Wikipedia entry on the Sicilian language. I always thought that Sicilian was an Italian dialect, although I was aware on several influences from French, Spanish, Latin and Greek, but I realised that scholars do consider it as a language in its own merit. That makes Sicilians bilingual at least.

Tuesday 1 July 2008

UMLGaph for auto generating class diagrams from your source code

As part of improving the documentation of our software - a REST API - for the benefit of our customer (mainly an architect) and (future) users, we have investigated UMLGraph, a free application that is able to parse source code and (with the help of graphviz) generate class diagrams that can be embedded in the javadoc documentation.

The tool is very good and we're trying now to integrate it in our continuous integration build via ant.