The Java EE 5 Tutorial

Customize Inline Example

The Customize Inline example illustrates some basic customizations made by means of inline annotations to an XML schema named po.xsd. In addition, this example implements a custom data type converter class, MyDatatypeConverter.java, which illustrates print and parse methods in the <javaType> customization for handling custom data type conversions.

    To summarize this example:

  1. po.xsd is an XML schema containing inline binding customizations.

  2. MyDatatypeConverter.java is a Java class file that implements print and parse methods specified by <javaType> customizations in po.xsd.

  3. Main.java is the primary class file in the Customize Inline example, which uses the schema-derived classes generated by the JAXB compiler.

Building and Running the Customize Inline Example Using NetBeans IDE

Follow these instructions to build and run the Customize Inline example on your Application Server instance using the NetBeans IDE.

  1. In NetBeans IDE, select File->Open Project.

  2. In the Open Project dialog, navigate to tut-install/javaeetutorial5/examples/jaxb/.

  3. Select the inline-customize folder.

  4. Select the Open as Main Project check box.

  5. Click Open Project.

  6. Right-click the inline-customize project and select Run.

Building and Running the Customize Inline Example Using Ant

To compile and run the Customize Inline example using Ant, in a terminal window, go to the tut-install/javaeetutorial5/examples/jaxb/inline-customize/ directory and type the following:


ant runapp

Key customizations in this sample, and the custom MyDatatypeConverter.java class, are described in more detail below.

Customized Schema

The customized schema used in the Customize Inline example is in the file tut-install/javaeetutorial5/examples/jaxb/inline-customize/po.xsd. The customizations are in the <xsd:annotation> tags.

Global Binding Declarations

The code below shows the globalBindings declarations in po.xsd:

<jxb:globalBindings
        fixedAttributeAsConstantProperty="true"
        collectionType="java.util.Vector"
        typesafeEnumBase="xsd:NCName"
        choiceContentProperty="false"
        typesafeEnumMemberName="generateError"
        bindingStyle="elementBinding"
        enableFailFastCheck="false"
        generateIsSetMethod="false"
        underscoreBinding="asCharInWord"/>

In this example, all values are set to the defaults except for collectionType.

Schema Binding Declarations

The following code shows the schema binding declarations in po.xsd:

<jxb:schemaBindings>
  <jxb:package name="primer.myPo">
    <jxb:javadoc>
      <![CDATA[<body> Package level documentation for generated package primer.myPo.</body>]]>
    </jxb:javadoc>
  </jxb:package>
  <jxb:nameXmlTransform>
    <jxb:elementName suffix="Element"/>
  </jxb:nameXmlTransform>
</jxb:schemaBindings>

Class Binding Declarations

The following code shows the class binding declarations in po.xsd:

<xsd:complexType name="PurchaseOrderType">
      <xsd:annotation>
      <xsd:appinfo>
         <jxb:class name="POType">
            <jxb:javadoc>
            A &lt;b>Purchase Order&lt;/b> consists of addresses and items.
            </jxb:javadoc>
         </jxb:class>
      </xsd:appinfo>
      </xsd:annotation>
      .
      .
      .
</xsd:complexType>

The Javadoc tool annotations for the schema-derived POType class will contain the description "A &lt;b>Purchase Order&lt;/b> consists of addresses and items." The &lt; is used to escape the opening bracket on the <b> HTML tags.


Note –

When a <class> customization is specified in the appinfo element of a complexType definition, as it is here, the complexType definition is bound to a Java content interface.


Later in po.xsd, another <javadoc> customization is declared at this class level, but this time the HTML string is escaped with CDATA:

<xsd:annotation>
  <xsd:appinfo>
    <jxb:class>
      <jxb:javadoc>
        <![CDATA[ First line of documentation for a <b>USAddress</b>.]]>
      </jxb:javadoc>
    </jxb:class>
  </xsd:appinfo>
</xsd:annotation>

Note –

If you want to include HTML markup tags in a <jaxb:javadoc> customization, you must enclose the data within a CDATA section or escape all left angle brackets using &lt;. See XML 1.0 2nd Edition for more information.


Property Binding Declarations

Of particular interest here is the generateIsSetMethod customization, which causes two additional property methods, isSetQuantity and unsetQuantity, to be generated. These methods enable a client application to distinguish between schema default values and values occurring explicitly within an instance document.

For example, in po.xsd:

<xsd:complexType name="Items">
   <xsd:sequence>
      <xsd:element name="item" minOccurs="1" maxOccurs="unbounded">
         <xsd:complexType>
            <xsd:sequence>
            <xsd:element name="productName" type="xsd:string"/>
            <xsd:element name="quantity" default="10">
            <xsd:annotation>
               <xsd:appinfo>
                  <jxb:property generateIsSetMethod="true"/>
               </xsd:appinfo>
            </xsd:annotation>
         ...
         </xsd:complexType>
      </xsd:element>
   </xsd:sequence>
</xsd:complexType>

The @generateIsSetMethod applies to the quantity element, which is bound to a property within the Items.ItemType interface. unsetQuantity and isSetQuantity methods are generated in the Items.ItemType interface.

MyDatatypeConverter Class

The class tut-install/javaeetutorial5/examples/jaxb/inline-customize/src/inlinecustomize/primer/MyDatatypeConverter, shown below, provides a way to customize the translation of XML data types to and from Java data types by means of a <javaType> customization.

package primer;
import java.math.BigInteger;
import javax.xml.bind.DatatypeConverter;

public class MyDatatypeConverter {

    public static short parseIntegerToShort(String value) {
        BigInteger result = DatatypeConverter.parseInteger(value);
        return (short)(result.intValue());
    }

    public static String printShortToInteger(short value) {
        BigInteger result = BigInteger.valueOf(value);
        return DatatypeConverter.printInteger(result);
    }

    public static int parseIntegerToInt(String value) {
        BigInteger result = DatatypeConverter.parseInteger(value);
        return result.intValue();
    }

    public static String printIntToInteger(int value) {
        BigInteger result = BigInteger.valueOf(value);
        return DatatypeConverter.printInteger(result);
    }
};

The following code shows how the MyDatatypeConverter class is referenced in a <javaType> declaration in po.xsd:

<xsd:simpleType name="ZipCodeType">
  <xsd:annotation>
     <xsd:appinfo>
        <jxb:javaType name="int" 
            parseMethod="primer.MyDatatypeConverter.parseIntegerToInt" 
            printMethod="primer.MyDatatypeConverter.printIntTo Integer" />
     </xsd:appinfo>
  </xsd:annotation>
    <xsd:restriction base="xsd:integer">
    <xsd:minInclusive value="10000"/>
    <xsd:maxInclusive value="99999"/>
  </xsd:restriction>
</xsd:simpleType>

In this example, the jxb:javaType binding declaration overrides the default JAXB binding of this type to java.math.BigInteger. For the purposes of the Customize Inline example, the restrictions on ZipCodeType (specifically, that legal United States ZIP codes are limited to five digits) make it so all valid values can easily fit within the Java primitive data type int. Note also that, because <jxb:javaType name="int"/> is declared within ZipCodeType, the customization applies to all JAXB properties that reference this simpleType definition, including the getZip and setZip methods.