Bean Builder III: JAXB in JAXB

In previous entries I sketched the main requirements for BeanBuilder, and explained why I decided to use XML Schema (Relax NG?) to model the JavaBeans.

In this entry I'll explore how to generate Java source code from the model written in XML Schema ("XML Schema Model" for short). Let me review some of the alternatives here.

Plain XML and stylesheets: JXOM

One alternative is using XSL stylesheets to parse the "XML Schema model" and to build Java source code from that. XSL Stylesheets are good not just for transforming XML to XML or XSL, but to create plain text files from XML too.

After some research I found that you can generate Java from XML using XSL stylesheets in at least two different ways:

  1. The naive approach: you set the xml:output type="text" in your stylesheet, and then just embed the Java source code in the XSLT. Things get way too complicated then, as you mix both XSLT and Java.
  2. You use a more "natural" approach that I found out there: you get a grammar for Java, you then transform that to a XSL stylesheet and then use that to create your Java source code. This approach, invented by the Nesterovsky brothers is both clever and powerful. You have a bunch of XSLT (2.0) utilities that allow you to create Java source code within your XSLT stylesheet. Your result is nicely formatted pure Java source code!

The second approach is very clever, and seems powerful, but it requires XSLT 2.0. As far as I can tell only Saxon is able to handle XSLT 2.0 (see these answers at StackOverflow). But I wouldn't like to tie BeanBuilder to a specific XSLT engine. Let's keep on looking for other alternatives.

JAXB Plugins

Another option would be to write a JAXB Plugin. This is basically a piece of Java that plugs-into JAXB internals, and when you compile your XML Schema with JAXB (using the XJC Compiler) your plug-in hooks in there somehow and you're able to modify how JAXB generates code.

There're a lot of plugins out there that I could use and/or modify. One of those plugins, the property-listener-injector plugin generates Java Beans with bound properties. This is very much what I want to do: generate JavaBeans from XML Schema with bound properties.

I like the JAXB plugin approach, mainly because it comes bundled with the JDK, but the problem is that I should learn about JAXB internals, and this is a pain in the neck for me. JAXB uses the CodeModel library to generate Java source code, and I wouldn't like to learn about JAXB internals and about the CodeModel library just to generate a few Java Beans. Furthermore: the internals of JAXB are not well documented, so I'll have to do lots of research to understand how to hook into JAXB internals in an effective way. So let's keep on looking for other alternatives.

Castor

I could also use the Castor XML Binding Library to parse the "XML Schema model", and then use some custom field handlers to customize how my fields are rendered. In fact there's a configuration property that allows you to create JavaBeans with bound properties automatically.

Castor is quite powerful (I first used it years ago) and well documented, but I'd prefer not using external libraries. So, again, let's keep on looking for another alternatives.

XML Schema in XML Schema and... JAXB in JAXB!

Another alternative could be to transform the "XML Schema model" in Java, and then explore, query, manipulate or generate source code from it. I know Java, so manipulating the "XML Schema model" of the JavaBeans in Java would be a great thing!!

But, how can I transform my "XML Schema model" into Java? Mmmm.... let me think... well,... using JAXB, of course!

The basic idea is to obtain the XML Schema of XML Schema itself (which the W3C provides for free!), and then generate JAXB Java classes from it, Java classes that bind to arbitrary XML Schemas. What I'll call "XML Schema Binding Classes". I can do this quickly in my command line:

xjc.sh -d my/directory -target 2.0 -p net.antonioshome.xmlschema -xmlschema XMLSchema.xsd

With these "XML Schema Binding Classes" I will be able to parse any XML Schema of my liking, including my "XML Schema model".

Now I can do whatever I want with those classes. I can generate Excel files with Apache POI, for instance. Or I can use the Velocity template engine to generate Java source code. In fact I'm not just restricted to JavaBeans... I can do templates for whatever I want (EJB3, Spring, JPA, JSF, NetBeans Node source code, etc., etc.).

But, hold down a moment. You say I can read arbitrary XML Schemas and generate Java source code from them using a template engine of my liking? D'oh! If I were smart enough, I could even write JAXB in JAXB !!

The approach seems so cool to me that I couldn't resist and I've just created this "XML Schema Binding Classes" and I've uploaded them to my Kenai project using the NetBeans integration with KENAI.

Source code is available as well as a small jar file you can download now.

In the next entries I'll start playing with this "XML Schema Binding" library in order to get used ot it.

At first sight it seems to me that I will have to understand all the XML Schema stuff in depth, and this seems complex. But, hey, I prefer understanding XML Schema in depth to fight CodeModel and JAXB plugins! Really. Understanding XML Schema in detail is probably more useful to me in the future.

So take it easy with me for a while, as I play with this XML Schema Binding Library. I'll keep you informed of any advances.

Happy bean-building meanwhile! ;-)

Antonio

blog comments powered by Disqus