# First steps

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): &address;

Our target is to convert this into convenient, standard Java bean 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

The usual way to use JaxMe is to start from a schema and generate source code from that schema. So (with the address example in mind) we create an XML Schema from which the sources will be generated. When using JaxMe in the wild sometimes the schema will already exist, in other cases the application developer will develop the schema as the application develops. In either case, the way that JaxMe is used is very similar.

The schema can be regarded as a description of compliant document instances (in our case addresses). For example (`examples/misc/address.xsd` in the JaxMe 2 distribution): &addressxsd; You will easily note that xs:element is used to define elements. An attribute is added using xs:attribute, and so on. XML schema are very expressive (which is why they support source generation so well) but with this expressiveness comes complexity. Getting to grips with the XML schema standard is worth the effort but some users may choose to use one of the numerous tools that help with XML schema generation.

### Running The Generator

The easiest way to run the generator is by invoking an Ant task. Here is a typical ant target:

        <target name="taskdef">
          <!--
          Set up the classpath for the generation task.
          Include all the standard jaxme jars.
          -->
          <path id="generate.class.path">
            <pathelement location="jaxme2.jar"/>
            <pathelement location="jaxmejs.jar"/>
            <pathelement location="jaxmexs.jar"/>
            <pathelement location="jaxmeapi.jar"/>
          </path>
          <!--
          Defines the generation task using that classpath.
          -->
          <taskdef name="xjc"
            classname="org.apache.ws.jaxme.generator.XJCTask"
            classpathref="generate.class.path"/>
          <!--
          Generate source code.
          The 'schema' attribute gives the path to the schema the sources
          will be generated from.
          The 'target' attribute specifies the base directory that the source
          will be generated into. Sources will be created in subdirectories
          corresponding to the package structure.
          -->
          <xjc
            schema="examples/misc/address.xsd"
            target="build/src">
                <!--
                The source files being created. The xjc task uses these for
                a check, whether they are uptodate. If so, the generation is
                skipped, for improved speed.
                Specifying the package isn't necessary, unless you have other
                files in the target directory as well, for example manually
                written files or files created by another generator or xjc call.
                If so, these need to be excluded from the uptodate check.
                -->
                <produces includes="org/apache/ws/jaxme/examples/misc/address/*.java"/>
          </xjc>
        </target>

The example demonstrates how a classpath called generate.class.path is created and used to define a new ant task called "xjc". This 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 org.apache.ws.jaxme.examples.misc.address, hence the effective location is `build/src/org/apache/ws/jaxme/examples/misc/address`.

After running the task, 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 extends 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 (though you will need to ensure that it remains on the classpath). The main task of the file is a mapping between XML element names (like Address in namespace http://ws.apache.org/jaxme/examples/misc/address) and Java classes.

  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`

  The JAXB standard uses this file. Typically you'll never even notice that it exists (though again, it must be found on the classpath). The task of the file is to ensure that the JAXB runtime correctly initializes the JaxMe runtime.

`impl/AddressHandler.java`

  A SAX2 ContentHandler, which can convert XML documents of type Address into implementations of the Java interface Address. This is rarely called directly. Usually it will be 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`

  Converts instances of AddressType into XML documents. It is also used to convert instances of Address.

## Working with XML

In this section we'll show how to create XML from the beans generated earlier. XML (or better an XML document) exists in various flavours: you might want to have it serialized into a String or you may prefer character or byte streams (typically instances of Writer or OutputStream). In other cases, a DOM representation is more useful. Feeding SAX events to a pipeline may be more efficient on other occasions.

The important questions are: how do I create a serialized XML document (a String, a character or byte stream)? And, vice versa, how do I read such a document and convert it back into Java objects?

### Writing XML Documents

In the case of JaxMe, you'll start from simple Java beans whose source has typically been generated. An address implementation is constructed by instantiating an AddressImpl (which implements Address). For example:

    import java.io.FileWriter;
    import java.io.Writer;

    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.JAXBException;
    import javax.xml.bind.Marshaller;

    import org.apache.ws.jaxme.examples.misc.address.Address;
    import org.apache.ws.jaxme.examples.misc.address.AddressType.EmailDetailsType.EmailType;
    import org.apache.ws.jaxme.examples.misc.address.AddressType.PhoneDetailsType.PhoneType;
    import org.apache.ws.jaxme.examples.misc.address.impl.AddressImpl;
    import org.apache.ws.jaxme.examples.misc.address.impl.AddressTypeImpl.EmailDetailsTypeImpl;
    import org.apache.ws.jaxme.examples.misc.address.impl.AddressTypeImpl.EmailDetailsTypeImpl.EmailTypeImpl;
    import org.apache.ws.jaxme.examples.misc.address.impl.AddressTypeImpl.PhoneDetailsTypeImpl;
    import org.apache.ws.jaxme.examples.misc.address.impl.AddressTypeImpl.PhoneDetailsTypeImpl.PhoneTypeImpl;
    import org.apache.ws.jaxme.examples.misc.address.impl.AddressTypeImpl.NameTypeImpl;
    import org.apache.ws.jaxme.examples.misc.address.impl.AddressTypeImpl.PostalTypeImpl;

    public class AddressCreator {

      public static void writeAddress(Writer pWriter) throws JAXBException {
        // Create the element:
        Address addr = new AddressImpl();
        addr.setName(new NameTypeImpl());
        addr.getName().setFirst("Jane");
        addr.getName().setLast("Doe");
        addr.setPostal(new PostalTypeImpl());
        addr.getPostal().setStreet("34 Main Street");
        addr.getPostal().setCity("Boston");
        addr.getPostal().setState("MA");
        addr.getPostal().setZIP("02215");
        addr.setEmailDetails(new EmailDetailsTypeImpl());

        /* Lots of similar lines omitted for brevity ...
         * ...
         */

        // And save it into the file "Address.xml"
        JAXBContext context = JAXBContext.newInstance("org.apache.ws.jaxme.examples.misc.address");
        Marshaller marshaller = context.createMarshaller();
        marshaller.marshal(addr, pWriter);
      }

      public static void main(String[] args) throws Exception {
        FileWriter fw = new FileWriter("Address.xml");
        writeAddress(fw);
        fw.close();
      }
    }

The complete example code can be found in the JaxMe distribution (`src/java/org/apache/ws/jaxme/examples/misc/address/AddressCreator.java`).

There are several things you should note here:

- The class and property names directly correspond to element and attribute names.
- Although the Address document uses namespaces, attributes, and child elements, the example does not require that the developers have extensive knowledge of XML. For example, you do not need to care for character escaping. This is particularly useful when those without great knowledge of xml wish to develop code against an existing schema.
- Complex child elements are java beans themselves, like the Address element. For example, this means that the Name element has to be instantiated.
- To convert the object into an XML string, the JAXBContext and Marshaller are used. These objects are specified by JAXB. The example uses no JaxMe specific features and should run with any compliant JAXB implementation.

### Reading XML

The example on writing XML was surprisingly simple. In fact, the only nasty part was creating the object, which requires invocation of lots of setters and getters. Quite opposed to the marshalling, which took place in three lines. And, as we soon will see: unmarshalling (the process of reading a document) is by no means more complex.

To demonstrate the unmarshalling process, we'll quote an example from the JaxMe distribution again. This time it's the file `src/java/org/apache/ws/jaxme/examples/misc/address/AddressPrinter.java`:

    package org.apache.ws.jaxme.examples.misc.address;

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.StringWriter;

    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.JAXBException;
    import javax.xml.bind.Marshaller;
    import javax.xml.bind.Unmarshaller;

    import org.apache.ws.jaxme.examples.misc.address.Address;
    import org.xml.sax.InputSource;

    public class AddressPrinter {
      public static Address getAddress(InputSource pSource) throws JAXBException {
        JAXBContext context = JAXBContext.newInstance("org.apache.ws.jaxme.examples.misc.address");
        Unmarshaller unmarshaller = context.createUnmarshaller();
        return (Address) unmarshaller.unmarshal(pSource);
      }

      public static String getAddressAsString(Address pAddress) throws JAXBException {
        StringWriter sw = new StringWriter();
        JAXBContext context = JAXBContext.newInstance("org.apache.ws.jaxme.examples.misc.address");
        Marshaller marshaller = context.createMarshaller();
        marshaller.marshal(pAddress, sw);
        return sw.toString();
      }

      public static void main(String[] args) throws Exception {
        File f = new File("Address.xml");
        InputSource isource = new InputSource(new FileInputStream(f));
        isource.setSystemId(f.toURL().toString());
        Address addr = getAddress(isource);

        // A simpler variant might be:
        // Address addr = unmarshaller.unmarshal(f);

        if (addr.getName() == null) {
          System.out.println("Loaded address without name.");
        } else {
          System.out.println("Loaded address " + addr.getName().getLast() +
                             ", " + addr.getName().getFirst() + ".");
        }
        System.out.println("Details:" + getAddressAsString(addr));
      }
    }

How this example works:

1. It reads the file `Address.xml`. This is the very same file created in the first example. JaxMe supports true round-tripping.
2. An instance of InputSource is constructed. The InputSource is part of the SAX API and can be viewed as an abstract data source from which XML can be read. Typically, the InputSource will be backed by an InputStream or a Writer.
3. The method `getAddress()` is invoked to convert the XML document into an instance of Address. These are the promised three lines, again using classes and methods specified by JAXB.
4. Finally the method `getAddressAsString` is invoked to convert the Address instance back into a printable String, which we may use to verify that everything went fine. (It is always nice to see a result being displayed on the screen. :-)