Thursday, 25 April 2013

JDOM2 namespaces

JDOM2 is relatively new (2012) and it is replacing ancient, pre Java 5 generic, JDOM1 version. You can find nice set of basic examples here.

My requirement was to generate xml with single namespace without prefix. Quite common task you can say, but this happend to be little bit tricky. I thought that namespace, once set on Element, should be inherited by child Elements. Of course unless you intentionaly set another namespace on some child. I was wrong!

You must explicitly set very same namespace over and over again on every Element you create. Very annoying indeed. There is a page dedicated to namespace scoping but call me stupid, it haven't help me single bit.

Luckily, after you are finished with creating elements, you can "namespacize" them in one shot with following simple recursive method...

import org.jdom2.Element;
import org.jdom2.Namespace;

public static void setNamespace(Element element, Namespace namespace) {
 element.setNamespace(namespace);
 List children = element.getChildren();
 for (Element child : children) {
  setNamespace(child, namespace);
 }
}
Happy new namespaces!

Thursday, 18 April 2013

Building Fluent Builder

Recently I've rediscovered another wheel again, but this one is pretty interesting I think...

Simple Fluent Builder

Builder is rather simple desing pattern. It accumulates bunch of values and then uses them to construct some complex product.

Fluent builder is a builder with fluent interface. That means it returns reference to self from every method (except the build() method that returns product) so it allows method chaining.
Nice and simple example is StringBuilder from java standard library.

String hello = new StringBuilder()
  .append("h").append("e").append("l").append("l").append("o")
  .toString();

Generic getThis() trick

When Builder is single standalone class, using return this is dead simple solution, but when inheritance comes into play, builder base class methods cannot return this, because we need concrete builder to be returned to allow method chaining.

Solution is the getThis() trick, that allows to return reference to concrete builder even from base class that builder is extending. The price is that every concrete builder must implement getThis() method.

Here is a nice article with some background and explanation

Generic parent trick

I've found another slightly different scenario, when similar generic trick can be used. It employs two builders and uses generic parent (instead of generic self) to keep track of builders used in chaining. It is quite simple JSON builder.

JSON message is built on two structures: object and array, therefore we will have two concrete builders working together. We don't want builder user to be confused by offering object building methods to him when he constructs array and contrariwise. When user completes constructing array or object, previous builder must be restored and returned to user.

This builder completely prevents user from making wrong method call at any point of building.

JSR-353 - JSON-P

Brand new Java API for JSON processing is going to be part of the upcoming JEE 7 specification also contains JSON builder.
Surprisinly to me they came with simplest builder that is throwing exception when user calls object/array builder method out of correct object/array building context.
For example this code
JsonGenerator jg = javax.json.Json.createGenerator(System.out);
jg.writeStartObject().write("array_element").writeEnd();
executed will throw
javax.json.stream.JsonGenerationException: write(String) can only be called in array context
Very error prone API indeed! I've filed improvement into Jira, but since JSR already passed the Final Approval Ballot, I guess there is no hope.