/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.test.xml;
import java.io.StringReader;
import java.io.StringWriter;
import org.jboss.xb.binding.MappingObjectModelProvider;
import org.jboss.xb.binding.Unmarshaller;
import org.jboss.xb.binding.UnmarshallerFactory;
import org.jboss.xb.binding.XercesXsMarshaller;
import org.jboss.xb.binding.Constants;
import org.jboss.xb.binding.sunday.unmarshalling.LSInputAdaptor;
import org.jboss.xb.binding.sunday.unmarshalling.SchemaBinding;
import org.jboss.xb.binding.sunday.unmarshalling.SchemaBindingResolver;
import org.jboss.xb.binding.sunday.unmarshalling.XsdBinder;
import org.jboss.xb.binding.sunday.marshalling.MarshallerImpl;
import org.w3c.dom.ls.LSInput;
/**
* @author <a href="mailto:alex@jboss.org">Alexey Loubyansky</a>
* @version <tt>$Revision: 45337 $</tt>
*/
public class XsiTypeUnitTestCase
extends AbstractJBossXBTest
{
private static final String PO_NS = "http://www.example.com/IPO";
private static final String ADDRESS_XSD =
"<schema targetNamespace='" + PO_NS + "'" +
" xmlns='http://www.w3.org/2001/XMLSchema'" +
" xmlns:jbxb='" + Constants.NS_JBXB + "'" +
" xmlns:ipo='" + PO_NS + "'>" +
" <complexType name='Address'>" +
" <sequence>" +
" <element name='name' type='string'/>" +
" <element name='street' type='string'/>" +
" <element name='city' type='string'/>" +
" </sequence>" +
" </complexType>" +
" <complexType name='USAddress'>" +
" <annotation>" +
" <appinfo>" +
" <jbxb:class impl='" + USAddress.class.getName() + "'/>" +
" </appinfo>" +
" </annotation>" +
" <complexContent>" +
" <extension base='ipo:Address'>" +
" <sequence>" +
" <element name='state' type='string'/>" +
" <element name='zip' type='string'/>" +
" </sequence>" +
" </extension>" +
" </complexContent>" +
" </complexType>" +
" <complexType name='UKAddress'>" +
" <annotation>" +
" <appinfo>" +
" <jbxb:class impl='" + UKAddress.class.getName() + "'/>" +
" </appinfo>" +
" </annotation>" +
" <complexContent>" +
" <extension base='ipo:Address'>" +
" <sequence>" +
" <element name='postcode' type='string'/>" +
" </sequence>" +
" <attribute name='exportCode' type='string' fixed='1'/>" +
" </extension>" +
" </complexContent>" +
" </complexType>" +
"</schema>";
private static final String PO_XSD =
"<schema targetNamespace='" + PO_NS + "'" +
" xmlns='http://www.w3.org/2001/XMLSchema'" +
" xmlns:jbxb='" + Constants.NS_JBXB + "'" +
" xmlns:ipo='" + PO_NS + "'>" +
" <include schemaLocation='http://www.example.com/schemas/address.xsd'/>" +
" <complexType name='PurchaseOrderType'>" +
" <annotation>" +
" <appinfo>" +
" <jbxb:class impl='" + PurchaseOrder.class.getName() + "'/>" +
" </appinfo>" +
" </annotation>" +
" <sequence>" +
" <element name='shipTo' type='ipo:Address'/>" +
" <element name='billTo' type='ipo:Address'/>" +
" </sequence>" +
" </complexType>" +
" <element name='purchaseOrder' type='ipo:PurchaseOrderType'/>" +
"</schema>";
private static final String PO_XML =
"<ipo:purchaseOrder" +
" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" +
" xmlns:ipo='" + PO_NS + "'>" +
" <shipTo exportCode='1' xsi:type='ipo:UKAddress'>" +
" <name>Helen Zoe</name>" +
" <street>47 Eden Street</street>" +
" <city>Cambridge</city>" +
" <postcode>CB1 1JR</postcode>" +
" </shipTo>" +
" <billTo xsi:type='ipo:USAddress'>" +
" <name>Robert Smith</name>" +
" <street>8 Oak Avenue</street>" +
" <city>Old Town</city>" +
" <state>PA</state>" +
" <zip>95819</zip>" +
" </billTo>" +
"</ipo:purchaseOrder>";
private static final String COLLECTION_XSD =
"<schema targetNamespace='" + PO_NS + "'" +
" xmlns='http://www.w3.org/2001/XMLSchema'" +
" xmlns:jbxb='" + Constants.NS_JBXB + "'" +
" xmlns:ipo='" + PO_NS + "'>" +
" <include schemaLocation='http://www.example.com/schemas/address.xsd'/>" +
" <complexType name='AddressCollection'>" +
" <annotation>" +
" <appinfo>" +
" <jbxb:class impl='" + PurchaseOrder.class.getName() + "'/>" +
" </appinfo>" +
" </annotation>" +
" <sequence>" +
" <element name='address' type='ipo:Address' maxOccurs='unbounded'/>" +
" </sequence>" +
" </complexType>" +
" <element name='addresses' type='ipo:AddressCollection'/>" +
"</schema>";
private static final String COLLECTION_XML =
"<ipo:addresses" +
" xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'" +
" xmlns:ipo='" + PO_NS + "'>" +
" <address xsi:type='ipo:USAddress'>" +
" <name>Robert Smith</name>" +
" <street>8 Oak Avenue</street>" +
" <city>Old Town</city>" +
" <state>PA</state>" +
" <zip>95819</zip>" +
" </address>" +
" <address exportCode='1' xsi:type='ipo:UKAddress'>" +
" <name>Helen Zoe</name>" +
" <street>47 Eden Street</street>" +
" <city>Cambridge</city>" +
" <postcode>CB1 1JR</postcode>" +
" </address>" +
"</ipo:addresses>";
private static final SchemaBindingResolver SCHEMA_RESOLVER = new SchemaBindingResolver()
{
public String getBaseURI()
{
throw new UnsupportedOperationException("getBaseURI is not implemented.");
}
public void setBaseURI(String baseURI)
{
throw new UnsupportedOperationException("setBaseURI is not implemented.");
}
public SchemaBinding resolve(String nsUri, String baseURI, String schemaLocation)
{
throw new UnsupportedOperationException("resolve is not implemented.");
}
public LSInput resolveAsLSInput(String nsUri, String baseUri, String schemaLocation)
{
if(schemaLocation.endsWith("address.xsd"))
{
return new LSInputAdaptor(new StringReader(ADDRESS_XSD), null);
}
return null;
}
};
public XsiTypeUnitTestCase(String name)
{
super(name);
}
protected void configureLogging()
{
}
public void testUnmarshalling() throws Exception
{
SchemaBinding schema = XsdBinder.bind(new StringReader(PO_XSD), null, SCHEMA_RESOLVER);
Unmarshaller unmarshaller = UnmarshallerFactory.newInstance().newUnmarshaller();
Object o = unmarshaller.unmarshal(new StringReader(PO_XML), schema);
assertEquals(PurchaseOrder.INSTANCE, o);
}
public void testMarshallingXerces() throws Exception
{
XercesXsMarshaller marshaller = new XercesXsMarshaller();
marshaller.setSchemaResolver(SCHEMA_RESOLVER);
marshaller.mapClassToXsiType(UKAddress.class, PO_NS, "UKAddress");
marshaller.mapClassToXsiType(USAddress.class, PO_NS, "USAddress");
MappingObjectModelProvider provider = new MappingObjectModelProvider();
StringWriter writer = new StringWriter();
marshaller.marshal(new StringReader(PO_XSD), provider, PurchaseOrder.INSTANCE, writer);
assertXmlEqual(PO_XML, writer.getBuffer().toString());
}
public void testMarshallingSunday() throws Exception
{
SchemaBinding schema = XsdBinder.bind(new StringReader(PO_XSD), null, SCHEMA_RESOLVER);
MarshallerImpl marshaller = new MarshallerImpl();
marshaller.setSchemaResolver(SCHEMA_RESOLVER);
marshaller.mapClassToXsiType(UKAddress.class, PO_NS, "UKAddress");
marshaller.mapClassToXsiType(USAddress.class, PO_NS, "USAddress");
StringWriter writer = new StringWriter();
marshaller.marshal(schema, null, PurchaseOrder.INSTANCE, writer);
assertXmlEqual(PO_XML, writer.getBuffer().toString());
}
public void testUnmarshalCollection() throws Exception
{
SchemaBinding schema = XsdBinder.bind(new StringReader(COLLECTION_XSD), null, SCHEMA_RESOLVER);
Unmarshaller unmarshaller = UnmarshallerFactory.newInstance().newUnmarshaller();
Object o = unmarshaller.unmarshal(new StringReader(COLLECTION_XML), schema);
assertNotNull(o);
assertTrue(o instanceof PurchaseOrder);
PurchaseOrder po = (PurchaseOrder) o;
assertNotNull(po.address);
assertEquals(2, po.address.length);
if(po.address[0] instanceof UKAddress)
{
assertEquals(PurchaseOrder.INSTANCE.shipTo, po.address[0]);
assertEquals(PurchaseOrder.INSTANCE.billTo, po.address[1]);
}
else
{
assertEquals(PurchaseOrder.INSTANCE.shipTo, po.address[1]);
assertEquals(PurchaseOrder.INSTANCE.billTo, po.address[0]);
}
}
public void testMarshalCollectionSunday() throws Exception
{
SchemaBinding schema = XsdBinder.bind(new StringReader(COLLECTION_XSD), null, SCHEMA_RESOLVER);
MarshallerImpl marshaller = new MarshallerImpl();
marshaller.setSchemaResolver(SCHEMA_RESOLVER);
marshaller.mapClassToXsiType(UKAddress.class, PO_NS, "UKAddress");
marshaller.mapClassToXsiType(USAddress.class, PO_NS, "USAddress");
StringWriter writer = new StringWriter();
PurchaseOrder po = new PurchaseOrder();
po.address = new Address[2];
po.address[0] = PurchaseOrder.INSTANCE.billTo;
po.address[1] = PurchaseOrder.INSTANCE.shipTo;
marshaller.marshal(schema, null, po, writer);
assertXmlEqual(COLLECTION_XML, writer.getBuffer().toString());
}
// Inner
public static final class PurchaseOrder
{
public static final PurchaseOrder INSTANCE = new PurchaseOrder();
static
{
UKAddress ukAddr = new UKAddress();
ukAddr.name = "Helen Zoe";
ukAddr.street = "47 Eden Street";
ukAddr.city = "Cambridge";
ukAddr.postcode = "CB1 1JR";
ukAddr.exportCode = "1";
INSTANCE.shipTo = ukAddr;
USAddress usAddr = new USAddress();
usAddr.name = "Robert Smith";
usAddr.street = "8 Oak Avenue";
usAddr.city = "Old Town";
usAddr.state = "PA";
usAddr.zip = "95819";
INSTANCE.billTo = usAddr;
}
public Address shipTo;
public Address billTo;
public Address[] address; //for collection test
public String toString()
{
return "[shipTo=" + shipTo + ", billTo=" + billTo + "]";
}
public boolean equals(Object o)
{
if(this == o)
{
return true;
}
if(!(o instanceof PurchaseOrder))
{
return false;
}
final PurchaseOrder purchaseOrder = (PurchaseOrder)o;
if(billTo != null ? !billTo.equals(purchaseOrder.billTo) : purchaseOrder.billTo != null)
{
return false;
}
if(shipTo != null ? !shipTo.equals(purchaseOrder.shipTo) : purchaseOrder.shipTo != null)
{
return false;
}
return true;
}
public int hashCode()
{
int result;
result = (shipTo != null ? shipTo.hashCode() : 0);
result = 29 * result + (billTo != null ? billTo.hashCode() : 0);
return result;
}
}
public static class Address
{
public String name;
public String street;
public String city;
public String toString()
{
return "name=" + name + ", street=" + street + ", city=" + city;
}
public boolean equals(Object o)
{
if(this == o)
{
return true;
}
if(!(o instanceof Address))
{
return false;
}
final Address address = (Address)o;
if(city != null ? !city.equals(address.city) : address.city != null)
{
return false;
}
if(name != null ? !name.equals(address.name) : address.name != null)
{
return false;
}
if(street != null ? !street.equals(address.street) : address.street != null)
{
return false;
}
return true;
}
public int hashCode()
{
int result;
result = (name != null ? name.hashCode() : 0);
result = 29 * result + (street != null ? street.hashCode() : 0);
result = 29 * result + (city != null ? city.hashCode() : 0);
return result;
}
}
public static final class USAddress
extends Address
{
public String state;
public String zip;
public String toString()
{
return super.toString() + ", state=" + state + ", zip=" + zip;
}
public boolean equals(Object o)
{
if(this == o)
{
return true;
}
if(!(o instanceof USAddress))
{
return false;
}
if(!super.equals(o))
{
return false;
}
final USAddress usAddress = (USAddress)o;
if(state != null ? !state.equals(usAddress.state) : usAddress.state != null)
{
return false;
}
if(zip != null ? !zip.equals(usAddress.zip) : usAddress.zip != null)
{
return false;
}
return true;
}
public int hashCode()
{
int result = super.hashCode();
result = 29 * result + (state != null ? state.hashCode() : 0);
result = 29 * result + (zip != null ? zip.hashCode() : 0);
return result;
}
}
public static final class UKAddress
extends Address
{
public String postcode;
public String exportCode;
public String toString()
{
return super.toString() + ", postcode=" + postcode + ", exportCode=" + exportCode;
}
public boolean equals(Object o)
{
if(this == o)
{
return true;
}
if(!(o instanceof UKAddress))
{
return false;
}
if(!super.equals(o))
{
return false;
}
final UKAddress ukAddress = (UKAddress)o;
if(exportCode != null ? !exportCode.equals(ukAddress.exportCode) : ukAddress.exportCode != null)
{
return false;
}
if(postcode != null ? !postcode.equals(ukAddress.postcode) : ukAddress.postcode != null)
{
return false;
}
return true;
}
public int hashCode()
{
int result = super.hashCode();
result = 29 * result + (postcode != null ? postcode.hashCode() : 0);
result = 29 * result + (exportCode != null ? exportCode.hashCode() : 0);
return result;
}
}
}