Tải bản đầy đủ (.pdf) (67 trang)

JiBX 1.2, Phần 2: Từ lược đồ XML thành mã Java Tạo mã Java tùy chỉnh, sạch hơn từ lược đồ XML pot

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (362.53 KB, 67 trang )

JiBX 1.2, Phần 2: Từ lược đồ XML thành mã Java
Tạo mã Java tùy chỉnh, sạch hơn từ lược đồ XML
Dennis Sosnoski, Nhà tư vấn, Sosnoski Software Solutions, Inc.
Tóm tắt: Việc tạo mã từ các định nghĩa lược đồ XML được sử dụng rộng rãi cho
mọi kiểu trao đổi dữ liệu XML, bao gồm cả các dịch vụ Web. Hầu hết các công cụ
liên kết dữ liệu cấu trúc một cách cứng nhắc mã được tạo ra dựa trên lược đồ —
ngay cả các khía cạnh của lược đồ không liên quan gì đến ứng dụng của bạn.
Trong hướng dẫn này, là phần thứ hai của loạt bài hai phần, sẽ tìm hiểu cách làm
thế nào để JiBX 1.2 tạo ra mã sạch hơn qua việc thực hiện diễn dịch lược đồ tốt
hơn và loại bỏ các lớp lộn xộn không cần thiết. Bạn cũng sẽ thấy có thể tùy chỉnh
mã được tạo ra như thế nào để phù hợp tốt hơn với nhu cầu của bạn, bao gồm các
tuỳ chỉnh có thể dễ dàng loại bỏ các thành phần không cần thiết của lược đồ.
Trước khi bắt đầu
Về hướng dẫn này
JiBX là một công cụ để liên kết dữ liệu XML với các đối tượng Java™. Liên kết
dữ liệu JiBX đã được biết đến từ lâu như là cách tiếp cận nhanh nhất và linh hoạt
nhất để liên kết mã Java tới XML. Nhưng sự phức tạp của các định nghĩa liên kết
JiBX và sự hỗ trợ còn hạn chế của nó với các định nghĩa lược đồ XML đang được
sử dụng ngày càng rộng rãi hơn đã làm cho những người dùng thất vọng nhiều lần.
May mắn thay, phiên bản 1.2 của JiBX đã tiến một bước dài theo hướng loại bỏ
những vấn đề này. Trong hướng dẫn này, bạn sẽ tìm hiểu về việc sử dụng các đặc
tính mới của JiBX 1.2 để tạo ra các định nghĩa lược đồ XML một cách dễ dàng từ
mã Java hiện có và để đọc và viết các tài liệu khớp với các định nghĩa lược đồ đã
tạo ra — hoàn toàn không cần phải đi vào các chi tiết của các định nghĩa liên kết
của JiBX. Phần 1 trình bày nửa còn lại của vấn đề: bắt đầu từ mã Java và tạo ra
các định nghĩa lược đồ XML.
Mục tiêu
Hướng dẫn này chỉ dẫn cho bạn về quá trình sử dụng JiBX để tạo mã Java từ các
định nghĩa lược đồ XML. Đầu tiên, bạn sẽ tìm hiểu cách làm việc một lược đồ đơn
giản và tạo ra một mô hình dữ liệu Java mặc định khớp với lược đồ này như thế
nào, sau đó sử dụng mô hình dữ liệu để đọc và việt các tài liệu XML. Tiếp theo


bạn sẽ thấy cách làm thế nào để có thể sử dụng các tùy chỉnh để sửa đổi việc sinh
mã sao cho nó phù hợp tốt hơn với các yêu cầu của bạn. Cuối cùng, bạn sẽ chuyển
đến một ví dụ lược đồ chuẩn- công nghiệp phức tạp hơn và khám phá khả năng
của các tùy chỉnh để làm đơn giản mô hình dữ liệu đã được sinh ra cho lược đồ đó
và cải thiện khả năng sử dụng. Sau khi đọc hướng dẫn này và thực hiện hết các ví
dụ được cung cấp, bạn sẽ có khả năng sử dụng JiBX để tạo ra các mô hình dữ liệu
Java tùy chỉnh cho các lược đồ riêng của bạn.


Các điều kiện cần có trước
Để hiểu được hướng dẫn này, bạn ít nhất nên có các kiến thức cơ bản về cả mã
Java và XML. Bạn không cần phải hiểu biết chi tiết về các định nghĩa lược đồ
XML nhưng sự quen thuộc với các lược đồ sẽ giúp bạn hiểu rõ các ví dụ tốt hơn.


Các yêu cầu hệ thống
Để chạy các ví dụ này, bạn cần phải cài đặt:
 Cả hai:
o Sun's JDK 1.5.0_09 (hoặc mới hơn).
o Bộ dụng cụ cho nhà phát triển của IBM cho công nghệ Java 1.5.0
SR3.
 Một phiên bản mới nhất của công cụ xây dựng Apache Ant.
Các hướng dẫn tải về và cài đặt JiBX có trong hướng dẫn này.
Giới thiệu JiBX
JiBX là một trong nhiều công cụ dùng để chuyển đổi giữa các cấu trúc dữ liệu
Java và các tài liệu XML (xem Tài nguyên). Cái làm nên sự khác biệt của JiBX so
với những công cụ khác là các đặc tính linh hoạt và hiệu năng. Hiệu năng của
JiBX luôn được đánh giá ở vị trí cao nhất trong lĩnh vực này, vượt quá hai lần
hoặc hơn nữa so với hiệu năng của các công cụ phổ biến khác (như JAXB 2.0
chẳng hạn). JiBX cũng linh hoạt hơn hơn hầu hết tất cả các công cụ Java-XML

khác, khi sử dụng các định nghĩa liên kết để tách các cấu trúc Java khỏi mô tả
XML sao cho từng cái có thể được thay đổi độc lập với cái kia.
Với bản phát hành 1.2, JiBX bổ sung thêm các đặc tính hỗ trợ các định nghĩa lược
đồ XML. Bạn có thể sử dụng các công cụ kèm theo trong bản phát hành JiBX để
tạo ra một định nghĩa lược đồ khớp với mã Java của bạn hoặc để tạo ra mã Java
khớp với định nghĩa lược đồ của bạn. Dù bằng cách nào, bạn cũng nhận được một
định nghĩa liên kết để cho phép bạn sử dụng JiBX để chuyển đổi giữa các mã Java
và các tài liệu XML khớp với định nghĩa lược đồ. Trong hướng dẫn này, bạn sẽ
thấy cách làm thế nào để áp dụng kiểu tạo thứ hai: từ định nghĩa lược đồ tạo mã
Java.
Cài đặt JiBX
Bạn cần phải cài đặt JiBX trước khi tiếp tục thực hiện hướng dẫn này. Hãy Tải về
bản ZIP phân phối mới nhất 1.2.x và giải nén nó vào một chỗ thuận tiện trên hệ
thống của bạn. Xong việc, bạn sẽ nhận được một thư mục có tên là jibx, trong đó
có chứa tất cả các tệp JiBX JAR, tài liệu hướng dẫn, các ví dụ và thậm chí cả mã
nguồn.
Cài đặt mã nguồn các ví dụ của hướng dẫn này
Bây giờ hãy tải về các mã mẫu của hướng dẫn này, cũng được cung cấp dưới dạng
một tệp tin ZIP. Cách dễ nhất để cài đặt nó trên hệ thống của bạn là giải nén tệp tin
ZIP vào thư mục gốc của bản phân phối JiBX của bạn (hoặc trên Windows®, sao
chép thư mục dwcode1 từ bên trong tệp tin ZIP này vào thư mục gốc bản phân
phối JiBX của bạn). Điều này sẽ tạo ra một thư mục con dwcode2 trong thư mục
jibx, với các tệp tin ví dụ (bao gồm cả các tệp tin build.xml, custom.xml và các tệp
tin khác) bên trong thư mục con dwcode2 đó.
Mã mẫu bao gồm một tệp tin xây dựng Ant Apache để tự động hoá cho chạy các
công cụ JiBX và xử lý các bước khác có trong các ví dụ. Nếu bạn cài đặt các mã
mẫu trực tiếp vào thư mục cài đặt của JiBX, công cụ xây dựng (build) có thể truy
cập các tệp JiBX JAR mà không cần thêm bất kỳ cấu hình nào. Nếu bạn cài đặt
các mã mẫu ở nơi khác, bạn vẫn có thể sử dụng công cụ xây dựng Ant. Trong
trường hợp này, bạn chỉ cần chỉnh sửa tệp tin build.properties bên trong thư mục

mã mẫu và thay đổi giá trị của thuộc tính jibx-home thành đường dẫn đến bản cài
đặt JiBX của bạn.
Tạo liên kết và mã mặc định từ lược đồ
Rất dễ dàng để tạo ra một định nghĩa liên kết JiBX và mã Java tương ứng từ một
định nghĩa lược đồ XML. Bạn sẽ tìm hiểu cách làm thế nào trong phần này.
Giới thiệu về ví dụ lược đồ đơn giản
Như một ví dụ đơn giản, tôi sẽ bắt đầu với một trong những lược đồ được tạo ra
trong Phần 1. Listing 1 hiển thị một phiên bản rút gọn của lược đồ này, nhằm biểu
diễn một đơn hàng từ một cửa hàng trực tuyến. Lược đồ đầy đủ được cung cấp
trong tệp tin starter.xsd trong thư mục của dwcode2 của mã mẫu.

Listing 1. Lược đồ ví dụ đầu tiên

<xs:schema
xmlns:xs="
xmlns:tns="
elementFormDefault="qualified"
targetNamespace="
<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>



Tạo mã và liên kết mặc định
Để tạo ra một liên kết JiBX và các lớp Java từ một lược đồ XML, bạn chỉ cần chạy
công cụ org.jibx.schema.codegen.CodeGen có trong tệp tin jibx-tools.jar từ bản
phân phối JiBX. Bạn có thể chạy công cụ trực tiếp từ dòng lệnh hoặc gián tiếp
thông qua một công cụ xây dựng như Ant Apache.
Phần tải về của hướng dẫn bao gồm một kịch bản lệnh Ant là build.xml có đích
codegen để thực hiện hoạt động tạo mã.
Để thử điều này, hãy mở một cửa sổ dòng lệnh trong thư mục dwcode2 nơi đã cài
đặt bản tải về và gõ ant codegen. Nếu bạn đã cài đặt Ant trên hệ thống của mình và
cài đặt mã tải về theo đúng các hướng dẫn, bạn sẽ nhìn thấy kết quả tương tự như

được hiển thị trong Hình 1:

Hình 1. Sử dụng công cụ xây dựng Ant

Bạn cũng có thể chạy CodeGen trực tiếp từ cửa sổ dòng lệnh. Để làm được điều
này, bạn cần phải:
1. Đưa tên tệp tin jibx-tools.jar vào đường dẫn lớp (classpath) Java của bạn.
2. Chỉ rõ org.jibx.schema.codegen.CodeGen là lớp được chạy.
3. Liệt kê (các) định nghĩa lược đồ được tạo ra.
Đích Ant codegen đã cho sử dụng một số tham số bổ sung thêm để ra lệnh cho
CodeGen sử dụng thư mục gen/src như là gốc của cấu trúc gói mô hình dữ liệu
được tạo ra và xóa hết tất cả các tệp tin hiện có khỏi thư mục đó trước khi thực
hiện hoạt động tạo mã. Đây là dòng lệnh Java để sao đúp đích Ant codegen từ một
cĐửa sổ dòng lệnh trong thư mục dwcode2 (giả định bạn đã làm theo đúng hướng
dẫn cài đặt được đề nghị):
java
-cp /lib/jibx-tools.jar org.jibx.schema.codegen.CodeGen -t gen/src -w
starter.xsd

Trên Windows, lệnh đó là:
java
-cp \lib\jibx-tools.jar org.jibx.schema.codegen.CodeGen -t gen\src -w
starter.xsd

Bạn có thể chuyển tới CodeGen nhiều tùy chọn khác từ dòng lệnh. Bạn sẽ xem xét
chúng sau trong hướng dẫn này. Bây giờ chúng ta hãy xem mã Java đã tạo ra.


Các tạo phẩm đã tạo ra
Mã được tạo ra bao gồm năm lớp, tương ứng với năm định nghĩa kiểu toàn cục

trong lược đồ ở Listing 1. Listing 2 cho thấy một số mẫu của mã được tạo ra với
các đoạn trích từ lớp org.jibx.starter.Order và toàn bộ lớp org.jibx.starter.Shipping:

Listing 2. Mã được tạo ra

/**
* Order information.
*
* Schema fragment(s) for this class:
* <pre>
* <xs:complexType xmlns:ns="
xmlns:xs=" 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="
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
}

Như bạn có thể thấy từ Listing 2, CodeGen sẽ tự động chuyển đổi tài liệu lược đồ
thành Javadocs trong mã đã tạo ra (ở đây hiển thị như là các chú thích đứng trước
trong Javadoc của mỗi lớp và như là một phần của các chú thích cho các phương
thức getShipTo() và setShipTo()). CodeGen theo mặc định cũng sát nhập cả các
định nghĩa lược đồ hiện tại vào Javadocs của lớp và đối với các phương thức
get/set để truy nhập thuộc tính, nó mô tả thành phần lược đồ tương ứng với thuộc
tính ấy.
Đối với các giá trị lặp lại, ví dụ như phần tử mục hàng lặp lại nhiều lần trong định
nghĩa kiểu phức hợp (complexType) đơn hàng ở Listing 1, CodeGen tạo ra một
danh sách có định kiểu của Java 5 theo mặc định. Đối với các bảng kê hạn chế
kiểu đơn giản (simpleType), ví dụ như kiểu vận chuyển (shipping) trong Listing 1,
CodeGen tạo ra một kiểu enum của Java 5 theo mặc định. Mã được tạo ra cho cả
hai trường hợp này được hiển thị trong Listing 2.
Liên kết JiBX được tạo ra
Bên cạnh mã đã tạo ra, CodeGen cũng đưa ra một định nghĩa liên kết JiBX (là tệp
tin binding.xml, trong trường hợp này). Định nghĩa liên kết báo cho trình biên dịch
liên kết JiBX biết cách chuyển đổi giữa các lớp Java và XML như thế nào. Các
định nghĩa liên kết bao gồm đầy đủ các chi tiết về các phép biến đổi được JiBX
thực hiện, do đó chúng nhất định là phải phức tạp. May mắn thay, bạn không cần
phải hiểu định nghĩa liên kết để làm việc với JiBX khi sử dụng tạo mã và liên kết
của CodeGen, vì vậy hướng dẫn này không trình bày các chi tiết ở đây.
Làm việc với các tài liệu XML
Trong phần này, bạn sẽ tìm hiểu về việc chạy trình biên dịch liên kết JiBX và việc
sử dụng JiBX lúc đang chạy thực để làm việc với các tài liệu XML.
Chạy trình biên dịch liên kết JiBX

Để sử dụng định nghĩa liên kết được tạo ra trong khi làm việc với các tài liệu
XML, trước hết bạn cần phải chạy công cụ trình biên dịch liên kết JiBX. Trình
biên dịch liên kết thêm mã byte (bytecode) vào các tệp tin lớp đã biên dịch của bạn
để thực sự triển khai thực hiện các phép biến đổi thành XML và từ XML, như định
nghĩa liên kết đã chỉ rõ. Bạn phải chạy trình biên dịch liên kết mỗi khi bạn biên
dịch lại lớp Java của bạn hoặc sửa đổi định nghĩa liên kết, vì vậy tốt nhất là thêm
bước biên dịch liên kết như là một phần của quá trình xây dựng tiêu chuẩn của các
dự án của bạn.
Trình biên dịch liên kết có trong bản phân phối JiBX như là một phần của tệp tin
jibx-bind.jar. Tài liệu JiBX cung cấp đầy đủ các chi tiết về các cách khác nhau để
chạy trình biên dịch liên kết, bao gồm cả cách làm thế nào để bạn có thể gọi nó khi
đang chạy ứng dụng của bạn chứ không phải như là một phần của quá trình xây
dựng. JiBX cũng cung cấp các trình cắm thêm cho Eclipse và IntelliJ IDEA, có thể
tự động cho chạy trình biên dịch liên kết khi bạn đang làm việc trong các IDE này.
Với mục đích của hướng dẫn này, bạn nên làm đơn giản mọi việc và chỉ cần chạy
trình biên dịch liên kết thông qua Ant. Đích compile của tập tin build.xml sẵn sàng
liên kết bằng cách biên dịch cả mã đã tạo ra và chương trình thử nghiệm được
cung cấp, trong khi đích bind thực sự chạy trình biên dịch liên kết. Hình 2 cho
thấy kết quả đầu ra mà bạn sẽ thấy khi bạn chạy đích này, giả định bạn đã chạy các
đích codegen. (Bạn cũng có thể chạy lần lượt tất cả ba đích này bằng cách liệt kê
chúng theo thứ tự trên dòng lệnh: ant codegen compile bind.)

Hình 2. Các tác vụ compile và bind của công cụ xây dựng Ant



Sử dụng JiBX trong môi trường đang chạy chương trình
Listing 3 cho thấy một tài liệu thử nghiệm đơn giản khớp với lược đồ, có trong mã
tải về của hướng dẫn này, là tệp tin:


Listing 3. Tài liệu kiểm tra cho lược đồ đơn hàng

<order orderDate="2008-10-18" shipDate="2008-10-22"
xmlns="
<orderNumber>12345678</orderNumber>
<customer>
<customerNumber>5678</customerNumber>
<firstName>John</firstName>
<lastName>Smith</lastName>
</customer>
<billTo state="WA" postCode="98059">
<street1>12345 Happy Lane</street1>
<city>Plunk</city>
<country>USA</country>
</billTo>
<shipping>PRIORITY_MAIL</shipping>
<shipTo state="WA" postCode="98034">
<street1>333 River Avenue</street1>
<city>Kirkland</city>
</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>

Gói tải về cũng bao gồm một chương trình kiểm tra đơn giản, được hiển thị ở đây
như Listing 4, để trình bày việc sử dụng JiBX cho cả hai tài liệu không tuần tự hóa
(unmarshalling) và tuần tự hóa (marshalling). Marshalling là quá trình sinh ra một
biểu diễn XML của một đối tượng trong bộ nhớ, có thể bao gồm cả các đối tượng
được liên kết với đối tượng ban đầu. Unmarshalling là quá trình ngược với tuần tự

hóa, tức là xây dựng một đối tượng (và có thể là một đồ thị của các đối tượng liên
kết với nhau) trong bộ nhớ từ một biểu diễn XML). Đích run của Ant thi hành
chương trình thử nghiệm này, bằng cách sử dụng tài liệu trong Listing 3 làm đầu
vào và viết ra một bản sao kết quả tuần tự hóa của tài liệu thành một tệp tin có tên
là out.xml.

Listing 4. Chương trình thử nghiệm
public class Test
{
/**
* Unmarshal the sample document from a file, compute and set order total, then
* marshal it back out to another file.
*
* @param args
*/
public static void main(String[] args) {
if (args.length < 2) {
System.out.println("Usage: java -cp " +
"org.jibx.starter.Test in-file out-file");
System.exit(0);
}
try {

// unmarshal customer information from file
IBindingFactory bfact = BindingDirectory.getFactory(Order.class);
IUnmarshallingContext uctx = bfact.createUnmarshallingContext();
FileInputStream in = new FileInputStream(args[0]);
Order order = (Order)uctx.unmarshalDocument(in, null);

// compute the total amount of the order

float total = 0.0f;
for (Iterator<Item> iter = order.getItems().iterator(); iter.hasNext();) {
Item item = iter.next();
total += item.getPrice() * item.getQuantity();
}
order.setTotal(new Float(total));

// marshal object back out to file (with nice indentation, as UTF-8)
IMarshallingContext mctx = bfact.createMarshallingContext();
mctx.setIndent(2);
FileOutputStream out = new FileOutputStream(args[1]);
mctx.setOutput(out, null);
mctx.marshalDocument(order);
System.out.println("Processed order with " + order.getItems().size() +
" items and total value " + total);

} catch (FileNotFoundException e) {
e.printStackTrace();
System.exit(1);
} catch (JiBXException e) {
e.printStackTrace();
System.exit(1);
}
}
}

Hình 3 hiển thị kết quả mà bạn sẽ thấy khi chạy đích run:

Hình 3. Tác vụ run của công cụ xây dựng Ant


Đây chính là chương trình thử nghiệm giống như đã sử dụng trong Phần 1 của
hướng dẫn và nó cũng chịu các hạn chế giống như đã bàn luận trong hướng dẫn
ấy. Cũng như trong Phần 1, tệp tin out.xml là kết quả sinh ra bởi tuần tự hóa
ngược lại dữ liệu đơn hàng đã nhận được khi không sắp xếp theo thứ tự tài liệu
ban đầu.
Giới thiệu các tùy chỉnh CodeGen
Trong phần này, bạn sẽ tìm hiểu những điều căn bản về tùy chỉnh CodeGen để
kiểm soát cấu trúc của mã được sinh ra từ một lược đồ đơn giản.
Một ví dụ tùy chỉnh đơn giản
CodeGen hỗ trợ rất nhiều tùy chỉnh về tất cả các khía cạnh về tạo mã và tạo liên
kết. Tập hợp các tùy chỉnh sẽ áp dụng được chuyển đến CodeGen dưới dạng một
tài liệu XML, có các phần tử lồng nhau, liên hệ với các lược đồ hay các thành
phần lược đồ. Listing 5 đưa ra một ví dụ đơn giản:

Listing 5. Ví dụ tuỳ chỉnh đơn giản
<schema prefer-inline="true" show-schema="false"
enumeration-type="simple"
generate-all="false" includes="order item"/>

Tuỳ chỉnh của Listing 5 bao gồm một phần tử lược đồ không có vùng tên với một
số thuộc tính khác nhau, cung cấp các tuỳ chỉnh cụ thể sẽ được áp dụng. (Cho đến
nay, bạn chỉ đang làm việc với một định nghĩa lược đồ, vì thế có thể sử dụng dạng
tuỳ chỉnh rất đơn giản này. Về sau trong hướng dẫn này, bạn sẽ thấy các ví dụ về
các tuỳ chỉnh để làm việc với nhiều lược đồ). Thuộc tính tuỳ biến đầu tiên —
prefer-inline="true" — ra lệnh cho CodeGen thay thế ngay vào các định nghĩa
lược đồ mà chỉ được tham chiếu một lần, thay vì áp dụng hành vi mặc định là giữ
chúng dưới dạng các lớp riêng biệt. Thuộc tính thứ hai — show-schema="false"
— chặn việc nhúng các định nghĩa lược đồ vào trong Javadoc của lớp.
enumeration-type="simple" tạo ra các bảng kê an toàn về kiểu đơn giản hơn các
bảng kê của Java 5.

Cặp thuộc tính cuối cùng làm việc cùng với nhau. CodeGen theo mặc định sẽ tạo
ra một lớp mức đỉnh riêng cho mỗi định nghĩa kiểu toàn cục trong các lược đồ ở
đầu vào, cùng với một phép ánh xạ tương ứng trong liên kết JiBX sẽ sinh ra cho
mỗi kiểu phức hợp (complexType). Thuộc tính generate-all="false" thay đổi hành
vi mặc định này, chỉ dứt khoát tạo ra các complexType đó được bao gồm cụ thể
vào hoặc được tham chiếu từ một kiểu được bao gồm ấy. Sau đó thuộc tính
includes="order item" đưa ra các tên sẽ được tạo ra; các tên này đã được lựa chọn
để bảo đảm tính tương thích với chương trình thử nghiệm — phần tử <order> là
cần phải có, bởi vì đó là phần tử gốc của mỗi cá thể tài liệu và các mục hàng kiểu
complexType là cần phải có bởi vì chương trình thử nghiệm chờ đợi sẽ tìm thấy
một lớp mức đỉnh riêng biệt cho kiểu này khi nó tính tổng giá trị của đơn hàng.
Bạn có thể thử các tuỳ chỉnh này bằng cách sử dụng tác vụ Ant custgen thay cho
tác vụ codegen (hoặc sử dụng ngay tác vụ full, để chạy toàn bộ chuỗi các đích
clean custgen compile bind run). Listing 6 cho thấy các đoạn trích của mã được
tạo ra mà bạn có thể so sánh với mã được tạo ra theo mặc định như hiển thị trong
Listing 2. Các sự khác biệt lớn (ngoài Javadoc của các lớp đã được đơn giản hóa)
là ở chỗ lớp Customer bây giờ đã được thay thế trực tiếp vào dòng lệnh và lớp
Shipping bây giờ là một lớp lồng bên trong, sử dụng một lớp bảng kê tùy chỉnh, an
toàn về kiểu.

Listing 6. Mã được tạo ra với các tuỳ chỉnh
/**
* Order information.
*/
public class Order
{
private long orderNumber;
private long customerCustomerNumber;
private String customerFirstName;
private String customerLastName;

private Address billTo;
private Shipping shipping;
private Address shipTo;

×