I am using eclipse link(v2.5.1) Dynamic JAXB to convert XML to JSON and viceversa using a multiple schemas. While umarshalling the JSON to XML,I want to validate the JSON(against the XSD) and Dynamic Moxy is unable to validate the generated JSON and results in classcast exception.
emp.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:emp="Employee:2:0" targetNamespace="Employee:2:0"
elementFormDefault="unqualified" attributeFormDefault="unqualified"
version="2.0">
<xsd:element name="searchManager" type="emp:SearchManager" />
<xsd:complexType name="SearchManager">
<xsd:sequence>
<xsd:element name="CompanyName" type="xsd:string" />
<xsd:element name="objects" type="emp:Employee" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Employee">
<xsd:complexContent>
<xsd:extension base="emp:Organization">
<xsd:sequence>
<xsd:element name="EmpId" type="xsd:string" minOccurs="0" />
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="Projects">
<xsd:complexContent>
<xsd:extension base="emp:Organization"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:complexType name="Organization">
<xsd:annotation>
<xsd:documentation>Abstract base class </xsd:documentation>
</xsd:annotation>
</xsd:complexType>
</xsd:schema>
Manager.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="Manager:1:0" xmlns:emp="Employee:2:0"
xmlns:manager="Manager:1:0" xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="unqualified" attributeFormDefault="unqualified"
version="1.0">
<!-- schema imports -->
<xs:import namespace="Employee:2:0" schemaLocation="emp.xsd" />
<xs:complexType name="Manager">
<xs:annotation>
<xs:documentation>
Definition of class Employee
</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:extension base="emp:Employee">
<xs:sequence>
<xs:element name="teamSize" type="xsd:int" minOccurs="0" />
<xs:element name="project1" type="manager:Project1"
minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Project1">
<xs:complexContent>
<xs:extension base="manager:Developement">
<xs:sequence>
<xs:element name="type" type="xsd:int" minOccurs="0" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Developement">
<xs:annotation>
<xs:documentation>
Abstract base class for an Development
</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:extension base="emp:Projects"/>
</xs:complexContent>
</xs:complexType>
</xs:schema>
sample.xml
<emp:searchManager xmlns:emp="Employee:2:0"
xmlns:manager="Manager:1:0">
<CompanyName>Test</CompanyName>
<objects xmlns:ns2="Manager:1:0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:Manager">
<EmpId>123456</EmpId>
<teamSize>10</teamSize>
<project1>
<type>1</type>
</project1>
</objects>
</emp:searchManager>
The driver program to test is as follows
public class XMLToJSON {
/**
* @param args
*/
public static void main(String[] args) {
FileInputStream xsdInputStream;
try {
xsdInputStream = new FileInputStream("Manager.xsd");
DynamicJAXBContext jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(xsdInputStream, new MyEntityResolver(), null, null);
FileInputStream xmlInputStream = new FileInputStream("sample.xml");
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
JAXBElement<DynamicEntity> manager = (JAXBElement) unmarshaller.unmarshal(xmlInputStream);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//input xml to print
marshaller.marshal(manager, System.out);
Map namespaces = new HashMap();
namespaces.put("http://www.w3.org/2001/XMLSchema-instance", "xsi");
namespaces.put("Employee:2:0", "ns1");
namespaces.put("Manager:1:0", "ns2");
// XML to JSON
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
marshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, namespaces);
FileOutputStream jsonOutputStream = new FileOutputStream("sample.json");
marshaller.marshal(manager, jsonOutputStream);
marshaller.marshal(manager, System.out);
//JSON to XML
JAXBUnmarshaller jsonUnmarshaller = jaxbContext.createUnmarshaller();
jsonUnmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, "application/json");
jsonUnmarshaller.setProperty(UnmarshallerProperties.JSON_NAMESPACE_PREFIX_MAPPER, namespaces);
jsonUnmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, true);
jsonUnmarshaller.setProperty(UnmarshallerProperties.JSON_ATTRIBUTE_PREFIX, "@");
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File("Manager.xsd"));
jsonUnmarshaller.setSchema(schema);
StreamSource json = new StreamSource("sample.json");
JAXBElement<DynamicEntity> myroot = (JAXBElement) jsonUnmarshaller.unmarshal(json);
Marshaller m = jaxbContext.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
m.marshal(myroot, System.out);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (JAXBException e) {
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Generated Sample JSON
{
"ns1.searchManager" : {
"CompanyName" : "Test",
"objects" : [ {
"xsi.type" : "ns2.Manager",
"EmpId" : "123456",
"teamSize" : 10,
"project1" : [ {
"type" : 1
} ]
} ]
}
}
While unmarshalling the below exception was seen
Exception in thread "main" java.lang.ClassCastException: org.eclipse.persistence.internal.oxm.record.XMLReaderAdapter$ExtendedContentHandlerAdapter cannot be cast to org.eclipse.persistence.internal.oxm.record.UnmarshalRecord
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.isTextValue(JSONReader.java:454)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:350)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:244)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:430)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:299)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parseRoot(JSONReader.java:166)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:125)
at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:140)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:778)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:666)
at org.eclipse.persistence.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:593)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:287)
at XMLToJSON.main(XMLToJSON.java:74)
EDIT:Corrected the generated sample json
Question
The intention is to check whether JSON conforms to the XML schema. Does Dynamic JAXB support JSON Validation while unmarshalling? Is this a bug in Dynamic JAXB Moxy?