Going further with customizations

The Example 2 customizations showed some basic modifications to BindGen default behavior. Now it's time to go a couple of steps further, using custom2.xml:

<custom namespace-style="fixed" namespace="http://www.jibx.org/starters/fromcode"
    property-access="true">
  <package name="org.jibx.starter1">
    <class name="Address" includes="street1 city state postCode country"
        requireds="street1 city"/>
    <class name="Customer" requireds="lastName firstName /customerNumber"/>
    <class name="Item" excludes="description" requireds="@id @quantity price"/>
    <class name="Order" requireds="orderNumber customer billTo shipping orderDate"/>
  </package>
</custom>

The namespace-style="fixed" attribute on the root 'custom' element tells BindGen to use fixed namespaces, rather than deriving namespaces from package names. The namespace="http://www.jibx.org/starters/fromcode" attribute then defines the namespace to be used. If you want a single, fixed, namespace for all your XML definitions you need to use both of these attributes together - if you use the 'namespace' attribute by itself, the namespace you specify will still be modified for each nested package.

There are three other differences in this customization file, as compared to the Example 2 customizations. The 'package' element is a convenient wrapper for the 'class' elements, allowing simple class names to be used on the 'class' elements instead of fully-qualified class names. You can also add any nesting customization attributes to the 'package' element. So for example, the 'namespace-style', 'namespace', and 'property-access' attributes could all be moved from the 'custom' element to the 'package' element.

The other differences are in the 'requireds' value lists for the 'Customer' and 'Item' classes. In this version of the customizations, the list of 'requireds' value names for the 'Customer' class is in a different order and the 'customerNumber' value name is prefixed with a slash character ('/'), and the 'id' and 'quantity' value names in the 'requireds' list for the 'Item' class are prefixed with an at-sign character. These prefix characters tell BindGen to use a specific representation for the values - a slash character for an element, an at-sign character for an attribute. The prefix characters can be used for all the attributes which take value name lists: 'includes', 'optionals', and 'requireds' (they're ignored in the case of 'excludes'). Values names without one of these indicator prefix characters just use the default representation.

Generated schema

You can try out the above customization by again using the Ant 'compile' target to compile the sample code, followed by the 'custgen2' target to run BindGen using the above customizations. Here's the resulting schema (again with the longer lines split):

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:tns="http://www.jibx.org/starters/fromcode" elementFormDefault="qualified"
    targetNamespace="http://www.jibx.org/starters/fromcode">
  <xs:complexType name="address">
    <xs:annotation>
      <xs:documentation>Address information.</xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element type="xs:string" name="street1"/>
      <xs:element type="xs:string" name="city"/>
      <xs:element type="xs:string" name="state" minOccurs="0"/>
      <xs:element type="xs:string" name="postCode" minOccurs="0"/>
      <xs:element type="xs:string" name="country" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
  <xs:element type="tns:order" name="order"/>
  <xs:complexType name="order">
    <xs:annotation>
      <xs:documentation>Order information.</xs:documentation>
    </xs:annotation>
    <xs:sequence>
      <xs:element name="customer">
        <xs:complexType>
          <xs:sequence>
            <xs:element type="xs:string" name="lastName"/>
            <xs:element type="xs:string" name="firstName"/>
            <xs:element type="xs:long" name="customerNumber"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:element type="tns:address" name="billTo"/>
      <xs:element name="shipping">
        <xs:simpleType>
          <xs:annotation>
            <xs:documentation>Supported shipment methods. The "INTERNATIONAL" shipment methods
            can only be used for orders with shipping addresses outside the U.S., and one of these
            methods is required in this case.</xs:documentation>
          </xs:annotation>
          <xs:restriction base="xs:string">
            <xs:enumeration value="STANDARD_MAIL"/>
            <xs:enumeration value="PRIORITY_MAIL"/>
            <xs:enumeration value="INTERNATIONAL_MAIL"/>
            <xs:enumeration value="DOMESTIC_EXPRESS"/>
            <xs:enumeration value="INTERNATIONAL_EXPRESS"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:element>
      <xs:element type="tns:address" name="shipTo" minOccurs="0"/>
      <xs:element name="item" minOccurs="0" maxOccurs="unbounded">
        <xs:complexType>
          <xs:sequence/>
          <xs:attribute type="xs:string" use="required" name="id"/>
          <xs:attribute type="xs:int" use="required" name="quantity"/>
          <xs:attribute type="xs:float" use="required" name="price"/>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
    <xs:attribute type="xs:long" use="required" name="orderNumber"/>
    <xs:attribute type="xs:date" use="required" name="orderDate"/>
    <xs:attribute type="xs:date" name="shipDate"/>
    <xs:attribute type="xs:float" name="total"/>
  </xs:complexType>
</xs:schema>

Comparing this to the Example 2 schema shows that the schema target namespace has been changed to that specified by the customizations, the child elements of 'customer' have been reordered, the 'customerNumber' value is now an element rather than an attribute, and the 'id' value is now an attribute rather than an element (all changes shown in bold type in the listing). There's no change to the 'quantity' value representation, since that was already an attribute in the original schema.

Testing the binding

Since the actual XML structure has changed with the customizations used for this example, testing it requires a different document. The data2.xml document in the examples/bindgen directory uses the same data as data1.xml, but is restructured to match the schema changes. Here's the document:

<order orderNumber="12345678" orderDate="2008-10-18" shipDate="2008-10-22"
    xmlns="http://www.jibx.org/starters/fromcode">
  <customer>
    <lastName>Smith</lastName>
    <firstName>John</firstName>
    <customerNumber>5678</customerNumber>
  </customer>
  <billTo>
    <street1>12345 Happy Lane</street1>
    <city>Plunk</city>
    <state>WA</state>
    <postCode>98059</postCode>
    <country>USA</country>
  </billTo>
  <shipping>PRIORITY_MAIL</shipping>
  <shipTo>
    <street1>333 River Avenue</street1>
    <city>Kirkland</city>
    <state>WA</state>
    <postCode>98034</postCode>
  </shipTo>
  <item quantity="1" price="5.99" id="FA9498349851"/>
  <item quantity="2" price="9.50" id="GC1234905049"/>
  <item quantity="1" price="8.95" id="AX9300048820"/>
</order>

You can compare this to the data1.xml listing to see the changes.

Once you've run the Ant 'compile', 'custgen2', and 'bind' targets you can test the generated binding using 'run-alt' (which runs the same test program as used by the prior examples, but with data2.xml as input and out2.xml as output). You can also try out the full 'compile', 'custgen2', 'bind', and 'run-alt' sequence by using the Ant target 'custom2'.