JAXB Fluent API

Two weeks ago I taught a short session on C# 3.0 and LINQ, including LINQ to XML. One of the things that I really admire in this technology is the functional construction of XML elements.

Last week I started using JAXB to construct and consume XAdES digital signatures. One of the aspects that I immediately disliked was the way to build the object trees, using the classes generated by the binding compiler (XJC). Each of these classes has a parameterless constructor and a set of setter and getter methods to assign and retrieve each of the properties. Unfortunately the setter methods have void as the return type, meaning that an object initialization requires multiple statements. When building a deeply nested hierarchy, this implies code like the one showed below, where the tree is built in reverse order (from leafs to root).

   1: Person alice = new Person();

   2: alice.setName("Alice");

   3:  

   4: Person bob = new Person();

   5: bob.setName("Bob");

   6:  

   7: Person carol = new Person();

   8: carol.setName("Carol");

   9: carol.setFirstChild(alice);

  10: carol.setSecondChild(bob);

I find this code very unpleasant to write, namely when I’m familiar with better idioms, so I immediately started thinking in a way to solve this.

Fortunately, I found the XJC Fluent API Plugin, which extends the classes generated by the binding compiler with extra methods called “withXXX”. These methods are similar to the setter methods with the important difference that they return the instance on which they were called, allowing for method chaining. Using this, the above initialization code becomes

   1: Person carol = new Person().withName("Carol")

   2:     .withFirstChild(new Person().withName("Alice"))

   3:     .withSecondChild(new Person().withName("Bob"));

Notice that the code structure now follows the element structure (from root to leafs). This makes it easier to read and also to write, since the IDE’s auto-completion feature can be used to “guide” the method chaining.

Some remarks regarding this plugin:

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s