Export to GitHub

hackystat-sensorbase-uh - JAXBResourceProcessing.wiki


The problem: Converting XML resource representations to and from Java

Most of the initial Hackystat services will be implemented in Java, and most of those will be requesting data objects from other services, such as the SensorBase. In the SensorBase, as in most other services, requests for resources will be provided in XML format. This creates the question: what is the easiest way to get from XML to a Java class instance where the data can be effectively manipulated?

The Answer: JAXB 2.0

For Java, pretty much the standard response is JAXB. The way JAXB works, in a nutshell, is like this:

  • Design your XML data representation. In particular, implement an XmlSchema definition for each type of object you are manipulating.

  • Install JAXB 2.0

  • Run the XJC compiler, giving it as input your XmlSchema definition. It will blast out a bunch of Java class definitions that correspond to your XmlSchema and that are specially suited to processing by JAXB classes.

  • Compile your newly generated Java classes, and then use the JAXB "Marshaller" class to translate Java to XML, and the JAXB "Unmarshaller" class to go from XML to Java.

For a more comprehensive, yet still concise treatment, see Java Architecture for XML Binding.

Make it even simpler: Use the SensorBase (or SensorShell) resource library

It turns out that the SensorBase already has done the work of creating XmlSchema and running XJC to generate Java classes for its four resources: SensorData, SensorDataTypes, Users, and Projects.

Since many of the Java-based Hackystat services will want to request these resources from the SensorBase, and thus need to convert their XML representation to Java, it seems to make sense to let these services leverage the work we already did in the SensorBase. While the XmlSchema representations are publicly available and could be used as the starting point, an alternative is to provide a "library" jar file that contains the Java class definitions. This avoids the need for other services to duplicate the work of generating them from the XmlSchema.

So, the recommended strategy is as follows:

  • Install JAXB 2.0

  • Download the a binary distribution of the SensorBase (or SensorShell), whose top-level directory contains library jar files. (If you checked out the SensorBase sources from SVN, you can build this file yourself with "ant -f jar.build.xml jar-lib". Make sure this file is on your classpath.

  • When receiving (or mocking) an XML representation of a SensorBase resource, use the JAXB Unmarshaller class to create Java objects from it.

An example: Converting SensorBase XML to Java in 2 lines of code

Here is an example of a complete program that illustrates how easy it is to convert from a SensorBase XML resource representation into Java. Note that JAXB 2.0 and the SensorBase jar file must be on the classpath for this to work:

``` import java.io.File; import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller;

import org.hackystat.sensorbase.resource.sensordatatypes.jaxb.SensorDataType; import org.hackystat.sensorbase.resource.sensordatatypes.jaxb.SensorDataTypes;

public class SimpleSDTExample {

public static void main(String[] args) throws Exception { // Example file containing sensor data type definitions. File dataFile = new File("/Users/johnson/svn-google/sensorbase-uh/xml/examples/sensordatatypes.example.xml");

// Next two lines are special JAXB magic.
JAXBContext context = JAXBContext.newInstance(org.hackystat.sensorbase.resource.sensordatatypes.jaxb.ObjectFactory.class);
Unmarshaller unmarshaller = context.createUnmarshaller();

// Get an instance of our XML file as a Java class.
SensorDataTypes sensorDataTypes = (SensorDataTypes) unmarshaller.unmarshal(dataFile);

// Now we can manipulate our XML data in Java easily.
for (SensorDataType sensorDataType : sensorDataTypes.getSensorDataType()) {
  System.out.println(sensorDataType.getName());
}

} } ```

I use a File containing XML code here for convenience, but the Unmarshaller can accept lots of other formats: Strings, InputStreams, Dom objects, and so forth.

This example shows the manipulation of the SensorDataTypes resource, but you use the same approach to convert Project, User, and SensorData XML representations to Java. The jar file contains definitions for all of them.