Generating default binding and code from schema
It's easy to generate a JiBX binding definition, and the corresponding Java code, from an XML schema definition. You'll learn how in this section.
Introducing the simple example schema
As a simple example, I'll start with one of the schemas generated in Part 1. Listing 1 shows an abbreviated version of this schema, intended to represent an order from an online store. The full schema is supplied as starter.xsd in the sample code's dwcode2 directory.
Listing 1. First example schema
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://jibx.org/starter" elementFormDefault="qualified"
targetNamespace="http://jibx.org/starter">
<xs:simpleType name="shipping">
<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:restriction>
</xs:simpleType>
<xs:complexType name="item">
<xs:annotation>
<xs:documentation>Order line item information.</xs:documentation>
</xs:annotation>
<xs:sequence/>
<xs:attribute type="xs:string" use="required" name="id">
<xs:annotation>
<xs:documentation>Stock identifier. This is expected to be 12 characters in
length, with two leading alpha characters followed by ten decimal digits.
</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute type="xs:int" use="required" name="quantity">
<xs:annotation>
<xs:documentation>Number of units ordered.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute type="xs:float" use="required" name="price">
<xs:annotation>
<xs:documentation>Price per unit.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="address">
<xs:annotation>
<xs:documentation>Address information.</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element type="xs:string" name="street1">
<xs:annotation>
<xs:documentation>First line of street information (required).
</xs:documentation>
</xs:annotation>
</xs:element>
...
</xs:sequence>
<xs:attribute type="xs:string" name="state">
<xs:annotation>
<xs:documentation>State abbreviation (required for the U.S. and Canada,
optional otherwise).</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute type="xs:string" name="postCode">
<xs:annotation>
<xs:documentation>Postal code (required for the U.S. and Canada, optional
otherwise).</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
<xs:complexType name="customer">
<xs:annotation>
<xs:documentation>Customer information.</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element type="xs:long" name="customerNumber"/>
...
</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 type="xs:long" name="orderNumber"/>
<xs:element type="tns:customer" name="customer"/>
<xs:element type="tns:address" name="billTo">
<xs:annotation>
<xs:documentation>Billing address information.</xs:documentation>
</xs:annotation>
</xs:element>
...
<xs:element type="tns:item" name="item" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute type="xs:date" use="required" name="orderDate">
<xs:annotation>
<xs:documentation>Date order was placed with server.</xs:documentation>
</xs:annotation>
</xs:attribute>
...
</xs:complexType>
</xs:schema>
|
 |
Generating the default binding and code
To generate a JiBX binding and Java classes from an XML schema, you just need to run the org.jibx.schema.codegen.CodeGen tool included in the jibx-tools.jar from the JiBX distribution. You can run the tool directly from the command line or indirectly via a build tool such as Apache Ant.
The tutorial download includes an Ant build.xml script with the codegen target to run the generation.
To try this out, open a console in the dwcode2 directory of the installed download and type ant codegen. If you have Ant installed on your system and have installed the download code according to the instructions, you should see output similar to that shown in Figure 1:
Figure 1. Using the Ant build
You can also run CodeGen directly from the console. To do this, you need to:
- Include the jibx-tools.jar in your Java classpath.
- Specify
org.jibx.schema.codegen.CodeGen as the class to be run.
- List the schema definition(s) to be generated.
The supplied Ant codegen target uses a couple of additional parameters to tell CodeGen to use the gen/src directory as the root of the generated data-model package structure and to wipe all existing files out of that directory before running the generation. Here's the Java command line for duplicating the Ant codegen target from a console in the dwcode2 directory (assuming you've followed the recommended installation instructions):
java -cp ../lib/jibx-tools.jar org.jibx.schema.codegen.CodeGen -t gen/src -w starter.xsd |
On Windows, the command is:
java -cp ..\lib\jibx-tools.jar org.jibx.schema.codegen.CodeGen -t gen\src -w starter.xsd |
You can pass many other options to CodeGen from the command line. You'll look into those later in the tutorial. Now let's take a look at the generated Java code.
Generated artifacts
The generated code consists of five classes, corresponding to the five global type
definitions in the Listing 1 schema. Listing 2 shows some samples of the generated code, with excerpts from the org.jibx.starter.Order class and the entire org.jibx.starter.Shipping class:
Listing 2. Generated code
/**
* Order information.
*
* Schema fragment(s) for this class:
* <pre>
* <xs:complexType xmlns:ns="http://jibx.org/starter"
xmlns:xs="http://www.w3.org/2001/XMLSchema" name="order">
* <xs:sequence>
* <xs:element type="xs:long" name="orderNumber"/>
* <xs:element type="ns:customer" name="customer"/>
* <xs:element type="ns:address" name="billTo"/>
* <xs:element type="ns:shipping" name="shipping"/>
* <xs:element type="ns:address" name="shipTo" minOccurs="0"/>
* <xs:element type="ns:item" name="item" minOccurs="0" maxOccurs="unbounded"/>
* </xs:sequence>
* <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>
* </pre>
*/
public class Order
{
private long orderNumber;
private Customer customer;
private Address billTo;
private Shipping shipping;
private Address shipTo;
private List<Item> itemList = new ArrayList<Item>();
private Date orderDate;
private Date shipDate;
private Float total;
...
/**
* Get the 'shipTo' element value. Shipping address information. If missing, the
* billing address is also used as the shipping address.
*/
public Address getShipTo() {
return shipTo;
}
/**
* Set the 'shipTo' element value. Shipping address information. If missing, the
* billing address is also used as the shipping address.
*/
public void setShipTo(Address shipTo) {
this.shipTo = shipTo;
}
/**
* Get the list of 'item' element items.
*/
public List<Item> getItems() {
return itemList;
}
/**
* Set the list of 'item' element items.
*/
public void setItems(List<Item> list) {
itemList = list;
}
...
}
/**
* 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.
*
* Schema fragment(s) for this class:
* <pre>
* <xs:simpleType xmlns:xs="http://www.w3.org/2001/XMLSchema" name="shipping">
* <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>
* </pre>
*/
public enum Shipping {
STANDARD_MAIL, PRIORITY_MAIL, INTERNATIONAL_MAIL, DOMESTIC_EXPRESS,
INTERNATIONAL_EXPRESS
} |
As you can see from Listing 2, CodeGen automatically converts schema documentation to Javadocs in the generated code (shown here as the leading comments in each class Javadoc, and as part of the comments for the getShipTo() and setShipTo() methods). CodeGen by default also incorporates the actual schema definitions in the class Javadocs and for get/set property-access methods it describes the schema component corresponding to the property.
For repeated values, such as the repeating item element within the Listing 1 order
complexType definition, CodeGen generates a Java 5 typed
list by default. For simpleType restriction enumerations,
such as the shipping type in Listing 1, CodeGen generates a Java 5 enum type by default.
The generated code for both of these instances is shown in Listing 2.
Generated JiBX binding
Besides the generated code, CodeGen also produces a JiBX binding definition (as the binding.xml file, in this case), which tells the JiBX binding compiler how to convert between the Java classes and XML. Binding definitions contain full details of the conversions to be done by JiBX, so they're necessarily complex. Fortunately, you don't need to understand the binding definition in order to work with JiBX using CodeGen binding and code generation, so this tutorial doesn't cover the details.
|