In a previous post, Using Generics To Build Fluent API’s In Java, I detailed a way to create type-safe fluent API’s using generics. Handy, but unfortunately the process can be somewhat tedious. Any project wishing to utilize a builder must carefully hand-code the various classes and interfaces. Modifications made later are oftentimes painful to implement.
Looking at the simplistic examples from the previous article, it is easy to see patterns in the way the classes are constructed. The type parameters act as a sort of stack, storing the memory of where a method came from, while simultaneously providing insight into where it can go. A sort of…state machine, where classes can transition between each other based on the methods invoked. That’s all a program really is in the end anyway, right?
I took that concept and started writing a code generation tool which would build fluent API’s in Java, wrapping the complex maneuvering around the many types required. Flapi is the result of that work. Using a fluent builder itself, it is easy to create a set of classes which form a builder of your design. Lots of great features like nested blocks of methods, chaining methods together, and invocation tracking make writing and using a builder easy and fun. See the Getting Started page on the wiki to start creating your own fluent API’s.
The code is written in Java, with the only dependency being on CodeModel, an implementation of the Java code model which provides the code generation support. Really, except for a few small bugs it is an absolute pleasure to work with (if not slightly mind-altering, given that you are writing Java code from within a Java program). The classes created are connected to the user’s program logic through pluggable helper interfaces, which the user then implements.
Flapi builds classes which are carefully designed to perform the appropriate transition at each method call. One cool benefit of this is that, unlike a simple builder which allows you to cal the same
setXYZ(...) method over and over, methods can ‘disappear’ once they are invoked. This is immediately apparent when using code completion, and is something which I really enjoy about the builders created as it provides an intuitive ‘maximum invocation tracking’. For the minimum invocations, the generated classes will keep track to make sure that a method is called the correct number of times. Including this logic in in these classes means that as a developer you don’t have to worry about it. (See the Pizza Builder example for more information about disappearing methods.)
One of the most rewarding parts of the development process was designing the builder API which Flapi uses to generate descriptors of other builders. This is not unlike a compiler being bootstrapped to compile itself. Some initial classes were hand-coded, and then once it got going I was able to generate the rest. Now it is self-sustaining. This is a form of self hosting, though it really felt more like I was writing a quine. Swapping out the old classes for the generated ones (captured here) was actually quite exciting.
The project’s wiki page on github provides lots of helpful information about getting started, example descriptors and their usage, and more. As well, all of the code for the project is available on github. Flapi is currently in a beta version. The more exercise it gets the more it can be improved. Feel free to poke around!