Table of Contents
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://ws.apache.org/jaxme/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, 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"); ...
After you've downloaded JaxMe, you're ready to use it. In this section we will demonstrate how to generate sources.
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):
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xml:lang="EN" targetNamespace="http://ws.apache.org/jaxme/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. 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.
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
.