通过代码生成默认绑定和模式
 |
非 Java 5 用法
教程示例代码使用 Java 5 类型的集合和枚举功能,但是 JiBX 本身完全兼容更早的 Java 版本。标准的 JiBX 运行时可以与 1.3 及更高版本的 JVM 结合使用,并且还可以构建与 J2ME 兼容的产品。大多数其他 JiBX 组件(包括 BindGen)都可以在 1.4.1 和更高版本的 JVM 上运行。JiBX 下载中的 BindGen 文档包括一个示例,展示自定义如何能够在使用 Java 5 以前的代码的情况下为 BindGen 提供等效的类型集合。
|
|
通过 Java 代码生成 JiBX 绑定定义和相应的 XML 模式定义非常容易。您将在本节中了解具体操作。
Java 示例代码简介
作为示例,我将使用表示在线商店订单的一组 bean 样式(私有字段、公共 get 和 set 访问方法)的类的 Java 代码。
清单 1 显示了简短版本的代码,其中大多数 get/set 方法已省去。完整的样例代码位于样例代码的 src 目录中。
清单 1. 基本 Java 代码
package org.jibx.starter;
/**
* Order information.
*/
public class Order
{
private long orderNumber;
private Customer customer;
/** Billing address information. */
private Address billTo;
private Shipping shipping;
/** Shipping address information. If missing, the billing address is also used as the
shipping address. */
private Address shipTo;
private List<Item> items;
/** Date order was placed with server. */
private Date orderDate;
/** Date order was shipped. This will be <code>null</code> if the order has not
yet shipped. */
private Date shipDate;
private Float total;
public long getOrderNumber() {
return orderNumber;
}
...
}
/**
* Customer information.
*/
public class Customer
{
private long customerNumber;
/** Personal name. */
private String firstName;
/** Family name. */
private String lastName;
/** Middle name(s), if any. */
private List<String> middleNames;
...
}
/**
* Address information.
*/
public class Address
{
/** First line of street information (required). */
private String street1;
/** Second line of street information (optional). */
private String street2;
private String city;
/** State abbreviation (required for the U.S. and Canada, optional otherwise). */
private String state;
/** Postal code (required for the U.S. and Canada, optional otherwise). */
private String postCode;
/** Country name (optional, U.S. assumed if not supplied). */
private String country;
...
}
/**
* Order line item information.
*/
public class Item
{
/** Stock identifier. This is expected to be 12 characters in length, with two
leading alpha characters followed by ten decimal digits. */
private String id;
/** Text description of item. */
private String description;
/** Number of units ordered. */
private int quantity;
/** Price per unit. */
private float price;
...
}
/**
* 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.
*/
public enum Shipping
{
STANDARD_MAIL, PRIORITY_MAIL, INTERNATIONAL_MAIL, DOMESTIC_EXPRESS,
INTERNATIONAL_EXPRESS
} |

 |

|
生成默认绑定和模式
要通过一些 Java 类生成 JiBX 绑定和 XML 模式,首先需要编译这些类,然后运行 JiBX 发行版的 jibx-tools.jar 中附带的 org.jibx.binding.generator.BindGen 工具。您可以通过命令行直接运行该工具,也可以通过 Ant 之类的构建工具间接运行该工具。
本教程的下载部分包括 Ant build.xml 脚本,其中 compile 目标用于编译示例代码,bindgen 目标用于在编译后的代码上运行 BindGen 程序。
要尝试使用此脚本,请打开已安装下载的 dwcode1 目录中的控制台,然后输入 ant compile bindgen。如果系统中安装了 Ant 并且根据说明安装了下载代码,则应当会看到类似图 1 中所示的输出:
图 1. 使用 Ant 构建
您还可以直接从控制台运行 BindGen。为此,需要在 Java 类路径中包括 jibx-tools.jar,以及用作生成输入的编译后的类文件路径。如果需要复制 Ant bindgen 目标的效果,则还需要在命令行中传递类的源文件的根目录。最后,需要列出希望用于生成的根类。在 UNIX® 和 Linux® 系统中,用于在 dwcode1 目录(假定您遵循了推荐安装说明)中通过控制台复制 Ant bindgen 目标的 Java 命令行(包含单独的一行代码,即使它在显示屏中显示为多行)为:
java -cp ../lib/jibx-tools.jar:bin org.jibx.binding.generator.BindGen
-s src org.jibx.starter.Order |
On Windows, the command (a single line, regardless of its appearance here) is:
java -cp ..\lib\jibx-tools.jar;bin org.jibx.binding.generator.BindGen
-s src org.jibx.starter.Order |
许多其他选项可以通过命令行传递给 BindGen。您稍后将在教程中看到这些选项。现在,让我们看一看生成的模式。
生成的工件
清单 2 显示了通过 BindGen(即 starter.xsd)生成的模式输出,其中进行了略微调整以适应页面宽度,并且删除了一些细节。匹配各个 Java 类的模式定义的开始标记用粗体显示以强调结构。
清单 2. 生成的模式
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://jibx.org/starter" elementFormDefault="qualified"
targetNamespace="http://jibx.org/starter">
<xs:complexType name="address">
<xs:annotation>
<xs:documentation>Address information.</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element type="xs:string" name="street1" minOccurs="0">
<xs:annotation>
<xs:documentation>First line of street information (required).</xs:documentation>
</xs:annotation>
</xs:element>
...
</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" minOccurs="0">
<xs:complexType>
...
</xs:complexType>
</xs:element>
<xs:element type="tns:address" name="billTo" minOccurs="0">
<xs:annotation>
<xs:documentation>Billing address information.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="shipping" minOccurs="0">
<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:restriction>
</xs:simpleType>
</xs:element>
<xs:element type="tns:address" name="shipTo" minOccurs="0">
<xs:annotation>
<xs:documentation>Shipping address information. If missing, the billing address is
also used as the shipping address.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="item" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="id" minOccurs="0">
<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:element>
<xs:element type="xs:string" name="description" minOccurs="0">
<xs:annotation>
<xs:documentation>Text description of item.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
<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:element>
</xs:sequence>
<xs:attribute type="xs:long" use="required" name="orderNumber"/>
<xs:attribute type="xs:date" name="orderDate">
<xs:annotation>
<xs:documentation>Date order was placed with server.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute type="xs:date" name="shipDate">
<xs:annotation>
<xs:documentation>
<![CDATA[Date order was shipped. This will be <code>null</code> if the order
has not yet shipped.]]></xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:schema> |
默认情况下,BindGen 将为只使用一次的类型生成带有嵌套的 complexType 和 simpleType 定义的模式,并为使用多次的类型生成带有各种定义的模式。在这种情况下,嵌套的样式将得到只有 3 个全局定义的模式:address 和 order 复杂类型以及 order 元素。Order 类在两个位置使用了 Address 类(表示帐单地址和送货地址),因此该类在模式中是由单独的全局定义表示的(仅当定义为全局定义时,模式才允许您重用定义)。Java 数据结构中的其他类(Customer、Item 和 Shipping)都只在 Order 类中被引用了一次,因此相应的类型定义是直接嵌入到 order 模式类型定义中的。
可以通过输入类中的 Javadoc 生成模式文档,这是 BindGen 比较棒的功能之一。在 清单 2 中,您可以看到 清单 1 中带有 Javadoc 的各个字段的模式文档,以及与带有 Javadoc 的类对应的各个全局类型的模式文档。BindGen 的默认处理并不能使所有形式的 Javadoc 与模式组件相匹配 — 并且某些 Javadoc(例如关于 “get” 访问方法的 Javadoc)在转换成模式文档后可能看上去很奇怪 — 但是得到的模式文档对于阐明 XML 表示的正确用法极为有用。如果需要在转换过程中对文本进行某些更改(例如从 “get” 方法 Javadoc 中去掉 “Get the ...” 引导语句),您甚至可以为用作模式文档的 Javadoc 定义您自己的 formatter 类。
仅当您可以获得类的源代码并且为 BindGen 提供一个实参告诉它根目录路径时,才可以使用这项 Javadoc 转换功能。在我先前提供的命令行样例中(请参阅 生成默认绑定和模式),提供的源代码路径为 -s src。
生成的 JiBX 绑定
除了模式定义之外,BindGen 还将生成 JiBX 绑定定义(在本例中为 binding.xml 文件),该绑定定义将告诉 JiBX 绑定编译器如何在 Java 类与 XML 之间进行转换。实际上,该绑定定义是 BindGen 的主要输出,同时通过绑定生成了模式。绑定定义包含 JiBX 所完成的转换的完整信息,因此它们必然非常复杂。幸运的是,使用 BindGen 绑定和模式生成,您无需了解绑定定义即可使用 JiBX,因此本教程不会介绍这部分详细信息。
|