Jato: The new kid on the open source block, Part 1

A new library for converting between Java and XML

1 2 Page 2
Page 2 of 2

This script demonstrates how Jato integrates with a system through a helper class using the <Jato:translate> tag, allows non-Jato tags to be embedded within scripts, and invokes nonbean and static methods. Like Java, Jato maintains a 'this' reference, referred to in Jato as the current object and accessible using the keyword 'this'. The current object is utilized at line 5 when the 'name' attribute is set for the <property> tag. The current object at line 5 is the object being iterated as part of the <Jato:translate> tag at line 3. At line 7, the current object is used again as the parameter to the System.getProperty(String name) method.

In Table 1, note the similarities between this Jato script and the PrintProps Java class found in Listing 1:

Table 1. Comparison between PrintProps and Jato script
 PrintProps Jato script

 Properties props = System.getProperties();

 Enumeration e = props.keys();

 String key, prop;

 while(e.hasMoreElements()) {

    

key = (String)e.nextElement();

 <Jato:translate key='prop-names'>

  

<property>

    System.out.print("\t" + key + "=");    <Jato:attribute name='name' type='this'/>

    prop = System.getProperty(key);

    

System.out.println(prop);

   <Jato:attribute name='value' invoke='getProperty'

               class='System'>

      <Jato:param type='this'/>

   

</Jato:attribute>

 }

   </property>

 

</Jato:translate>

Moving beyond Jato syntax, let's explore how Jato obtains the objects for the <Jato:translate> tag. When Jato obtains a <Jato:translate> tag, it invokes the helper's getObject() method and passes the value of the 'key' attribute. In our helper class, the getObject() method ignores the 'key' value and simply returns the Enumeration object for the system property names:

public Object getObject(String key) {
    Properties props = System.getProperties();
    return props.keys();
}

Those two lines are the same as the first two lines in PrintProps, shown in Listing 1. Jato understands how to iterate arrays, Enumeration instances, and Iterator instances. The helper class uses the XML string passed to the parent class's constructor to provide the interpreter the Jato script used for the transformation:

SimpleJavaToXml() throws JDOMException {
   super(sJatoXML); //sJatoXML is the static script string
}

The XmlHelperAdapter class provides the following constructors:

  • public XmlHelperAdapter (Document jato)
  • public XmlHelperAdapter (File jatoFile)
  • public XmlHelperAdapter (String jatoXml)

The constructor parameter always creates the Jato transformation script.

To translate Java objects to XML within an application, a program can use the JavaToXml class as follows:

JavaToXml jtox = new JavaToXml();
jtox.setrootOption("system-properties");
jtox.setSaveOption(true, "simple.xml");
jtox.setHelperClass("SimpleJavaToXml");
Document doc = jtox.transform();

The JDOM document returned by jtox.transform() contains the XML representation of the application's objects. In this example, the document has already been saved to the simple.xml file.

XML-to-Java example

As a logical follow-up to the previous example, let's examine a program to translate the system properties XML document back into a java.util.Properties object. We can do this with the SimpleXmlToJava class from Listing 3:

Listing 3: Program that performs an XML-to-Java translation

1.  import java.util.Properties;
2.  import org.jato.ObjectHelperAdapter;
3.  import org.jdom.JDOMException;
4.
5.  public class SimpleXmlToJava extends ObjectHelperAdapter {
6.     public SimpleXmlToJava() throws JDOMException {
7.        super(sJatoXML);
8.     }
9.
10.    public void publish(String key, Object obj, int state)  {
11.       if (state == INITIALIZED_STATE) {
12.          Properties props = (Properties)obj;
13.
14.          props.save(System.out, "System Properties");
15.          System.out.println(props.size());
16.       }
17.    }
18.
19.    static String sJatoXML =
20.    "<?xml version='1.0' encoding='UTF-8'?> \n" +
21.    "<Jato:java-defs xmlns:Jato='http://www.kruel.com/jato' > \n" +
22.    "   <Jato:import>java.util.*</Jato:import> \n" +
23.    "\n" +
24.    "   <Jato:translate elt='system-properties'> \n" +
25.    "      <Jato:object class='Properties' publish='props'> \n" +
26.    "         <Jato:on-elt name='property' action='Jato:invoke' method='setProperty'> \n" +
27.    "            <Jato:param type='string' path='@name'/> \n" +
28.    "            <Jato:param type='string' path='@value'/> \n" +
29.    "         </Jato:on-elt> \n" +
30.    "      </Jato:object> \n" +
31.    "   </Jato:translate> \n" +
32.    "</Jato:java-defs>";
33. }

The org.jato.XmlToJava class runs XML-to-Java transformation scripts from the command line, or allows them to be easily embedded in your applications. To run the script at the command line type:

> java org.jato.XmlToJava -o SimpleXmlToJava -i simple.xml

-o specifies the helper class; -i specifies the XML document to be translated. By default, the XmlToJava class will use default.xml as the name of the input XML document, and the org.jato.ObjectHelperAdapter class as the default helper class.

Once again, let's start our examination by looking at the script, listed at lines 19-32. The script states the following:

  • Import all classes in the java.util package (line 22). The Properties class can be explicitly imported by changing java.util.* to java.util.Properties. If the <Jato:import> tag is omitted, then the 'class' attribute at line 40 must be specified as 'java.util.Properties'.
  • Begin translating the XML to Java when a <system-properties> tag is encountered (line 24).
  • When a tag is encountered, instantiate a Properties object and publish the object to the helper under the name 'props'.
  • For each <property> tag encountered within the <system-properties> tag, invoke the setProperty(String, String) method on the current object (lines 26-29). Then the current object will be the Properties object instantiated at line 40.
  • Get the first parameter as a String using the 'name' attribute for the <property> tag (line 27). The type attribute can be the name of any Java primitive type, a fully qualified class name, or string. The string keyword makes it convenient to create the ever-common java.lang.String objects. The path attribute is the XPath-compliant path to the element or attribute from which the property value will be obtained.
  • Get the second parameter as a String using the 'value' attribute for the <property> tag (line 28).

The helper class contains a single method: publish(). Jato passes objects to that method when a <Jato:object> tag contains the 'publish' attribute. The publish() method tests the state of the object at line 11, for objects are passed to publish() in two states:

  • CREATED_STATE: The object has been constructed but no methods have yet been invoked on it
  • INITIALIZED_STATE: The object has been completely initialized -- that is, all child tags of the <Jato:object> tag have been processed

If the object is in the INITIALIZED_STATE, it is cast to a Properties object, and the contents print to the System.out standard console.

Typical uses for Jato

Java applications routinely use XML to store configuration information, transfer data between heterogeneous databases, and exchange information between processes. In addition to those benefits, Jato could be used as a front-end for XSL, where the XML would be generated using objects that exist as part of a large Java application or JavaSpaces collection. Jato enables the state of a Java application to be easily streamed out in an XML format for performance profiling, technical support, or persistence purposes. In short, whenever a project calls for converting between Java and XML, Jato is the tool for the job.

Conclusion

This article introduced Jato, a nonprocedural XML language for transforming Java objects to and from XML documents. Jato is extremely powerful and capable of making your XML- and Java-based systems more maintainable, robust, and fun to develop. It is especially useful for projects in which the XML schemas and Java APIs change rapidly -- which means just about every new development project.

Jato does not require preprocessing, force XML or Java developers to adhere to arbitrary or proprietary conventions, or require the utilization of specific XML parsers. Simply put, Jato allows developers to create object-oriented Java designs and XML schemas optimized to encapsulate the data and functionality required for a given task.

In future articles, I'll provide detailed information about Jato syntax, features, and uses.

Learn more about this topic

Related:
1 2 Page 2
Page 2 of 2