Yet another Maybe monad for Java

A better one of course – based on cglib’s Enhancer functionality. I wanted to extract some optional elements from an XML file and (if present) assign their contents to fields of my class. In the beginning I started by using try-catch but it soon became unmanageable (and painful to look at) as the number of optional fields increased. Using my monad and AspectJ to add elem() method to NodeList class the following syntax was possible:

Doc doc = ...; // parsed XML document
MyClass x = ...; // my class
doc = (Document) Maybe.of(doc, Document.class); // now it's a Maybe of Document, the second argument is not required if you are sure that doc != null
x = (MyClass) Maybe.of(x);
x.setX(doc.getElementsByTagName("a").elem(0).getElementsByTagName("b").elem(0).getElementsByTagName("c").elem(0).getElementsByTagName("d").elem(0).getTextContent());
x.setY(doc.getElementsByTagName("a").elem(0).getElementsByTagName("b").elem(1).getElementsByTagName("c").elem(0).getElementsByTagName("d").elem(0).getTextContent());
x.setZ(doc.getElementsByTagName("a").elem(0).getElementsByTagName("b").elem(2).getElementsByTagName("c").elem(0).getElementsByTagName("d").elem(0).getTextContent());

As you can probably guess from the syntax, my Maybe modifies the return values of all the methods of the original class so that they become Maybes themselves, preventing NullPointerException from happening when accessing consecutive fields even if the results are not there. Notice the null pattern for NodeList.elem() and also for default NodeList.item(), this plays very well with the Maybe monad. As counter-example, the above syntax wouldn’t be possible with regular arrays, because accessing a non-existent element would cause an ArrayIndexOutOfBounds exception.

Additionally, the Maybe monad intercepts set*() calls and does nothing if the first parameter is either (null) or a (Maybe containing null) or an (object for which obj.equals(null)). This means that if the field x of my class contained a value before, it wouldn’t be modified unless there was the a/b[0]/c/d element in the XML file. Pretty clear, pretty useful, no try-catch involved, all the possible assignments will always be made. Guess it’s a pretty decent Maybe implementation, even though Java is not Monad-friendly at all. The code is Simplified BSD-licensed. Enjoy!

DOWNLOAD: maybe.zip

Leave a Reply

Your email address will not be published. Required fields are marked *