"http://www.w3.org/TR/REC-html40/loose.dtd">
Links on this page open their targets in a second window. If clicking on a link seems not to do anything, that's probably because that window is covered or minimized.
This sample processes a business order instance, as defined by UBL (Universal Business Language). It shows how JAXB helps when developing applications for industry-standard schema. The best thing is to start by running the sample, especially since many of the links in this document refer to the output.
$ JWSDP_HOME=<Your Java WSDP installation directory>
$ $JWSDP_HOME/apache-ant/bin/ant
> set JWSDP_HOME=<Your Java WSDP installation directory>
> %JWSDP_HOME%\apache-ant\bin\ant
This directory structure exists before running the project:
./cd-UBL-1.0 ) Subset of the bundle obtained from | | ) http://docs.oasis-open.org/ubl/cd-UBL-1.0.zip | | | ./xml/office ) Instance documents | | | ) Order instance | | ./UBL-Order-1.0-Office-Example.xml ) processed by | | ) this sample | | | ./xsd ) The UBL schema | | | ./codelist | | | | | ./UBL-CodeList-AcknowledgementResponseCode-1.0.xsd | | ./UBL-CodeList-AllowanceChargeReasonCode-1.0.xsd | | ./UBL-CodeList-ChannelCode-1.0.xsd | | ./UBL-CodeList-ChipCode-1.0.xsd | | ./UBL-CodeList-CountryIdentificationCode-1.0.xsd | | ./UBL-CodeList-CurrencyCode-1.0.xsd | | ./UBL-CodeList-DocumentStatusCode-1.0.xsd | | ./UBL-CodeList-LatitudeDirectionCode-1.0.xsd | | ./UBL-CodeList-LineStatusCode-1.0.xsd | | ./UBL-CodeList-LongitudeDirectionCode-1.0.xsd | | ./UBL-CodeList-OperatorCode-1.0.xsd | | ./UBL-CodeList-PaymentMeansCode-1.0.xsd | | ./UBL-CodeList-SubstitutionStatusCode-1.0.xsd | | | ./common | | | | | ./UBL-CommonAggregateComponents-1.0.xsd | | ./UBL-CommonBasicComponents-1.0.xsd | | ./UBL-CoreComponentParameters-1.0.xsd | | ./UBL-CoreComponentTypes-1.0.xsd | | ./UBL-SpecializedDatatypes-1.0.xsd | | ./UBL-UnspecializedDatatypes-1.0.xsd | | | ./maindoc | | | ./UBL-DespatchAdvice-1.0.xsd | ./UBL-Invoice-1.0.xsd | ./UBL-Order-1.0.xsd | ./UBL-OrderCancellation-1.0.xsd | ./UBL-OrderChange-1.0.xsd | ./UBL-OrderResponse-1.0.xsd | ./UBL-OrderResponseSimple-1.0.xsd | ./UBL-ReceiptAdvice-1.0.xsd | ./build.xml | ./docs | | | ./index.html ) | ./output.html ) Sample-specific documentation | ./xjb.html ) | ./src ) Application source code | | | ./samples/ubl/report ) Application package | | | ./PrintOrder.java ) Order printing | | ) application | | | ./facade ) Code implementing the | | ) facade design pattern | | | ./AddressFacade.java | ./OrderFacade.java | ./OrderLineTypeFacade.java | ./ubl.xjb ) Binding customizations
Running the project creates the directories gen-src
and classes
.
) Java bindings created by processing ./gen-src ) UBL schema with xjc using custom- | | ) izations in ubl.xjb. | | | ./org/oasis/ubl/codelist/acknowledgementresponse | ./org/oasis/ubl/codelist/allowancechargereason | ./org/oasis/ubl/codelist/channel | ./org/oasis/ubl/codelist/chip | ./org/oasis/ubl/codelist/countryidentification | ./org/oasis/ubl/codelist/currency | ./org/oasis/ubl/codelist/documentstatus | ./org/oasis/ubl/codelist/latitudedirection | ./org/oasis/ubl/codelist/linestatus | ./org/oasis/ubl/codelist/longitudedirection | ./org/oasis/ubl/codelist/operator | ./org/oasis/ubl/codelist/paymentmeans | ./org/oasis/ubl/codelist/substitutionstatus | ./org/oasis/ubl/commonaggregatecomponents | ./org/oasis/ubl/commonbasiccomponents | ./org/oasis/ubl/corecomponentparameters | ./org/oasis/ubl/corecomponenttypes | ./org/oasis/ubl/despatchadvice | ./org/oasis/ubl/invoice | ./org/oasis/ubl/order | ./org/oasis/ubl/ordercancellation | ./org/oasis/ubl/orderchange | ./org/oasis/ubl/orderresponse | ./org/oasis/ubl/orderresponsesimple | ./org/oasis/ubl/receiptadvice | ./org/oasis/ubl/specializeddatatypes | ./org/oasis/ubl/unspecializeddatatypes | ./classes ) Packages for the compiled bindings | ) and application code. | ./org/oasis/ubl/codelist/acknowledgementresponse ./org/oasis/ubl/codelist/allowancechargereason ./org/oasis/ubl/codelist/channel ./org/oasis/ubl/codelist/chip ./org/oasis/ubl/codelist/countryidentification ./org/oasis/ubl/codelist/currency ./org/oasis/ubl/codelist/documentstatus ./org/oasis/ubl/codelist/latitudedirection ./org/oasis/ubl/codelist/linestatus ./org/oasis/ubl/codelist/longitudedirection ./org/oasis/ubl/codelist/operator ./org/oasis/ubl/codelist/paymentmeans ./org/oasis/ubl/codelist/substitutionstatus ./org/oasis/ubl/commonaggregatecomponents ./org/oasis/ubl/commonbasiccomponents ./org/oasis/ubl/corecomponentparameters ./org/oasis/ubl/corecomponenttypes ./org/oasis/ubl/despatchadvice ./org/oasis/ubl/invoice ./org/oasis/ubl/order ./org/oasis/ubl/ordercancellation ./org/oasis/ubl/orderchange ./org/oasis/ubl/orderresponse ./org/oasis/ubl/orderresponsesimple ./org/oasis/ubl/receiptadvice ./org/oasis/ubl/specializeddatatypes ./org/oasis/ubl/unspecializeddatatypes ./samples/ubl/report ./samples/ubl/report/facade
If this is the first time you've run the sample, you'll see output similar to this. Here's what's happening in each step.
xjc
)
The schema are in the cd-UBL-1.0/xsd
directory. Ant places the
output in the gen-src
directory.
Binding customizations get applied as part of the schema compilation. Their main purpose is to package the code more logically than if package names were derived from the schema namespaces. These customizations are controlled by this external binding file.
compile
)
Ant places the output in the classes
directory.
run
)To create the Javadoc on, e.g., Unix:
$ $JWSDP_HOME/apache-ant/bin/ant
javadoc
Ant places the output in docs/api
.
PrintOrder
unmarshals a UBL order instance, does some
simple calculations, and prints a report to the screen.
PrintOrder
is in the samples.ubl.report
package. It imports classes having the following functions.
import samples.ubl.report.facade.OrderFacade; import samples.ubl.report.facade.OrderLineTypeFacade; import samples.ubl.report.facade.AddressFacade;
import java.io.FileInputStream; import java.io.IOException;
import java.text.NumberFormat;
import java.util.List;
import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller;
import org.oasis.ubl.order.Order;
PrintOrder
's main
method:
Unmarshaller
:
JAXBContext jc = JAXBContext.newInstance("org.oasis.ubl.order:" + "org.oasis.ubl.commonaggregatetypes"); Unmarshaller u = jc.createUnmarshaller();
Order order = (Order) u.unmarshal(new FileInputStream("cd-UBL-1.0/xml/office/" + "UBL-Order-1.0-Office-Example.xml"));
OrderFacade of = new OrderFacade(order); printLetterHead(of); printDate(of); printBuyer(of); printLineItems(of);
The private methods in PrintOrder
use the facade
objects to print the data as Strings
. For example:
private static void printLetterHead(OrderFacade order) { AddressFacade addr = order.getSellerAddress(); System.out.println(" " + order.getSellerName() + "\n " + addr.getStreet() + "\n " + addr.getCity() + ", " + addr.getState() + " " + addr.getZip()); }
The facade design pattern provides a simpler, higher-level interface. Typically, that's done to isolate an application from the complexity of the underlying subsystems. Here, our principle motivation is to isolate our application from changes to an evolving schema. Since we just wanted to print a simple report, our facades are read-only.
A look at printBuyer()
in PrintOrder
shows that getting the name of the buyer contact (a person,
usually) is just a matter of calling OrderFacade
's
getBuyerContact()
method:
private static void printBuyer(OrderFacade order) {
AddressFacade addr = order.getBuyerAddress();
System.out.println("\nSold To: "
+ order.getBuyerContact()
+ "\n c/o "
+ order.getBuyerName()
+ "\n "
+ addr.getStreet()
+ "\n "
+ addr.getCity()
+ ", "
+ addr.getState()
+ " "
+ addr.getZip());
}
getBuyerContact()
insulates our application from
potential changes in the schema.
In this snippet,public String getBuyerContact() { BuyerPartyType party = order.getBuyerParty(); return ((Name) party.getParty().getPartyName().getName().get(0)).getValue(); }
order
is a reference to org.oasis.ubl.order.Order
, which is
bound to
in<element name="Order" type="{urn:oasis:names:tc:ubl:Order:1:0}OrderType"/>
UBL-Order-1.0.xsd
. If that binding were to change,
for example, such that order.getBuyerParty()
returned,
let's say, PartyType
, we could make this one-line
change to getBuyerContact()
without affecting
PrintOrder
:
This pattern characterizes the other methods inPartyType party = order.getBuyerParty();
OrderFacade
and the methods in
OrderLineTypeFacade
and AddressFacade
.
For more information about using JAXB, refer to the Java Web Services Tutorial. For more information about UBL, visit OASIS' Universal Business Language Technical Committee site.