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

Look in-depth at Java-to-XML translation

1 2 3 Page 3
Page 3 of 3
1. <Jato:macro name='dir'>
2.    <Jato:element name='dir' invoke='listFiles' recurse='true'>
3.       <Jato:param type='DirFilter'/>  
4.       <Jato:attribute name='name' property='name'/>
5.       <Jato:inline macro='files'/>
6.       <Jato:inline macro='info'/>
7.    </Jato:element>
8. </Jato:macro>

In Listing 7, line 2 recursively creates a <dir> element for each File object returned by listFiles(). Jato will automatically look for any enclosed <Jato:param> tags when invoking a Java method. At line 3, this script contains a single <Jato:param> tag, along with type='DirFilter', that instructs Jato to create a DirFilter instance. The keyword 'this', in lieu of a class name, specifies the current Jato object. The param tag also supports obtaining objects from the helper class using the 'get' attribute, such as get='dir-filter'. Notice the parameter tag does contain a name attribute. Parameter names are not utilized when invoking Java methods but are utilized in all other cases. You can specify a name attribute but it will be ignored.

In Listing 8, you'll see our finished script after writing a FileFilter class that filters out all directory classes and adding a <Jato:element> tag to generate <file> tags:

Listing 8: New script that uses <Jato:element> to create XML tags

<Jato:defs xmlns:Jato='http://jato.sourceforge.net'>
   <Jato:import>java.io.FilenameFilter</Jato:import>
   <Jato:translate key='root'>
      <Jato:attribute name='path' property='absolutePath'/>
      <Jato:inline macro='info'/>
      <Jato:element name='dir' invoke='listFiles' recurse='true'>
         <Jato:param type='DirFilter'/>
         <Jato:attribute name='name' property='name'/>
         <Jato:inline macro='info'/>
         <Jato:inline macro='files'/>
      </Jato:element>
      <Jato:inline macro='files'/>
   </Jato:translate>
   <Jato:macros>
   <Jato:macro name='files'>
      <Jato:element name='file' invoke='listFiles' recurse='true'>
         <Jato:param type='FileFilter'/>
         <Jato:text property='name'/>
         <Jato:attribute name='size' invoke='length'/>
         <Jato:inline macro='info'/>
      </Jato:element>
   </Jato:macro>
   <Jato:macro name='info'>
      <Jato:attribute name='modified' invoke='lastModified' format='date'/>
      <Jato:attribute name='permissions' function='file-perms'>
         <Jato:param name='read' invoke='canRead'/>
         <Jato:param name='write' invoke='canWrite'/>
      </Jato:attribute>
   </Jato:macro>
   </Jato:macros>
</Jato:defs>

The key differences between this script and the script in Listing 5 are:

  • The new script does not have any recursive macro invocations, allowing the 'dir' macro functionality to be inlined in the top-level script.
  • The new script does not include any conditional Jato expressions.
  • A new macro called 'file' creates <file> tags using the <Jato:element> tag and the newly written FileFilter class. Although this example utilized FileFilter and DirFilter default constructors, Jato supports instantiating objects using complex, nondefault constructors.

Personally, I prefer the second version based on its declarative form; however, its structure varies markedly from Java programs that accomplish a similar task. Indeed, many developers find developing Jato scripts more intuitive when they follow coding patterns similar to the patterns utilized when they write their Java programs.

Create elements in a namespace

As many XML documents utilize namespaces, Jato would be incomplete without such support. As such, Jato automatically supports namespaces for tags placed in a Jato script. To place the <dir> tag in the 'ls' namespace, the 'dir' macro in Listing 5 could be written as:

Listing 9: Explicitly create XML tags in a namespace

<Jato:macro name='dir' xmlns:ls='http://jato.sourceforge.net/ex/files'>
   <ls:dir> 
      <Jato:attribute name='name' property='name'/>
      <Jato:inline macro='info'/>
      <Jato:invoke method='listFiles'>
         <Jato:if property='directory'>
            <Jato:inline macro='dir'/>
            <Jato:else>
               <ls:file>
                  <Jato:text property='name'/>
                  <Jato:attribute name='size' invoke='length'/>
                  <Jato:inline macro='info'/>
               </ls:file>
            </Jato:else>
         </Jato:if>
      </Jato:invoke>
   </ls:dir>  
</Jato:macro>

Of course, as detailed in the XML specification, the 'xmlns' attribute can be specified any place within the XML document.

Placing <Jato:element>-created tags into a namespace requires an additional step: we must specify a <Jato:namespace> tag in the top level of the Jato script. This tag possesses attributes that specify the name and URI of the namespace. When specifying the name of the element to create in a <Jato:element> tag, specify the fully qualified name for the tag. Jato will parse the tag name, look up the namespace, and create the element within the specified namespace. Listing 10 shows how Listing 8 could be modified to create <ls:dir> tags:

Listing 10: Create XML tags in a namespace using <Jato:element> script tag

<Jato:defs xmlns:Jato='http://jato.sourceforge.net'>
   <Jato:import>java.io.FilenameFilter</Jato:import>
  <Jato:namespace name='ls' uri='http://jato.sourceforge.net/ex/files'/>  
   <Jato:translate key='root'>
      <Jato:attribute name='path' property='absolutePath'/>
      <Jato:inline macro='info'/>
      <Jato:element name='ls:dir' invoke='listFiles' recurse='true'>
         <Jato:param object='DirFilter' param-type='FilenameFilter'/>
         <Jato:attribute name='name' property='name'/>
         <Jato:inline macro='files'/>
         <Jato:inline macro='info'/>
      </Jato:element>
      <Jato:inline macro='files'/>
   </Jato:translate>
   . . .

Notice the <Jato:namespace> tag placed as a child of the <Jato:defs> tag. Although the ordering of the top-level tags is unimportant, the <Jato:import>, <Jato:namespace>, and <Jato:macros> tags must be placed as immediate descendants of the <Jato:defs> tag.

Conclusion

In this article, we looked in-depth at how to perform Java-to-XML transformations with the Jato API. Jato supports transformations that require complex attribute and text formatting, conditional tag generation, namespace support, debug statements, and recursive macro invocations. As with most languages, Jato supports multiple techniques for achieving the final programming task. Indeed, we explored using recursive macro calls and Jato's declarative syntax to generate the same XML document.

If you find Jato helpful for your projects, locate a bug, or think Jato could use a new feature, drop by the Jato project site and give us your input.

Learn more about this topic

1 2 3 Page 3
Page 3 of 3