blob: d6e3cb019157f4d37d19252137a1fdde148a52d5 [file] [log] [blame]
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.jaxb;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Type;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBElement;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.SchemaOutputResolver;
import jakarta.xml.bind.Unmarshaller;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.eclipse.persistence.internal.oxm.record.XMLStreamReaderInputSource;
import org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.JAXBUnmarshaller;
import org.eclipse.persistence.jaxb.JAXBUnmarshallerHandler;
import org.eclipse.persistence.jaxb.MarshallerProperties;
import org.eclipse.persistence.jaxb.UnmarshallerProperties;
import org.eclipse.persistence.jaxb.compiler.CompilerHelper;
import org.eclipse.persistence.jaxb.xmlmodel.XmlBindings;
import org.eclipse.persistence.oxm.MediaType;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLRoot;
import org.eclipse.persistence.oxm.record.XMLStreamWriterRecord;
import org.eclipse.persistence.platform.xml.SAXDocumentBuilder;
import org.eclipse.persistence.platform.xml.XMLPlatformFactory;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.testing.oxm.mappings.XMLMappingTestCases;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSResourceResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
public abstract class JAXBTestCases extends XMLMappingTestCases {
public static final String ECLIPSELINK_OXM_XSD = "eclipselink_oxm_2_6.xsd";
protected JAXBContext jaxbContext;
protected Marshaller jaxbMarshaller;
protected Unmarshaller jaxbUnmarshaller;
protected Class[] classes;
protected Type[] types;
protected String contextPath;
protected ClassLoader classLoader;
protected Source bindingsFileXSDSource;
public JAXBTestCases(String name) throws Exception {
super(name);
}
@Override
public XMLContext getXMLContext(Project project) {
return new XMLContext(project, classLoader);
}
@Override
public void setUp() throws Exception {
setupParser();
setupControlDocs();
InputStream bindingsFileXSDInputStream = getClass().getClassLoader().getResourceAsStream(ECLIPSELINK_OXM_XSD);
if(bindingsFileXSDInputStream == null){
bindingsFileXSDInputStream = getClass().getClassLoader().getResourceAsStream("org/eclipse/persistence/jaxb/" + ECLIPSELINK_OXM_XSD);
}
if(bindingsFileXSDInputStream == null){
fail("ERROR LOADING " + ECLIPSELINK_OXM_XSD);
}
bindingsFileXSDSource = new StreamSource(bindingsFileXSDInputStream);
}
@Override
public void tearDown() {
super.tearDown();
jaxbContext = null;
jaxbMarshaller = null;
jaxbUnmarshaller = null;
classLoader = null;
bindingsFileXSDSource = null;
}
@Override
protected void setProject(Project project) {
this.project = project;
}
public void setClasses(Class[] newClasses) throws Exception {
classLoader = Thread.currentThread().getContextClassLoader();
jaxbContext = JAXBContextFactory.createContext(newClasses, getProperties(), classLoader);
classes = newClasses;
xmlContext = ((org.eclipse.persistence.jaxb.JAXBContext)jaxbContext).getXMLContext();
setProject(xmlContext.getSession(0).getProject());
jaxbMarshaller = jaxbContext.createMarshaller();
jaxbUnmarshaller = jaxbContext.createUnmarshaller();
}
public void setContextPath(String contextPath) throws Exception {
classLoader = Thread.currentThread().getContextClassLoader();
this.contextPath = contextPath;
Map props = getProperties();
if(props != null){
Map overrides = (Map) props.get(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY);
if(overrides != null){
Iterator valuesIter = overrides.values().iterator();
while(valuesIter.hasNext()){
Object next = valuesIter.next();
validateBindingsFileAgainstSchema(next);
}
}
}
jaxbContext = JAXBContextFactory.createContext(contextPath, classLoader, getProperties());
xmlContext = ((org.eclipse.persistence.jaxb.JAXBContext)jaxbContext).getXMLContext();
setProject(xmlContext.getSession(0).getProject());
jaxbMarshaller = jaxbContext.createMarshaller();
jaxbUnmarshaller = jaxbContext.createUnmarshaller();
}
public void setTypes(Type[] newTypes) throws Exception {
types = newTypes;
classLoader = Thread.currentThread().getContextClassLoader();
Map props = getProperties();
if(props != null){
Map overrides = (Map) props.get(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY);
if(overrides != null){
Iterator valuesIter = overrides.values().iterator();
while(valuesIter.hasNext()){
Object next = valuesIter.next();
validateBindingsFileAgainstSchema(next);
}
}
}
jaxbContext = JAXBContextFactory.createContext(newTypes, getProperties(), classLoader);
xmlContext = ((org.eclipse.persistence.jaxb.JAXBContext)jaxbContext).getXMLContext();
setProject(xmlContext.getSession(0).getProject());
jaxbMarshaller = jaxbContext.createMarshaller();
jaxbUnmarshaller = jaxbContext.createUnmarshaller();
}
protected Map getProperties() throws JAXBException{
return null;
}
private Map getPropertiesFromJSON() throws JAXBException{
Map props = new HashMap(getProperties());
if(props !=null){
Object bindingFilesObject = props.get(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY);
if(bindingFilesObject != null){
JAXBContext jaxbContext = CompilerHelper.getXmlBindingsModelContext();
//unmarshal XML
Unmarshaller u =jaxbContext.createUnmarshaller();
Marshaller jsonMarshaller = jaxbContext.createMarshaller();
//Marshal bindings to JSON (with no root)
jsonMarshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
jsonMarshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, false);
if(bindingFilesObject instanceof Map){
Map<String, Object> bindingFiles = (Map<String, Object>) bindingFilesObject;
Iterator<String> keyIter = bindingFiles.keySet().iterator();
while(keyIter.hasNext()){
String nextKey = keyIter.next();
Object nextBindings = bindingFiles.get(nextKey);;
if(nextBindings instanceof List){
List nextList = (List) bindingFiles.get(nextKey);
for(int i=0;i< nextList.size();i++){
Object o = nextList.get(i);
if(o instanceof Source){
Source nextSource = (Source)o;
if(nextSource instanceof StreamSource){
StreamSource ss= (StreamSource)nextSource;
StreamSource ss2= new StreamSource(ss.getInputStream());
Object unmarshalledFromXML = u.unmarshal(ss2);
StringWriter sw = new StringWriter();
StreamResult newResult = new StreamResult(sw);
jsonMarshaller.marshal(unmarshalledFromXML, newResult);
StreamSource newSource = new StreamSource(new StringReader(sw.toString()));
nextList.set(i, newSource);
}
}
}
}else if(nextBindings instanceof Source){
Object unmarshalledFromXML = u.unmarshal((Source)nextBindings);
StringWriter sw = new StringWriter();
StreamResult newResult = new StreamResult(sw);
jsonMarshaller.marshal(unmarshalledFromXML, newResult);
StreamSource newSource = new StreamSource(new StringReader(sw.toString()));
bindingFiles.put(nextKey, newSource);
}
}
}else if(bindingFilesObject instanceof List){
List bindingFilesList = (List) bindingFilesObject;
for(int i=0; i<bindingFilesList.size(); i++){
Object next = bindingFilesList.get(i);
Object unmarshalledFromXML = getXmlBindings(next);
StringWriter sw = new StringWriter();
StreamResult newResult = new StreamResult(sw);
jsonMarshaller.marshal(unmarshalledFromXML, newResult);
StreamSource newSource = new StreamSource(new StringReader(sw.toString()));
bindingFilesList.set(i, newSource);
}
props.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, bindingFilesList);
}else{
Object unmarshalledFromXML = getXmlBindings(bindingFilesObject);
StringWriter sw = new StringWriter();
StreamResult newResult = new StreamResult(sw);
jsonMarshaller.marshal(unmarshalledFromXML, newResult);
StreamSource newSource = new StreamSource(new StringReader(sw.toString()));
props.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, newSource);
}
}
}
return props;
}
private static XmlBindings getXmlBindings(Object metadata) {
XmlBindings xmlBindings = null;
Unmarshaller unmarshaller;
// only create the JAXBContext for our XmlModel once
JAXBContext jaxbContext = CompilerHelper.getXmlBindingsModelContext();
try {
unmarshaller = jaxbContext.createUnmarshaller();
if (metadata instanceof File) {
xmlBindings = (XmlBindings) unmarshaller.unmarshal((File) metadata);
} else if (metadata instanceof InputSource) {
xmlBindings = (XmlBindings) unmarshaller.unmarshal((InputSource) metadata);
} else if (metadata instanceof BufferedInputStream) {
xmlBindings = (XmlBindings) unmarshaller.unmarshal((BufferedInputStream) metadata);
} else if (metadata instanceof InputStream) {
xmlBindings = (XmlBindings) unmarshaller.unmarshal((InputStream) metadata);
} else if (metadata instanceof Node) {
xmlBindings = (XmlBindings) unmarshaller.unmarshal((Node) metadata);
} else if (metadata instanceof Reader) {
xmlBindings = (XmlBindings) unmarshaller.unmarshal((Reader) metadata);
} else if (metadata instanceof Source) {
xmlBindings = (XmlBindings) unmarshaller.unmarshal((Source) metadata);
} else if (metadata instanceof URL) {
xmlBindings = (XmlBindings) unmarshaller.unmarshal((URL) metadata);
} else if (metadata instanceof XMLEventReader) {
xmlBindings = (XmlBindings) unmarshaller.unmarshal((XMLEventReader) metadata);
} else if (metadata instanceof XMLStreamReader) {
xmlBindings = (XmlBindings) unmarshaller.unmarshal((XMLStreamReader) metadata);
} else if (metadata instanceof String) {
if(((String)metadata).length() == 0) {
throw org.eclipse.persistence.exceptions.JAXBException.unableToLoadMetadataFromLocation((String)metadata);
}
URL url = null;
try {
url = new URL((String)metadata);
} catch(MalformedURLException ex) {
url = Thread.currentThread().getContextClassLoader().getResource((String)metadata);
}
if(url != null) {
xmlBindings = (XmlBindings)unmarshaller.unmarshal(url);
} else {
//throw exception
throw org.eclipse.persistence.exceptions.JAXBException.unableToLoadMetadataFromLocation((String)metadata);
}
} else {
throw org.eclipse.persistence.exceptions.JAXBException.incorrectValueParameterTypeForOxmXmlKey();
}
} catch (JAXBException jaxbEx) {
throw org.eclipse.persistence.exceptions.JAXBException.couldNotUnmarshalMetadata(jaxbEx);
}
return xmlBindings;
}
public JAXBContext getJAXBContext() {
return jaxbContext;
}
public Marshaller getJAXBMarshaller() {
return jaxbMarshaller;
}
public Unmarshaller getJAXBUnmarshaller() {
return jaxbUnmarshaller;
}
public Class getUnmarshalClass(){
return null;
}
@Override
public void testXMLToObjectFromInputStream() throws Exception {
if(isUnmarshalTest()) {
InputStream instream = ClassLoader.getSystemResourceAsStream(resourceName);
jaxbUnmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, getXMLUnmarshalMediaType());
Object testObject = null;
if(getUnmarshalClass() != null){
testObject = jaxbUnmarshaller.unmarshal(new StreamSource(instream), getUnmarshalClass());
}else{
testObject = jaxbUnmarshaller.unmarshal(instream);
}
instream.close();
xmlToObjectTest(testObject);
if(getProperties() != null){
JAXBContext jaxbContextFromJSONBindings = createJaxbContextFromJSONBindings();
Unmarshaller jaxbUnmarshallerFromJSONBindings = jaxbContextFromJSONBindings.createUnmarshaller();
jaxbUnmarshallerFromJSONBindings.setAttachmentUnmarshaller(jaxbUnmarshaller.getAttachmentUnmarshaller());
jaxbUnmarshallerFromJSONBindings.setProperty(UnmarshallerProperties.OBJECT_GRAPH, jaxbUnmarshaller.getProperty(UnmarshallerProperties.OBJECT_GRAPH));
jaxbUnmarshallerFromJSONBindings.setProperty(UnmarshallerProperties.JSON_NAMESPACE_PREFIX_MAPPER, jaxbMarshaller.getProperty(UnmarshallerProperties.JSON_NAMESPACE_PREFIX_MAPPER));
Object testObject2 = null;
log("************test with JSON bindings*********");
InputStream instream2 = ClassLoader.getSystemResourceAsStream(resourceName);
if(getUnmarshalClass() != null){
testObject2 = jaxbUnmarshallerFromJSONBindings.unmarshal(new StreamSource(instream2), getUnmarshalClass());
}else{
testObject2 = jaxbUnmarshallerFromJSONBindings.unmarshal(instream2);
}
instream2.close();
xmlToObjectTest(testObject2);
}
}
}
protected JAXBContext createJaxbContextFromJSONBindings() throws JAXBException{
if(classes != null){
return JAXBContextFactory.createContext(classes, getPropertiesFromJSON(), classLoader);
}else if (types != null){
return JAXBContextFactory.createContext(types, getPropertiesFromJSON(), classLoader);
}else if(contextPath != null){
return JAXBContextFactory.createContext(contextPath, classLoader, getPropertiesFromJSON());
}
return null;
}
public MediaType getXMLUnmarshalMediaType(){
return MediaType.APPLICATION_XML;
}
public void testRoundTrip() throws Exception{
if(isUnmarshalTest()) {
jaxbUnmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, getXMLUnmarshalMediaType());
InputStream instream = null;
if(writeControlDocumentLocation !=null){
instream = ClassLoader.getSystemResourceAsStream(writeControlDocumentLocation);
}else{
instream = ClassLoader.getSystemResourceAsStream(resourceName);
}
jaxbUnmarshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/xml");
Object testObject = null;
if(getUnmarshalClass() != null){
testObject = jaxbUnmarshaller.unmarshal(new StreamSource(instream), getUnmarshalClass());
}else{
testObject = jaxbUnmarshaller.unmarshal(instream);
}
instream.close();
xmlToObjectTest(testObject);
objectToXMLStringWriter(testObject);
}
}
@Override
public void testObjectToOutputStream() throws Exception {
Object objectToWrite = getWriteControlObject();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
XMLDescriptor desc = null;
if (objectToWrite instanceof XMLRoot) {
desc = (XMLDescriptor)xmlContext.getSession(0).getProject().getDescriptor(((XMLRoot)objectToWrite).getObject().getClass());
} else {
desc = (XMLDescriptor)xmlContext.getSession(0).getProject().getDescriptor(objectToWrite.getClass());
}
int sizeBefore = getNamespaceResolverSize(desc);
jaxbMarshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/xml");
try {
jaxbMarshaller.marshal(objectToWrite, stream);
} catch(Exception e) {
assertMarshalException(e);
return;
}
if(expectsMarshalException){
fail("An exception should have occurred but didn't.");
return;
}
int sizeAfter = getNamespaceResolverSize(desc);
assertEquals(sizeBefore, sizeAfter);
InputStream is = new ByteArrayInputStream(stream.toByteArray());
Document testDocument = getTestDocument(is);
stream.close();
is.close();
objectToXMLDocumentTest(testDocument);
if(getProperties() != null){
log("************test with JSON bindings*********");
ByteArrayOutputStream stream2 = new ByteArrayOutputStream();
JAXBContext jaxbContextFromJSONBindings = createJaxbContextFromJSONBindings();
Marshaller jaxbMarshallerFromJSONBindings = jaxbContextFromJSONBindings.createMarshaller();
jaxbMarshallerFromJSONBindings.setAttachmentMarshaller(jaxbMarshaller.getAttachmentMarshaller());
jaxbMarshallerFromJSONBindings.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, jaxbMarshaller.getProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER));
jaxbMarshallerFromJSONBindings.setProperty(MarshallerProperties.OBJECT_GRAPH, jaxbMarshaller.getProperty(MarshallerProperties.OBJECT_GRAPH));
jaxbMarshallerFromJSONBindings.marshal(objectToWrite, stream2);
InputStream is2 = new ByteArrayInputStream(stream2.toByteArray());
Document testDocument2 = parser.parse(is2);
stream2.close();
is2.close();
objectToXMLDocumentTest(testDocument2);
}
}
@Override
public void testObjectToOutputStreamASCIIEncoding() throws Exception {
Object objectToWrite = getWriteControlObject();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
XMLDescriptor desc = null;
if (objectToWrite instanceof XMLRoot) {
desc = (XMLDescriptor)xmlContext.getSession(0).getProject().getDescriptor(((XMLRoot)objectToWrite).getObject().getClass());
} else {
desc = (XMLDescriptor)xmlContext.getSession(0).getProject().getDescriptor(objectToWrite.getClass());
}
jaxbMarshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/xml");
int sizeBefore = getNamespaceResolverSize(desc);
String originalEncoding = (String)jaxbMarshaller.getProperty(Marshaller.JAXB_ENCODING);
jaxbMarshaller.setProperty(Marshaller.JAXB_ENCODING, "US-ASCII");
try {
jaxbMarshaller.marshal(objectToWrite, stream);
} catch(Exception e) {
assertMarshalException(e);
return;
}
if(expectsMarshalException){
fail("An exception should have occurred but didn't.");
return;
}
jaxbMarshaller.setProperty(Marshaller.JAXB_ENCODING, originalEncoding);
int sizeAfter = getNamespaceResolverSize(desc);
assertEquals(sizeBefore, sizeAfter);
InputStream is = new ByteArrayInputStream(stream.toByteArray());
Document testDocument = getTestDocument(is);
stream.close();
is.close();
objectToXMLDocumentTest(testDocument);
}
public Document getTestDocument(InputStream is) throws Exception{
return parser.parse(is);
}
public Document getTestDocument(String s) throws Exception{
StringReader reader = new StringReader(s);
InputSource inputSource = new InputSource(reader);
Document doc = parser.parse(inputSource);
reader.close();
return doc;
}
@Override
public void testObjectToXMLStringWriter() throws Exception {
objectToXMLStringWriter(getWriteControlObject());
}
@Override
public void testValidatingMarshal() {
}
public void objectToXMLStringWriter(Object objectToWrite) throws Exception {
StringWriter writer = new StringWriter();
XMLDescriptor desc = null;
if (objectToWrite instanceof XMLRoot) {
desc = (XMLDescriptor)xmlContext.getSession(0).getProject().getDescriptor(((XMLRoot)objectToWrite).getObject().getClass());
} else {
desc = (XMLDescriptor)xmlContext.getSession(0).getProject().getDescriptor(objectToWrite.getClass());
}
int sizeBefore = getNamespaceResolverSize(desc);
jaxbMarshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/xml");
try {
jaxbMarshaller.marshal(objectToWrite, writer);
} catch(Exception e) {
assertMarshalException(e);
return;
}
if(expectsMarshalException){
fail("An exception should have occurred but didn't.");
return;
}
int sizeAfter = getNamespaceResolverSize(desc);
assertEquals(sizeBefore, sizeAfter);
Document testDocument = getTestDocument(writer.toString());
writer.close();
objectToXMLDocumentTest(testDocument);
}
@Override
public void testObjectToXMLStreamWriter() throws Exception {
if(XML_OUTPUT_FACTORY != null) {
StringWriter writer = new StringWriter();
XMLOutputFactory factory = XMLOutputFactory.newInstance();
factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.valueOf(false));
XMLStreamWriter streamWriter= factory.createXMLStreamWriter(writer);
Object objectToWrite = getWriteControlObject();
XMLDescriptor desc = null;
if (objectToWrite instanceof XMLRoot) {
desc = (XMLDescriptor)xmlContext.getSession(0).getProject().getDescriptor(((XMLRoot)objectToWrite).getObject().getClass());
} else {
desc = (XMLDescriptor)xmlContext.getSession(0).getProject().getDescriptor(objectToWrite.getClass());
}
jaxbMarshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/xml");
int sizeBefore = getNamespaceResolverSize(desc);
try {
jaxbMarshaller.marshal(objectToWrite, streamWriter);
} catch(Exception e) {
assertMarshalException(e);
return;
}
if(expectsMarshalException){
fail("An exception should have occurred but didn't.");
return;
}
streamWriter.flush();
int sizeAfter = getNamespaceResolverSize(desc);
assertEquals(sizeBefore, sizeAfter);
Document testDocument = getTestDocument(writer.toString());
writer.close();
objectToXMLDocumentTest(testDocument);
}
}
public void testObjectToXMLStreamWriterRecord() throws Exception {
if(XML_OUTPUT_FACTORY != null) {
StringWriter writer = new StringWriter();
XMLOutputFactory factory = XMLOutputFactory.newInstance();
factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.valueOf(false));
XMLStreamWriter streamWriter= factory.createXMLStreamWriter(writer);
Object objectToWrite = getWriteControlObject();
XMLDescriptor desc = null;
if (objectToWrite instanceof XMLRoot) {
desc = (XMLDescriptor)xmlContext.getSession(0).getProject().getDescriptor(((XMLRoot)objectToWrite).getObject().getClass());
} else {
desc = (XMLDescriptor)xmlContext.getSession(0).getProject().getDescriptor(objectToWrite.getClass());
}
jaxbMarshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/xml");
int sizeBefore = getNamespaceResolverSize(desc);
XMLStreamWriterRecord record = new XMLStreamWriterRecord(streamWriter);
try {
((org.eclipse.persistence.jaxb.JAXBMarshaller)jaxbMarshaller).marshal(objectToWrite, record);
} catch(Exception e) {
assertMarshalException(e);
return;
}
if(expectsMarshalException){
fail("An exception should have occurred but didn't.");
return;
}
streamWriter.flush();
int sizeAfter = getNamespaceResolverSize(desc);
assertEquals(sizeBefore, sizeAfter);
Document testDocument = getTestDocument(writer.toString());
writer.close();
objectToXMLDocumentTest(testDocument);
}
}
@Override
public void testObjectToXMLEventWriter() throws Exception {
if(XML_OUTPUT_FACTORY != null) {
StringWriter writer = new StringWriter();
XMLOutputFactory factory = XMLOutputFactory.newInstance();
factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.valueOf(false));
XMLEventWriter eventWriter= factory.createXMLEventWriter(writer);
Object objectToWrite = getWriteControlObject();
XMLDescriptor desc = null;
if (objectToWrite instanceof XMLRoot) {
desc = (XMLDescriptor)xmlContext.getSession(0).getProject().getDescriptor(((XMLRoot)objectToWrite).getObject().getClass());
} else {
desc = (XMLDescriptor)xmlContext.getSession(0).getProject().getDescriptor(objectToWrite.getClass());
}
jaxbMarshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/xml");
int sizeBefore = getNamespaceResolverSize(desc);
try {
jaxbMarshaller.marshal(objectToWrite, eventWriter);
} catch(Exception e) {
assertMarshalException(e);
return;
}
if(expectsMarshalException){
fail("An exception should have occurred but didn't.");
return;
}
eventWriter.flush();
int sizeAfter = getNamespaceResolverSize(desc);
assertEquals(sizeBefore, sizeAfter);
Document testDocument = getTestDocument(writer.toString());
writer.close();
objectToXMLDocumentTest(testDocument);
}
}
@Override
public void testObjectToContentHandler() throws Exception {
SAXDocumentBuilder builder = new SAXDocumentBuilder();
Object objectToWrite = getWriteControlObject();
XMLDescriptor desc = null;
if (objectToWrite instanceof XMLRoot) {
desc = (XMLDescriptor)xmlContext.getSession(0).getProject().getDescriptor(((XMLRoot)objectToWrite).getObject().getClass());
} else {
desc = (XMLDescriptor)xmlContext.getSession(0).getProject().getDescriptor(objectToWrite.getClass());
}
int sizeBefore = getNamespaceResolverSize(desc);
jaxbMarshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/xml");
try {
jaxbMarshaller.marshal(objectToWrite, builder);
} catch(Exception e) {
assertMarshalException(e);
return;
}
if(expectsMarshalException){
fail("An exception should have occurred but didn't.");
return;
}
int sizeAfter = getNamespaceResolverSize(desc);
assertEquals(sizeBefore, sizeAfter);
Document controlDocument = getWriteControlDocument();
Document testDocument = builder.getDocument();
log("**testObjectToContentHandler**");
log("Expected:");
log(controlDocument);
log("\nActual:");
log(testDocument);
//Diff diff = new Diff(controlDocument, testDocument);
//this.assertXMLEqual(diff, true);
assertXMLIdentical(controlDocument, testDocument);
}
@Override
public void testXMLToObjectFromURL() throws Exception {
if(isUnmarshalTest()) {
java.net.URL url = ClassLoader.getSystemResource(resourceName);
jaxbUnmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, getXMLUnmarshalMediaType());
Object testObject = null;
if(getUnmarshalClass() != null){
testObject = jaxbUnmarshaller.unmarshal(new StreamSource(url.openStream()), getUnmarshalClass());
}else{
testObject = jaxbUnmarshaller.unmarshal(url);
}
xmlToObjectTest(testObject);
}
}
@Override
public void testXMLToObjectFromXMLStreamReader() throws Exception {
if(null != XML_INPUT_FACTORY && isUnmarshalTest()) {
InputStream instream = ClassLoader.getSystemResourceAsStream(resourceName);
XMLStreamReader xmlStreamReader = XML_INPUT_FACTORY.createXMLStreamReader(instream);
jaxbUnmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, getXMLUnmarshalMediaType());
Object testObject = null;
if(getUnmarshalClass() != null){
testObject = getJAXBUnmarshaller().unmarshal(xmlStreamReader, getUnmarshalClass());
}else{
testObject = jaxbUnmarshaller.unmarshal(xmlStreamReader);
}
instream.close();
xmlToObjectTest(testObject);
}
}
@Override
public void testXMLToObjectFromNode() throws Exception {
if(isUnmarshalTest()) {
InputStream instream = ClassLoader.getSystemResourceAsStream(resourceName);
Node node = parser.parse(instream);
jaxbUnmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, getXMLUnmarshalMediaType());
Object testObject = null;
if(getUnmarshalClass() != null){
testObject = jaxbUnmarshaller.unmarshal(node, getUnmarshalClass());
}else{
testObject = jaxbUnmarshaller.unmarshal(node);
}
instream.close();
xmlToObjectTest(testObject);
}
}
public void testXMLToObjectFromXMLStreamReaderEx() throws Exception {
if(null != XML_INPUT_FACTORY && isUnmarshalTest()) {
InputStream instream = ClassLoader.getSystemResourceAsStream(resourceName);
XMLStreamReader xmlStreamReader = XML_INPUT_FACTORY.createXMLStreamReader(instream);
ExtendedXMLStreamReaderReader xmlStreamReaderReaderEx = new ExtendedXMLStreamReaderReader();
xmlStreamReaderReaderEx.setErrorHandler(((JAXBUnmarshaller) jaxbUnmarshaller).getXMLUnmarshaller().getErrorHandler());
XMLStreamReaderInputSource xmlStreamReaderInputSource = new XMLStreamReaderInputSource(xmlStreamReader);
SAXSource saxSource = new SAXSource(xmlStreamReaderReaderEx, xmlStreamReaderInputSource);
jaxbUnmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, getXMLUnmarshalMediaType());
Object testObject = null;
if(getUnmarshalClass() != null){
testObject = jaxbUnmarshaller.unmarshal(saxSource, getUnmarshalClass());
}else{
testObject = jaxbUnmarshaller.unmarshal(saxSource);
}
instream.close();
xmlToObjectTest(testObject);
}
}
@Override
public void testXMLToObjectFromXMLEventReader() throws Exception {
if(null != XML_INPUT_FACTORY && isUnmarshalTest()) {
InputStream instream = ClassLoader.getSystemResourceAsStream(resourceName);
XMLEventReader xmlEventReader = XML_INPUT_FACTORY.createXMLEventReader(instream);
jaxbUnmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, getXMLUnmarshalMediaType());
Object testObject = null;
if(getUnmarshalClass() != null){
testObject = jaxbUnmarshaller.unmarshal(xmlEventReader, getUnmarshalClass());
}else{
testObject = jaxbUnmarshaller.unmarshal(xmlEventReader);
}
instream.close();
xmlToObjectTest(testObject);
}
}
@Override
public void testObjectToXMLDocument() throws Exception {
Object objectToWrite = getWriteControlObject();
XMLDescriptor desc = null;
if (objectToWrite instanceof XMLRoot) {
desc = (XMLDescriptor)xmlContext.getSession(0).getProject().getDescriptor(((XMLRoot)objectToWrite).getObject().getClass());
} else {
desc = (XMLDescriptor)xmlContext.getSession(0).getProject().getDescriptor(objectToWrite.getClass());
}
jaxbMarshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/xml");
int sizeBefore = getNamespaceResolverSize(desc);
Document testDocument = XMLPlatformFactory.getInstance().getXMLPlatform().createDocument();
try {
jaxbMarshaller.marshal(objectToWrite, testDocument);
} catch(Exception e) {
assertMarshalException(e);
return;
}
if(expectsMarshalException){
fail("An exception should have occurred but didn't.");
return;
}
int sizeAfter = getNamespaceResolverSize(desc);
assertEquals(sizeBefore, sizeAfter);
objectToXMLDocumentTest(testDocument);
}
@Override
public void xmlToObjectTest(Object testObject) throws Exception {
xmlToObjectTest(testObject, getReadControlObject());
}
public void xmlToObjectTest(Object testObject, Object controlObject) throws Exception {
log("\n**xmlToObjectTest**");
log("Expected:");
log(controlObject.toString());
log("Actual:");
log(testObject.toString());
if ((controlObject instanceof JAXBElement) && (testObject instanceof JAXBElement)) {
JAXBElement controlObj = (JAXBElement)controlObject;
JAXBElement testObj = (JAXBElement)testObject;
compareJAXBElementObjects(controlObj, testObj);
} else {
super.xmlToObjectTest(testObject);
}
}
@Override
public void testUnmarshallerHandler() throws Exception {
if(isUnmarshalTest()) {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setNamespaceAware(true);
SAXParser saxParser = saxParserFactory.newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader();
jaxbUnmarshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/xml");
JAXBUnmarshallerHandler jaxbUnmarshallerHandler = (JAXBUnmarshallerHandler)jaxbUnmarshaller.getUnmarshallerHandler();
xmlReader.setContentHandler(jaxbUnmarshallerHandler);
InputStream inputStream = ClassLoader.getSystemResourceAsStream(resourceName);
InputSource inputSource = new InputSource(inputStream);
xmlReader.parse(inputSource);
xmlToObjectTest(jaxbUnmarshallerHandler.getResult());
}
}
public void testSchemaGen(List<InputStream> controlSchemas) throws Exception {
MyStreamSchemaOutputResolver outputResolver = new MyStreamSchemaOutputResolver();
getJAXBContext().generateSchema(outputResolver);
List<Writer> generatedSchemas = outputResolver.getSchemaFiles();
compareSchemas(controlSchemas, generatedSchemas);
}
public void compareSchemas(List<InputStream> controlSchemas, List<Writer> generatedSchemas) throws Exception {
assertEquals(controlSchemas.size(), generatedSchemas.size());
for(int i=0;i<controlSchemas.size(); i++){
InputStream nextControlValue = controlSchemas.get(i);
Writer sw = generatedSchemas.get(i);
InputSource nextGeneratedValue = new InputSource(new StringReader(sw.toString()));
assertNotNull("Generated Schema not found.", nextGeneratedValue);
Document control = parser.parse(nextControlValue);
Document test = parser.parse(nextGeneratedValue);
JAXBXMLComparer xmlComparer = new JAXBXMLComparer();
boolean isEqual = xmlComparer.isSchemaEqual(control, test);
if(!isEqual){
logDocument(control);
logDocument(test);
}
assertTrue("generated schema did not match control schema", isEqual);
}
}
protected String validateAgainstSchema(InputStream src, Source schemaSource) {
return validateAgainstSchema(src, schemaSource, null);
}
protected String validateAgainstSchema(InputStream src, Source schemaSource, MyMapStreamSchemaOutputResolver outputResolver) {
SchemaFactory sFact = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
sFact.setResourceResolver(new ResourceResolver(outputResolver));
Schema theSchema;
try {
theSchema = sFact.newSchema(schemaSource);
Validator validator = theSchema.newValidator();
StreamSource ss = new StreamSource(src);
validator.validate(ss);
} catch (Exception e) {
if (e.getMessage() == null) {
return "An unknown exception occurred.";
}
return e.getMessage();
}
return null;
}
public class MySchemaOutputResolver extends SchemaOutputResolver {
// keep a list of processed schemas for the validation phase of the
// test(s)
public List<File> schemaFiles;
public MySchemaOutputResolver() {
schemaFiles = new ArrayList<File>();
}
@Override
public Result createOutput(String namespaceURI, String suggestedFileName)throws IOException {
File schemaFile = new File(suggestedFileName);
if(namespaceURI == null){
namespaceURI ="";
}
schemaFiles.add(schemaFile);
return new StreamResult(schemaFile);
}
public List<File> getSchemaFiles() {
return schemaFiles;
}
}
/**
* SchemaOutputResolver for writing out the generated schema. Returns a StreamResult
* wrapping a StringWriter.
*
*/
public static class MyStreamSchemaOutputResolver extends SchemaOutputResolver {
// keep a list of processed schemas for the validation phase of the test(s)
private List<Writer> schemaFiles;
public MyStreamSchemaOutputResolver() {
schemaFiles = new ArrayList<Writer>();
}
@Override
public Result createOutput(String namespaceURI, String suggestedFileName) throws IOException {
if (namespaceURI == null) {
namespaceURI = "";
}
StringWriter sw = new StringWriter();
schemaFiles.add(sw);
Result res = new StreamResult(sw);
res.setSystemId(suggestedFileName);
return res;
}
public List<Writer> getSchemaFiles() {
return schemaFiles;
}
}
public static class MyMapStreamSchemaOutputResolver extends SchemaOutputResolver {
// keep a list of processed schemas for the validation phase of the test(s)
public Map<String, Writer> schemaFiles;
public MyMapStreamSchemaOutputResolver() {
schemaFiles = new HashMap<String, Writer>();
}
@Override
public Result createOutput(String namespaceURI, String suggestedFileName) throws IOException {
//return new StreamResult(System.out);
if (namespaceURI == null) {
namespaceURI = "";
}
StringWriter sw = new StringWriter();
schemaFiles.put(namespaceURI, sw);
Result res = new StreamResult(sw);
res.setSystemId(suggestedFileName);
return res;
}
}
protected void logDocument(Document document){
try {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
} catch (Exception e) {
e.printStackTrace();
}
}
protected void validateBindingsFileAgainstSchema(Object obj) {
if(obj instanceof List){
List theList = (List)obj;
for(int i=0; i<theList.size(); i++){
Object next = theList.get(i);
if(next instanceof Source) {
Source src = (Source)theList.get(i);
validateBindingsFileAgainstSchema(src);
}
}
}
}
protected void validateBindingsFileAgainstSchema(Source src) {
String result = null;
SchemaFactory sFact = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema theSchema;
try {
InputStream bindingsFileXSDInputStream = getClass().getClassLoader().getResourceAsStream(ECLIPSELINK_OXM_XSD);
if (bindingsFileXSDInputStream == null){
bindingsFileXSDInputStream = getClass().getClassLoader().getResourceAsStream("org/eclipse/persistence/jaxb/" + ECLIPSELINK_OXM_XSD);
}
if (bindingsFileXSDInputStream == null){
fail("ERROR LOADING " + ECLIPSELINK_OXM_XSD);
}
Source bindingsFileXSDSource = new StreamSource(bindingsFileXSDInputStream);
theSchema = sFact.newSchema(bindingsFileXSDSource);
Validator validator = theSchema.newValidator();
validator.validate(src);
} catch (Exception e) {
e.printStackTrace();
if (e.getMessage() == null) {
result = "An unknown exception occurred.";
}
result = e.getMessage();
}
assertTrue("Schema validation failed unxepectedly: " + result, result == null);
}
public static class ExtendedXMLStreamReaderReader extends XMLStreamReaderReader {
@Override
protected void parseCharactersEvent(XMLStreamReader xmlStreamReader) throws SAXException {
try {
contentHandler.characters(xmlStreamReader.getElementText());
} catch(XMLStreamException e) {
super.parseCharactersEvent(xmlStreamReader);
}
}
}
/**
* Class responsible from resolving schema imports during schema
* validation.
*
*/
class ResourceResolver implements LSResourceResolver {
private MyMapStreamSchemaOutputResolver oResolver;
public ResourceResolver(MyMapStreamSchemaOutputResolver resolver) {
oResolver = resolver;
}
@Override
public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseUri) {
return new MyLSInput(namespaceURI, oResolver);
}
}
/**
* Class which will be returned to from resolveResource() call in
* ResourceResolver.
*
*/
class MyLSInput implements LSInput {
private String sValue;
private MyMapStreamSchemaOutputResolver oResolver;
public MyLSInput(String value, MyMapStreamSchemaOutputResolver resolver) {
sValue = value;
oResolver = resolver;
}
@Override
public void setSystemId(String arg0) {}
@Override
public void setStringData(String arg0) {}
@Override
public void setPublicId(String arg0) {}
@Override
public void setEncoding(String arg0) {}
@Override
public void setCharacterStream(Reader arg0) {}
@Override
public void setCertifiedText(boolean arg0) {}
@Override
public void setByteStream(InputStream arg0) {}
@Override
public void setBaseURI(String arg0) {}
@Override
public String getSystemId() {return null;}
@Override
public String getStringData() {
return oResolver.schemaFiles.get(sValue).toString();
}
@Override
public String getPublicId() {return null;}
@Override
public String getEncoding() {return null;}
@Override
public Reader getCharacterStream() {return null;}
@Override
public boolean getCertifiedText() {return false;}
@Override
public InputStream getByteStream() {return null;}
@Override
public String getBaseURI() {return null;}
}
}