General Usage Instructions

This section provides general usage instructions for the examples used in this chapter, including how to build and run the applications using the Ant build tool, and provides details about the default schema-to-JAXB bindings used in these examples.

Description

This chapter describes three sets of examples:

The Basic and Customize examples are based on a Purchase Order scenario. With the exception of the Fix Collides example, each uses an XML document, po.xml, written against an XML schema, po.xsd.

Table 16-9 briefly describes the Basic examples.

Table 16-9 Basic JAXB Examples
Example Name
Description
Demonstrates how to modify a Java content tree.
Demonstrates how to enable validation during unmarshalling.
Pull Parser Example
Demonstrates how to use the StAX pull parser to parse a portion of an XML document.

Table 16-10 briefly describes the Customize examples.

Table 16-10 Customize JAXB Examples
Example Name
Description
Demonstrates how to customize the default JAXB bindings by using inline annotations in an XML schema.
Similar to the Customize Inline example, this example illustrates alternate, more terse bindings of XML simpleType definitions to Java datatypes.
Illustrates how to use an external binding declarations file to pass binding customizations for a read-only schema to the JAXB binding compiler.

Table 16-11 briefly describes the Java-to-Schema examples.

Table 16-11 Java-toSchema JAXB Examples
Example Name
Description
j2s-create-marshal
Illustrates how to marshal and unmarshal JAXB-annotated classes to XML schema. The example also shows how to enable JAXP 1.3 validation at unmarshal time using a schema file that was generated from the JAXB mapped classes.
j2s-xmlAccessorOrder
Illustrates how to use the @XmlAccessorOrder and @XmlType.propOrder mapping annotations in Java classes to control the order in which XML content is marshalled/unmarshaled by a Java type.
j2s-xmlAdapter-field
Illustrates how to use the interface XmlAdapter and the annotation @XmlJavaTypeAdapter to provide a a custom mapping of XML content into and out of a HashMap (field) that uses an "int" as the key and a "string" as the value.
j2s-xmlAttribute-field
Illustrates how to use the annotation @XmlAttribute to define a property or field to be handled as an XML attribute.
j2s-xmlRootElement
Illustrates how to use the annotation @XmlRootElement to define an XML element name for the XML schema type of the corresponding class.
j2s-xmlSchemaType-class
Illustrates how to use the annotation @XmlSchemaType to customize the mapping of a property or field to an XML built-in type.
j2s-xmlType
Illustrates how to use the annotation @XmlType to map a class or enum type to an XML schema type.

Each Basic and Customize example directory contains several base files:

Using the Examples

As with all applications that implement schema-derived JAXB classes, as described above, there are two distinct phases in using JAXB:

  1. Generating and compiling JAXB Java classes from an XML source schema
  2. Unmarshalling, validating, processing, and marshalling XML content

You perform these steps by using ant with the build.xml project file included in each example directory. Use the "runapp" target to build, compile, and run each example and, when you are done examining everything that gets created and/or consumed, use the "clean" target to clean out the generated files and directories.

Configuring and Running the Samples

The build.xml file included in each example directory is an ant project file that, when run, automatically performs the following steps:

  1. Updates your CLASSPATH to include the necessary schema-derived JAXB classes.
  2. For the Basic and Customize examples, runs the JAXB binding compiler to generate JAXB Java classes from the XML source schema, po.xsd, and puts the classes in a package named primer.po. For the Java-to-Schema examples runs schemagen, the schema generator, to generate XML schema from the annotated Java classes.
  3. Compiles the schema-derived JAXB classes or the annotated Java code.
  4. Runs the Main class for the example.

The schema-derived JAXB classes and how they are bound to the source schema is described in About the Schema-to-Java Bindings. The methods used for building and processing the Java content tree are described in Basic Examples.

JAXB Compiler Options

The JAXB XJC schema binding compiler transforms, or binds, a source XML schema to a set of JAXB content classes in the Java programming language. The compiler, xjc, is provided in two flavors in the Application Server: xjc.sh (Solaris/Linux) and xjc.bat (Windows). Both xjc.sh and xjc.bat take the same command-line options. You can display quick usage instructions by invoking the scripts without any options, or with the -help switch. The syntax is as follows:

xjc [-options ...] <schema> 

The xjc command-line options are listed in Table 16-12.

Table 16-12 xjc Command-Line Options 
Option or Argument
Description
-nv
Do not perform strict validation of the input schema(s). By default, xjc performs strict validation of the source schema before processing. Note that this does not mean the binding compiler will not perform any validation; it simply means that it will perform less-strict validation.
-extension
By default, the XJC binding compiler strictly enforces the rules outlined in the Compatibility chapter of the JAXB Specification. In the default (strict) mode, you are also limited to using only the binding customizations defined in the specification. By using the-extension switch, you will be allowed to use the JAXB Vendor Extensions.
-b file
Specify one or more external binding files to process. (Each binding file must have its own -b switch.) The syntax of the external binding files is extremely flexible. You may have a single binding file that contains customizations for multiple schemas or you can break the customizations into multiple bindings files. In addition, the ordering of the schema files and binding files on the command line does not matter.
-d dir
By default, xjc will generate Java content classes in the current directory. Use this option to specify an alternate output directory. The directory must already exist; xjc will not create it for you.
-p package
Specify an alternate output directory. By default, the XJC binding compiler will generate the Java content classes in the current directory. The output directory must already exist; the XJC binding compiler will not create it for you.
-proxy proxy
Specify the HTTP/HTTPS proxy. The format is [user[:password]@]proxyHost[:proxyPort]. The old -host and -port options are still supported by the Reference Implementation for backwards compatibility, but they have been deprecated.
-classpath arg
Specify where to find client application class files used by the <jxb:javaType> and <xjc:superClass> customizations.
-catalog file
Specify catalog files to resolve external entity references. Supports TR9401, XCatalog, and OASIS XML Catalog format. For more information, please read the XML Entity and URI Resolvers document or examine the catalog-resolver sample application.
-readOnly
Force the XJC binding compiler to mark the generated Java sources read-only. By default, the XJC binding compiler does not write-protect the Java source files it generates.
-npa
Supress the generation of package level annotations into **/package-info.java. Using this switch causes the generated code to internalize those annotations into the other generated classes.
-xmlschema
Treat input schemas as W3C XML Schema (default). If you do not specify this switch, your input schemas will be treated as W3C XML Schema.
-quiet
Suppress compiler output, such as progress information and warnings.
-help
Display a brief summary of the compiler switches.
-version
Display the compiler version information.
-Xlocator
Enable source location support for generated code.
-Xsync-methods
Generate accessor methods with the synchronized keyword.
-mark-generated
Mark the generated code with the -@javax.annotation.Generated annotation.

JAXB Schema Generator Options

The JAXB Schema Generator, schemagen, creates a schema file for each namespace referenced in your Java classes. The schema generator can be launched using the appropriate schemagen shell script in the bin directory for your platform. The schema generator processes Java source files only. If your Java sources reference other classes, those sources must be accessible from your system CLASSPATH environment variable or errors will occur when the schema is generated. There is no way to control the name of the generated schema files.

You can display quick usage instructions by invoking the scripts without any options, or with the -help switch. The syntax is as follows:

schemagen [-options ...] [java_source_files] 

The schemagen command-line options are listed in Table 16-13.

Table 16-13 schemagen Command-Line Options 
Option or Argument
Description
-d path
Specifies the location of the processor- and javac-generated class files.

About the Schema-to-Java Bindings

When you run the JAXB binding compiler against the po.xsd XML schema used in the basic examples (Unmarshal Read, Modify Marshal, Unmarshal Validate), the JAXB binding compiler generates a Java package named primer.po containing eleven classes, making a total of twelve classes in each of the basic examples:

Table 16-14 Schema-Derived JAXB Classes in the Basic Examples 
Class
Description
primer/po/
Comment.java
Public interface extending javax.xml.bind.Element; binds to the global schema element named comment. Note that JAXB generates element interfaces for all global element declarations.
primer/po/
Items.java
Public interface that binds to the schema complexType named Items.
primer/po/
ObjectFactory.java
Public class extending com.sun.xml.bind.DefaultJAXBContextImpl; used to create instances of specified interfaces. For example, the ObjectFactory createComment() method instantiates a Comment object.
primer/po/
PurchaseOrder.java
Public interface extending javax.xml.bind.Element, and PurchaseOrderType; binds to the global schema element named PurchaseOrder.
primer/po/
PurchaseOrderType.java
Public interface that binds to the schema complexType named PurchaseOrderType.
primer/po/
USAddress.java
Public interface that binds to the schema complexType named USAddress.
primer/po/impl/
CommentImpl.java
Implementation of Comment.java.
primer/po/impl/
ItemsImpl.java
Implementation of Items.java
primer/po/impl/
PurchaseOrderImpl.java
Implementation of PurchaseOrder.java
primer/po/impl/
PurchaseOrderTypeImpl.java
Implementation of PurchaseOrderType.java
primer/po/impl/
USAddressImpl.java
Implementation of USAddress.java


Note: You should never directly use the generated implementation classes--that is, *Impl.java in the <packagename>/impl directory. These classes are not directly referenceable because the class names in this directory are not standardized by the JAXB specification. The ObjectFactory method is the only portable means to create an instance of a schema-derived interface. There is also an ObjectFactory.newInstance(Class JAXBinterface) method that enables you to create instances of interfaces.


These classes and their specific bindings to the source XML schema for the basic examples are described below.

Table 16-15 Schema-to-Java Bindings for the Basic Examples 
XML Schema
JAXB Binding
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="purchaseOrder" type="PurchaseOrderType"/>
PurchaseOrder.java
<xsd:element name="comment" type="xsd:string"/>
Comment.java
<xsd:complexType name="PurchaseOrderType">
  <xsd:sequence>
    <xsd:element name="shipTo" type="USAddress"/>
    <xsd:element name="billTo" type="USAddress"/>
    <xsd:element ref="comment" minOccurs="0"/>
    <xsd:element name="items" type="Items"/>
  </xsd:sequence>
  <xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
PurchaseOrderType.java
<xsd:complexType name="USAddress">
  <xsd:sequence>
    <xsd:element name="name" type="xsd:string"/>
    <xsd:element name="street" type="xsd:string"/>
    <xsd:element name="city" type="xsd:string"/>
    <xsd:element name="state" type="xsd:string"/>
    <xsd:element name="zip" type="xsd:decimal"/>
  </xsd:sequence>
<xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
</xsd:complexType>
USAddress.java
<xsd:complexType name="Items">
  <xsd:sequence>
    <xsd:element name="item" minOccurs="1" maxOccurs="unbounded">
Items.java
      <xsd:complexType>
        <xsd:sequence>
         <xsd:element name="productName" type="xsd:string"/>
         <xsd:element name="quantity">
           <xsd:simpleType>
             <xsd:restriction base="xsd:positiveInteger">
               <xsd:maxExclusive value="100"/>
             </xsd:restriction>
           </xsd:simpleType>
         </xsd:element>
         <xsd:element name="USPrice" type="xsd:decimal"/>
         <xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="shipDate" type="xsd:date" minOccurs="0"/>
        </xsd:sequence>
  <xsd:attribute name="partNum" type="SKU" use="required"/>
      </xsd:complexType>
Items.ItemType
    </xsd:element>
  </xsd:sequence>
</xsd:complexType>
 
<!-- Stock Keeping Unit, a code for identifying products -->
 
<xsd:simpleType name="SKU">
  <xsd:restriction base="xsd:string">
    <xsd:pattern value="\d{3}-[A-Z]{2}"/>
  </xsd:restriction>
</xsd:simpleType>
 
</xsd:schema>
 

Schema-Derived JAXB Classes

The code for the individual classes generated by the JAXB binding compiler for the Basic examples is listed below, followed by brief explanations of its functions. The classes listed here are:

Comment.java

In Comment.java:

The Comment.java code looks like this:

package primer.po;

public interface Comment
    extends javax.xml.bind.Element
{

    String getValue();
    void setValue(String value);
} 

Items.java

In Items.java, below:

The Items.java code looks like this:

package primer.po;

public interface Items {
   java.util.List getItem();

   public interface ItemType {
        String getPartNum();
        void setPartNum(String value);
        java.lang.String getComment();
        void setComment(java.lang.String value);
        java.math.BigDecimal getUSPrice();
        void setUSPrice(java.math.BigDecimal value);
        String getProductName();
        void setProductName(String value);
        java.util.Calendar getShipDate();
        void setShipDate(java.util.Calendar value);
        java.math.BigInteger getQuantity();
        void setQuantity(java.math.BigInteger value);
    }
} 

ObjectFactory.java

In ObjectFactory.java, below:

For example, in this case, for the Java interface primer.po.Items.ItemType, ObjectFactory creates the method createItemsItemType().

The ObjectFactory.java code looks like this:

package primer.po;

public class ObjectFactory
    extends com.sun.xml.bind.DefaultJAXBContextImpl {

    /**
     * Create a new ObjectFactory that can be used to create
     * new instances of schema derived classes for package: 
     * primer.po
     */
    public ObjectFactory() {
        super(new primer.po.ObjectFactory.GrammarInfoImpl());
    }

    /**
     * Create an instance of the specified Java content
     * interface.
     */
    public Object newInstance(Class javaContentInterface)
        throws javax.xml.bind.JAXBException
    {
        return super.newInstance(javaContentInterface);
    }

    /**
     * Get the specified property. This method can only be
     * used to get provider specific properties.
     * Attempting to get an undefined property will result
     * in a PropertyException being thrown.
     */
    public Object getProperty(String name)
        throws javax.xml.bind.PropertyException
    {
        return super.getProperty(name);
    }

    /**
     * Set the specified property. This method can only be
     * used to set provider specific properties.
     * Attempting to set an undefined property will result
     * in a PropertyException being thrown.
     */
    public void setProperty(String name, Object value)
        throws javax.xml.bind.PropertyException
    {
        super.setProperty(name, value);
    }

    /**
     * Create an instance of PurchaseOrder
     */
    public primer.po.PurchaseOrder createPurchaseOrder()
        throws javax.xml.bind.JAXBException
    {
        return ((primer.po.PurchaseOrder)
            newInstance((primer.po.PurchaseOrder.class)));
    }

    /**
     * Create an instance of ItemsItemType
     */
    public primer.po.Items.ItemType createItemsItemType()
        throws javax.xml.bind.JAXBException
    {
        return ((primer.po.Items.ItemType)
            newInstance((primer.po.Items.ItemType.class)));
    }

    /**
     * Create an instance of USAddress
     */
    public primer.po.USAddress createUSAddress()
        throws javax.xml.bind.JAXBException
    {
        return ((primer.po.USAddress)
            newInstance((primer.po.USAddress.class)));
    }

    /**
     * Create an instance of Comment
     */
    public primer.po.Comment createComment()
        throws javax.xml.bind.JAXBException
    {
        return ((primer.po.Comment)
            newInstance((primer.po.Comment.class)));
    }

    /**
     * Create an instance of Comment
     */
    public primer.po.Comment createComment(String value)
        throws javax.xml.bind.JAXBException
    {
        return new primer.po.impl.CommentImpl(value);
    }

    /**
     * Create an instance of Items
     */
    public primer.po.Items createItems()
        throws javax.xml.bind.JAXBException
    {
        return ((primer.po.Items)
            newInstance((primer.po.Items.class)));
    }

    /**
     * Create an instance of PurchaseOrderType
     */
    public primer.po.PurchaseOrderType createPurchaseOrderType()
        throws javax.xml.bind.JAXBException
    {
        return ((primer.po.PurchaseOrderType)
            newInstance((primer.po.PurchaseOrderType.class)));
    }
} 

PurchaseOrder.java

In PurchaseOrder.java, below:

The PurchaseOrder.java code looks like this:

package primer.po;

public interface PurchaseOrder
extends javax.xml.bind.Element, primer.po.PurchaseOrderType{
} 

PurchaseOrderType.java

In PurchaseOrderType.java, below:

The PurchaseOrderType.java code looks like this:

package primer.po;

public interface PurchaseOrderType {
    primer.po.Items getItems();
    void setItems(primer.po.Items value);
    java.util.Calendar getOrderDate();
    void setOrderDate(java.util.Calendar value);
    java.lang.String getComment();
    void setComment(java.lang.String value);
    primer.po.USAddress getBillTo();
    void setBillTo(primer.po.USAddress value);
    primer.po.USAddress getShipTo();
    void setShipTo(primer.po.USAddress value);
} 

USAddress.java

In USAddress.java, below:

The USAddress.java code looks like this:

package primer.po;

public interface USAddress {
    String getState();
    void setState(String value);
    java.math.BigDecimal getZip();
    void setZip(java.math.BigDecimal value);
    String getCountry();
    void setCountry(String value);
    String getCity();
    void setCity(String value);
    String getStreet();
    void setStreet(String value);
    String getName();
    void setName(String value);
}