Thursday 8 March 2012

JAVAEE5-JAXB solution examples2

The Java(TM) Web Services Tutorial at http://java.sun.com/webservices/docs/1.4/tutorial/doc/JAXBUsing.html has a few JAXB examples some of which still be made to work. These examples are similar to JAVAEE5-JAXB examples. I will provide the working solution for one of these examples which can also be used to make the other examples at JAVAEE5 tutorial’s examples section.

The main deficiency in these examples is; po.xml and po.xsd is provided instead of the primer.po package. You have to create this package with xjc from po.xml and po.xsd.

C:\Users\ars\Desktop\nbJAXB\modify-marshalARS>xjc po.xsd
parsing a schema...
compiling a schema...
generated\Items.java
generated\ObjectFactory.java
generated\PurchaseOrderType.java
generated\USAddress.java

C:\Users\ars\Desktop\nbJAXB\modify-marshalARS>This command creates a generated dir in the same location as po.xml. You can copy its content to the primer.po package. You may also use the parameters of the xjc command to do this directly.

The directory structure looks like this:




The NetBeans project directory looks like this:




createMarshall.java
package create.marshalars;

//1.The <JWSDP_HOME>/jaxb/samples/create-marshal/
//Main.java class declares imports for four standard Java classes plus three
//JAXB binding framework classes and the primer.po package:
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Calendar;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.datatype.XMLGregorianCalendar;
import primer.po.*;

public class CreateMarshal {

public static void main(String[] args) {
try {
// 1.A JAXBContext instance is created for handling classes generated in primer.po.
JAXBContext jc = JAXBContext.newInstance("primer.po");

//1.The ObjectFactory class is used to instantiate a new empty PurchaseOrder object.
// creating the ObjectFactory
ObjectFactory objFactory = new ObjectFactory();

// create an empty PurchaseOrder
PurchaseOrderType po = objFactory.createPurchaseOrderType();

//1.Per the constraints in the po.xsd schema, the PurchaseOrder object requires a value for the orderDate attribute. To satisfy this constraint, the orderDate is set using the standard Calendar.getInstance() method from java.util.Calendar.
po.setOrderDate(Calendar.getInstance());

//1.The ObjectFactory is used to instantiate new empty USAddress objects, and the required attributes are set.
USAddress shipTo = createUSAddress(objFactory, "Alice Smith",
"123 Maple Street",
"Cambridge",
"MA",
"12345");
po.setShipTo(shipTo);

USAddress billTo = createUSAddress(objFactory, "Robert Smith",
"8 Oak Avenue",
"Cambridge",
"MA",
"12345");
po.setBillTo(billTo);

//1.The ObjectFactory class is used to instantiate a new empty Items object.
Items items = objFactory.createItems();

//1.A get method is used to get a reference to the ItemType list.
List itemList = items.getItem();

//1.ItemType objects are created and added to the Items list.
itemList.add(createItemType(
objFactory,
"Nosferatu - Special Edition (1929)",
new BigInteger("5"),
new BigDecimal("19.99"),
null,
null,
"242-NO"));
itemList.add(createItemType(objFactory, "The Mummy (1959)",
new BigInteger("3"),
new BigDecimal("19.98"),
null,
null,
"242-MU"));
itemList.add(createItemType(objFactory,
"Godzilla and Mothra: Battle for Earth/Godzilla vs. King Ghidora",
new BigInteger("3"),
new BigDecimal("27.95"),
null,
null,
"242-GZ"));

//1.The items object now contains a list of ItemType objects and can be added to the po object.
po.setItems(items);

//1.A Marshaller instance is created, and the updated XML content is marshalled to system.out. The setProperty API is used to specify output encoding; in this case formatted (human readable) XML format.
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(po, System.out);
//1.Basic error handling is implemented.
} catch (JAXBException je) {
je.printStackTrace();
}
}
//1.An empty USAddress object is created and its properties set to comply with the schema constraints.
public static USAddress createUSAddress(
ObjectFactory objFactory,
String name,
String street,
String city,
String state,
String zip)
throws JAXBException {

// create an empty USAddress objects
USAddress address = objFactory.createUSAddress();

// set properties on it
address.setName(name);
address.setStreet(street);
address.setCity(city);
address.setState(state);
address.setZip(new BigDecimal(zip));

// return it
return address;
}

//1.Similar to the previous step, an empty ItemType object is created and its properties set to comply with the schema constraints.
public static Items.Item createItemType(ObjectFactory objFactory,
String productName,
BigInteger quantity,
BigDecimal price,
String comment,
Calendar shipDate,
String partNum)
throws JAXBException {

// create an empty ItemType object
Items.Item itemType =
objFactory.createItemsItem();

// set properties on it
itemType.setProductName(productName);
itemType.setQuantity(quantity);
itemType.setUSPrice(price);
itemType.setComment(comment);
itemType.setShipDate(shipDate);
itemType.setPartNum(partNum);

// return it
return itemType;
}
}

Primer.po/Items.java
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.03.06 at 05:03:34 PM EET
//


package primer.po;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.datatype.XMLGregorianCalendar;


/**
* <p>Java class for Items complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="Items">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="item" maxOccurs="unbounded">
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="productName" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="quantity">
* <simpleType>
* <restriction base="{http://www.w3.org/2001/XMLSchema}positiveInteger">
* <maxExclusive value="100"/>
* </restriction>
* </simpleType>
* </element>
* <element name="USPrice" type="{http://www.w3.org/2001/XMLSchema}decimal"/>
* <element ref="{}comment" minOccurs="0"/>
* <element name="shipDate" type="{http://www.w3.org/2001/XMLSchema}date" minOccurs="0"/>
* </sequence>
* <attribute name="partNum" use="required" type="{}SKU" />
* </restriction>
* </complexContent>
* </complexType>
* </element>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Items", propOrder = {
"item"
})
public class Items {

@XmlElement(required = true)
protected List<Items.Item> item;

/**
* Gets the value of the item property.
*
* <p>
* This accessor method returns a reference to the live list,
* not a snapshot. Therefore any modification you make to the
* returned list will be present inside the JAXB object.
* This is why there is not a <CODE>set</CODE> method for the item property.
*
* <p>
* For example, to add a new item, do as follows:
* <pre>
* getItem().add(newItem);
* </pre>
*
*
* <p>
* Objects of the following type(s) are allowed in the list
* {@link Items.Item }
*
*
*/
public List<Items.Item> getItem() {
if (item == null) {
item = new ArrayList<Items.Item>();
}
return this.item;
}


/**
* <p>Java class for anonymous complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType>
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="productName" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="quantity">
* <simpleType>
* <restriction base="{http://www.w3.org/2001/XMLSchema}positiveInteger">
* <maxExclusive value="100"/>
* </restriction>
* </simpleType>
* </element>
* <element name="USPrice" type="{http://www.w3.org/2001/XMLSchema}decimal"/>
* <element ref="{}comment" minOccurs="0"/>
* <element name="shipDate" type="{http://www.w3.org/2001/XMLSchema}date" minOccurs="0"/>
* </sequence>
* <attribute name="partNum" use="required" type="{}SKU" />
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"productName",
"quantity",
"usPrice",
"comment",
"shipDate"
})
public static class Item {

@XmlElement(required = true)
protected String productName;
protected BigInteger quantity;
@XmlElement(name = "USPrice", required = true)
protected BigDecimal usPrice;
protected String comment;
@XmlSchemaType(name = "date")
protected Calendar shipDate;
@XmlAttribute(required = true)
protected String partNum;

/**
* Gets the value of the productName property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getProductName() {
return productName;
}

/**
* Sets the value of the productName property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setProductName(String value) {
this.productName = value;
}

/**
* Gets the value of the quantity property.
*
*/
public BigInteger getQuantity() {
return quantity;
}

/**
* Sets the value of the quantity property.
*
*/
public void setQuantity(BigInteger value) {
this.quantity = value;
}

/**
* Gets the value of the usPrice property.
*
* @return
* possible object is
* {@link BigDecimal }
*
*/
public BigDecimal getUSPrice() {
return usPrice;
}

/**
* Sets the value of the usPrice property.
*
* @param value
* allowed object is
* {@link BigDecimal }
*
*/
public void setUSPrice(BigDecimal value) {
this.usPrice = value;
}

/**
* Gets the value of the comment property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getComment() {
return comment;
}

/**
* Sets the value of the comment property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setComment(String value) {
this.comment = value;
}

/**
* Gets the value of the shipDate property.
*
* @return
* possible object is
* {@link XMLGregorianCalendar }
*
*/
public Calendar getShipDate() {
return shipDate;
}

/**
* Sets the value of the shipDate property.
*
* @param value
* allowed object is
* {@link XMLGregorianCalendar }
*
*/
public void setShipDate(Calendar value) {
this.shipDate = value;
}

/**
* Gets the value of the partNum property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getPartNum() {
return partNum;
}

/**
* Sets the value of the partNum property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setPartNum(String value) {
this.partNum = value;
}

}

}

Primer.po/ObjectFactory.java
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.03.06 at 05:03:34 PM EET
//


package primer.po;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;


/**
* This object contains factory methods for each
* Java content interface and Java element interface
* generated in the generated package.
* <p>An ObjectFactory allows you to programatically
* construct new instances of the Java representation
* for XML content. The Java representation of XML
* content can consist of schema derived interfaces
* and classes representing the binding of schema
* type definitions, element declarations and model
* groups. Factory methods for each of these are
* provided in this class.
*
*/
@XmlRegistry
public class ObjectFactory {

private final static QName _PurchaseOrder_QNAME = new QName("", "purchaseOrder");
private final static QName _Comment_QNAME = new QName("", "comment");

/**
* Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: generated
*
*/
public ObjectFactory() {
}

/**
* Create an instance of {@link Items.Item }
*
*/
public Items.Item createItemsItem() {
return new Items.Item();
}

/**
* Create an instance of {@link PurchaseOrderType }
*
*/
public PurchaseOrderType createPurchaseOrderType() {
return new PurchaseOrderType();
}

/**
* Create an instance of {@link Items }
*
*/
public Items createItems() {
return new Items();
}

/**
* Create an instance of {@link USAddress }
*
*/
public USAddress createUSAddress() {
return new USAddress();
}

/**
* Create an instance of {@link JAXBElement }{@code <}{@link PurchaseOrderType }{@code >}}
*
*/
@XmlElementDecl(namespace = "", name = "purchaseOrder")
public JAXBElement<PurchaseOrderType> createPurchaseOrder(PurchaseOrderType value) {
return new JAXBElement<PurchaseOrderType>(_PurchaseOrder_QNAME, PurchaseOrderType.class, null, value);
}

/**
* Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}}
*
*/
@XmlElementDecl(namespace = "", name = "comment")
public JAXBElement<String> createComment(String value) {
return new JAXBElement<String>(_Comment_QNAME, String.class, null, value);
}

}

Primer.po/PurchaseOrderType.java
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.03.06 at 05:03:34 PM EET
//


package primer.po;

import java.util.Calendar;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.datatype.XMLGregorianCalendar;


/**
* <p>Java class for PurchaseOrderType complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="PurchaseOrderType">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="shipTo" type="{}USAddress"/>
* <element name="billTo" type="{}USAddress"/>
* <element ref="{}comment" minOccurs="0"/>
* <element name="items" type="{}Items"/>
* </sequence>
* <attribute name="orderDate" type="{http://www.w3.org/2001/XMLSchema}date" />
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "PurchaseOrderType", propOrder = {
"shipTo",
"billTo",
"comment",
"items"
})
public class PurchaseOrderType {

@XmlElement(required = true)
protected USAddress shipTo;
@XmlElement(required = true)
protected USAddress billTo;
protected String comment;
@XmlElement(required = true)
protected Items items;
@XmlAttribute
@XmlSchemaType(name = "date")
protected Calendar orderDate;

/**
* Gets the value of the shipTo property.
*
* @return
* possible object is
* {@link USAddress }
*
*/
public USAddress getShipTo() {
return shipTo;
}

/**
* Sets the value of the shipTo property.
*
* @param value
* allowed object is
* {@link USAddress }
*
*/
public void setShipTo(USAddress value) {
this.shipTo = value;
}

/**
* Gets the value of the billTo property.
*
* @return
* possible object is
* {@link USAddress }
*
*/
public USAddress getBillTo() {
return billTo;
}

/**
* Sets the value of the billTo property.
*
* @param value
* allowed object is
* {@link USAddress }
*
*/
public void setBillTo(USAddress value) {
this.billTo = value;
}

/**
* Gets the value of the comment property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getComment() {
return comment;
}

/**
* Sets the value of the comment property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setComment(String value) {
this.comment = value;
}

/**
* Gets the value of the items property.
*
* @return
* possible object is
* {@link Items }
*
*/
public Items getItems() {
return items;
}

/**
* Sets the value of the items property.
*
* @param value
* allowed object is
* {@link Items }
*
*/
public void setItems(Items value) {
this.items = value;
}

/**
* Gets the value of the orderDate property.
*
* @return
* possible object is
* {@link XMLGregorianCalendar }
*
*/
public Calendar getOrderDate() {
return orderDate;
}

/**
* Sets the value of the orderDate property.
*
* @param value
* allowed object is
* {@link XMLGregorianCalendar }
*
*/
public void setOrderDate(Calendar value) {
this.orderDate = value;
}

}

Primer.po/USAddress.java
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 in JDK 6
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2012.03.06 at 05:03:34 PM EET
//


package primer.po;

import java.math.BigDecimal;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;


/**
* <p>Java class for USAddress complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="USAddress">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="name" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="street" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="city" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="state" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="zip" type="{http://www.w3.org/2001/XMLSchema}decimal"/>
* </sequence>
* <attribute name="country" type="{http://www.w3.org/2001/XMLSchema}NMTOKEN" fixed="US" />
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "USAddress", propOrder = {
"name",
"street",
"city",
"state",
"zip"
})
public class USAddress {

@XmlElement(required = true)
protected String name;
@XmlElement(required = true)
protected String street;
@XmlElement(required = true)
protected String city;
@XmlElement(required = true)
protected String state;
@XmlElement(required = true)
protected BigDecimal zip;
@XmlAttribute
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
@XmlSchemaType(name = "NMTOKEN")
protected String country;

/**
* Gets the value of the name property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getName() {
return name;
}

/**
* Sets the value of the name property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setName(String value) {
this.name = value;
}

/**
* Gets the value of the street property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getStreet() {
return street;
}

/**
* Sets the value of the street property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setStreet(String value) {
this.street = value;
}

/**
* Gets the value of the city property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getCity() {
return city;
}

/**
* Sets the value of the city property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setCity(String value) {
this.city = value;
}

/**
* Gets the value of the state property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getState() {
return state;
}

/**
* Sets the value of the state property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setState(String value) {
this.state = value;
}

/**
* Gets the value of the zip property.
*
* @return
* possible object is
* {@link BigDecimal }
*
*/
public BigDecimal getZip() {
return zip;
}

/**
* Sets the value of the zip property.
*
* @param value
* allowed object is
* {@link BigDecimal }
*
*/
public void setZip(BigDecimal value) {
this.zip = value;
}

/**
* Gets the value of the country property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getCountry() {
if (country == null) {
return "US";
} else {
return country;
}
}

/**
* Sets the value of the country property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setCountry(String value) {
this.country = value;
}

}

Once you create the primer.po package using the xjc command you can use the primer.po in almost all the JAXB examples of JAVAEE5. One problem you may encounter though it may require a root element annotation.

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "PurchaseOrderType", propOrder = {
"shipTo",
"billTo",
"comment",
"items"
})
public class PurchaseOrderType {

A better example is given by JAVAEE5 in the j2s-xml-rootElement example:
@XmlRootElement(name = "purchaseOrder")
@XmlType(name = "PurchaseOrderType")
public class PurchaseOrderType {
public CreditCardVendor creditCardVendor;
public USAddress billTo;
public USAddress shipTo;

Do not forget to add:
import javax.xml.bind.annotation.XmlRootElement;

Please feel free to contact me for the working copies of the other examples by e-mail at arsaral(at) yahoo.com

Kind regards.

Ali R+ SARAL
Note. My response will be free of charge and within the same day.