Chapter 1. First steps

Table of Contents

Generating Java code
Creating a JaxMe schema
Running the generator
Working with XML
Writing XML documents
Reading XML

This chapter introduces the first steps of using JaxMe. In what follows, we will create some simple examples. All examples deal with addresses, stored in XML documents like the following, quoted from the file examples/misc/address.xml in the JaxMe 2 distribution:

<?xml version="1.0"?>
<!-- A sample document for the Address.xsd schema. This
     sample document is used in the docs, see
     docs/GenerateJava.html. -->

<Address xmlns="http://jaxme.sf.net/examples/misc/address">
  <Name>
    <First>Jane</First>
    <Middle>Lee</Middle>
    <Middle>Chris</Middle>
    <Last>Doe</Last>
    <Initials>(JD)</Initials>
  </Name>
  ... further details omitted for brevity ...
</Address>

Our target is to convert this into convenient Java code, much like the following:

      Address address = new Address();
      Name name = new Name();
      address.setName(name);
      name.setFirst("Jane");
      name.addMiddle("Lee");
      name.addMiddle("Chris");
      name.setSur("Doe");
      name.setInitials("JD");
      ...
    

Generating Java code

After you've downloaded JaxMe, you're ready to use it. In this section we will demonstrate how to generate sources.

Creating a JaxMe schema

With the address example in mind, we create the XML Schema. The schema can be regarded as a description of compliant document instances, in our case addresses. For example like this, quoting the file examples/misc/address.xsd in the JaxMe 2 distribution:

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xml:lang="EN"
    targetNamespace="http://jaxme.sf.net/examples/misc/address"
    elementFormDefault="qualified"
    attributeFormDefault="unqualified">
  <xs:element name="Address">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Name">
          <xs:annotation><xs:documentation>
              A name consists of two required (first and last name)
              and two optional parts (middle name and initials).
          </xs:documentation></xs:annotation>
          <xs:complexType>
            <xs:sequence>
              <xs:element name="First" type="xs:string"/>
              <xs:element name="Middle" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
              <xs:element name="Last" type="xs:string"/>
              <xs:element name="Initials" minOccurs="0" type="xs:string"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        ... further details omitted for brevity ...
      </xs:sequence>
      <xs:attribute name="id"/>
    </xs:complexType>
  </xs:element>
</xs:schema>
You will easily note that xs:element is used to define elements. An attribute is added using xs:attribute, and so on.

Running the generator

The easiest way to run the generator is by invoking an Ant task. Here's how this might look like:

    <target name="taskdef">
      <path id="generate.class.path">
        <pathelement location="jaxme.jar"/>
        <pathelement location="jaxmejs.jar"/>
        <pathelement location="jaxmexs.jar"/>
        <pathelement location="jaxb-api.jar"/>
        <pathelement location="jax-qname.jar"/>
        <pathelement location="namespace.jar"/>
      </path>
      <taskdef name="xjc"
        classname="net.sf.jaxme.generator.XJCTask"
        classpathref="generate.class.path"/>
      <xjc schema="examples/misc/address.xsd" target="build/src">
        <produces includes="net/sf/jaxme/examples/misc/address/*.java"/>
      </xjc>
    </target>

The example demonstrates how a classpath called generate.class.path is created. The class path is used, when a new ant task called "xjc" is created. In what follows the new task is used to compile a schema file called examples/misc/address.xsd. The generated sources will reside in the directory build/src. The target package is net.sf.jaxme.examples.misc.address, hence the effective location is build/src/net/sf/jaxme/examples/misc/address.

Looking into that directory, we find that the following files have been created:

Files generated by the JaxMe binding compiler

Address.java

Contains the Java interface describing the document type Address. This interface is extending the interface specified by AddressType.java.

AddressType.java

Contains the Java interface describing the inner contents of the document type Address. The best way to think of it is to assume that they are the same, except that the latter is anonymous and doesn't have an element name.

Configuration.xml

This file is used by the JaxMe runtime internally. Typically you'll never notice that it is even there. The main task of the file is a mapping between XML element names (like Address in namespace http://jaxme.sf.net/examples/misc/address) and Java classes.

Tip

In theory you are able to replace the implementations generated by JaxMe with your own classes. This is particularly useful, if you want to modify a certain behaviour by deriving a subclass.

jaxb.properties

This file is used by the JAXB properties. Typically you'll never notive that it is even there. The task of the file is to ensure that the JAXB runtime is to make sure that the JaxMe runtime is properly initialized.

impl/AddressHandler.java

A SAX2 ContentHandler, which can convert XML documents of type Address into instances of the Java interface Address. You'll rarely need it, because it is created and invoked automatically by the JAXB Marshaller.

impl/AddressImpl.java

Default Implementation of the Address interface.

impl/AddressType.java

Default Implementation of the AddressType interface.

impl/AddressTypeHandler.java

Similar to its subclass AddressHandler, this is a SAX2 ContentHandler for reading instances of AddressType. The main difference to the subclass is that the subclass doesn't have a fixed element name.

impl/AddressTypeImpl.java

Default implementation of AddressType.

impl/AddressTypeSerializer.java

This class is able to convert instances of AddressType into XML documents. It is also used to convert instances of Address.