blob: 40d855ace856cb4799e292e9c3d2054b1546d6e2 [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:
// dmccann - June 17/2009 - 2.0 - Initial implementation
package org.eclipse.persistence.testing.jaxb.externalizedmetadata;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
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.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.SchemaOutputResolver;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
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.core.sessions.CoreProject;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.helper.ConversionManager;
import org.eclipse.persistence.internal.jaxb.JaxbClassLoader;
import org.eclipse.persistence.jaxb.JAXBContext;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
import org.eclipse.persistence.jaxb.compiler.Generator;
import org.eclipse.persistence.jaxb.javamodel.reflection.JavaModelImpl;
import org.eclipse.persistence.jaxb.javamodel.reflection.JavaModelInputImpl;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.platform.xml.XMLComparer;
import org.eclipse.persistence.sessions.Project;
import org.eclipse.persistence.testing.jaxb.JAXBXMLComparer;
import org.eclipse.persistence.testing.oxm.OXTestCase;
import org.w3c.dom.Document;
import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSResourceResolver;
import org.xml.sax.InputSource;
import junit.framework.TestCase;
/**
* Tests Externalized Metadata functionality.
*
*/
public class ExternalizedMetadataTestCases extends TestCase {
private static final String tmpdir = System.getenv("T_WORK") == null
? System.getProperty("java.io.tmpdir") : System.getenv("T_WORK");
protected static ClassLoader loader = Thread.currentThread().getContextClassLoader();
protected static String EMPTY_NAMESPACE = "";
protected JAXBContext jaxbContext;
protected DocumentBuilder parser;
/**
* This is the preferred (and only) constructor.
*
*/
public ExternalizedMetadataTestCases(String name) {
super(name);
}
@Override
public void setUp() throws Exception {
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setNamespaceAware(true);
builderFactory.setIgnoringElementContentWhitespace(true);
parser = builderFactory.newDocumentBuilder();
}
/**
* Convenience method that will return the JAXBContext instance created during
* the last generateSchema call.
*
* Assumes a prior call to generateSchema has been made.
*
*/
public JAXBContext getJAXBContext() {
return jaxbContext;
}
/**
* Generate the schema(s) for a given set of classes. Any eclipselink-oxm.xml file(s)
* found in the package(s) will be applied by default.
*
*/
public MySchemaOutputResolver generateSchema(Class[] classes, int expectedSchemaCount) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
MySchemaOutputResolver outputResolver = new MySchemaOutputResolver();
try {
generateSchema(classes, null, outputResolver, classLoader);
} catch (Exception ex) {
ex.printStackTrace();
fail("Schema generation failed unexpectedly: " + ex.toString());
}
assertTrue("No schemas were generated", outputResolver.schemaFiles.size() > 0);
assertTrue("Expected schema generation count to be ["+expectedSchemaCount+"], but was [" + outputResolver.schemaFiles.size() + "]", outputResolver.schemaFiles.size() == expectedSchemaCount);
return outputResolver;
}
/**
* Generate the schema using the CONTEXT_PATH.
*
*/
public MySchemaOutputResolver generateSchema(String contextPath, int expectedSchemaCount) {
MySchemaOutputResolver outputResolver = new MySchemaOutputResolver();
try {
generateSchema(contextPath, outputResolver);
} catch (Exception ex) {
ex.printStackTrace();
fail("Schema generation failed unexpectedly: " + ex.toString());
}
assertTrue("No schemas were generated", outputResolver.schemaFiles.size() > 0);
assertTrue("Expected schema generation count to be ["+expectedSchemaCount+"], but was [" + outputResolver.schemaFiles.size() + "]", outputResolver.schemaFiles.size() == expectedSchemaCount);
return outputResolver;
}
/**
* Generate the schema using the CONTEXT_PATH.
*
*/
public void generateSchema(String contextPath, int expectedSchemaCount, MyStreamSchemaOutputResolver outputResolver) {
try {
generateSchema(contextPath, outputResolver);
} catch (Exception ex) {
ex.printStackTrace();
fail("Schema generation failed unexpectedly: " + ex.toString());
}
assertTrue("No schemas were generated", outputResolver.schemaFiles.size() > 0);
assertTrue("Expected schema generation count to be ["+expectedSchemaCount+"], but was [" + outputResolver.schemaFiles.size() + "]", outputResolver.schemaFiles.size() == expectedSchemaCount);
}
/**
* Generate the schema(s) for a given context path, and apply the eclipselink-oxm.xml
* file(s) in the properties map.
*
*/
public MySchemaOutputResolver generateSchema(String contextPath, Map<String, Object> properties, int expectedSchemaCount) {
MySchemaOutputResolver outputResolver = new MySchemaOutputResolver();
try {
generateSchema(contextPath, outputResolver, properties);
} catch (Exception ex) {
ex.printStackTrace();
fail("Schema generation failed unexpectedly: " + ex.toString());
}
assertTrue("No schemas were generated", outputResolver.schemaFiles.size() > 0);
assertTrue("Expected schema generation count to be ["+expectedSchemaCount+"], but was [" + outputResolver.schemaFiles.size() + "]", outputResolver.schemaFiles.size() == expectedSchemaCount);
return outputResolver;
}
/**
* Generate the schema(s) for a given set of classes, and apply the eclipselink-oxm.xml
* file found on the path. The eclipselink-oxm.xml will be stored in the property map
* using the contextPath as a key (maps package name to xml metadata file).
*
* @param contextPath used as key for storing eclipselink-oxm.xml file Source in properties map
* @param iStream eclipselink-oxm.xml file as a stream
*/
private MySchemaOutputResolver generateSchema(String contextPath, InputStream iStream, int expectedSchemaCount) {
HashMap<String, Source> metadataSourceMap = new HashMap<>();
metadataSourceMap.put(contextPath, new StreamSource(iStream));
validateBindingsFileAgainstSchema(iStream);
Map<String, Object> properties = new HashMap<>();
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, metadataSourceMap);
return generateSchema(contextPath, properties, expectedSchemaCount);
}
/**
* Generate the schema(s) for a given set of classes, and apply the eclipselink-oxm.xml
* file found on the path. The eclipselink-oxm.xml will be stored in the property map
* using the contextPath as a key (maps package name to xml metadata file).
*
* @param contextPath used as key for storing eclipselink-oxm.xml file Source in properties map
* @param path eclipselink-oxm.xml file will be searched for on this path
*/
public MySchemaOutputResolver generateSchema(String contextPath, String path, int expectedSchemaCount) {
String metadataFile = path + "eclipselink-oxm.xml";
return generateSchemaWithFileName(contextPath, metadataFile, expectedSchemaCount);
}
public MySchemaOutputResolver generateSchemaWithFileName(String contextPath, String metadataFile, int expectedSchemaCount) {
InputStream iStream = loader.getResourceAsStream(metadataFile);
InputStream iStreamCopy = loader.getResourceAsStream(metadataFile);
if (iStream == null) {
fail("Couldn't load metadata file [" + metadataFile + "]");
}
validateBindingsFileAgainstSchema(iStreamCopy);
HashMap<String, Source> metadataSourceMap = new HashMap<>();
metadataSourceMap.put(contextPath, new StreamSource(iStream));
Map<String, Object> properties = new HashMap<>();
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, metadataSourceMap);
return generateSchema(contextPath, properties, expectedSchemaCount);
}
/**
* Generate the schema(s) for a given set of classes, and apply the eclipselink-oxm.xml
* file found on the path. The eclipselink-oxm.xml will be stored in the property map
* using the contextPath as a key (maps package name to xml metadata file).
*
* @param contextPath used as key for storing eclipselink-oxm.xml file Source in properties map
* @param iStream eclipselink-oxm.xml file as a stream
*/
private MySchemaOutputResolver generateSchema(Class[] classes, String contextPath, InputStream iStream, int expectedSchemaCount) {
HashMap<String, Source> metadataSourceMap = new HashMap<String, Source>();
metadataSourceMap.put(contextPath, new StreamSource(iStream));
Map<String, Map<String, Source>> properties = new HashMap<String, Map<String, Source>>();
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, metadataSourceMap);
MySchemaOutputResolver outputResolver = new MySchemaOutputResolver();
try {
generateSchema(classes, properties, outputResolver, loader);
} catch (Exception ex) {
ex.printStackTrace();
fail("Schema generation failed unexpectedly: " + ex.toString());
}
assertTrue("No schemas were generated", outputResolver.schemaFiles.size() > 0);
assertTrue("Expected schema generation count to be ["+expectedSchemaCount+"], but was [" + outputResolver.schemaFiles.size() + "]", outputResolver.schemaFiles.size() == expectedSchemaCount);
return outputResolver;
}
/**
* Generate the schema(s) for a given set of classes, and apply the eclipselink-oxm.xml
* file found on the path. The eclipselink-oxm.xml will be stored in the property map
* using the contextPath as a key (maps package name to xml metadata file).
*
* @param contextPath used as key for storing eclipselink-oxm.xml file Source in properties map
* @param path eclipselink-oxm.xml file will be searched for on this path
*/
public MySchemaOutputResolver generateSchema(Class[] classes, String contextPath, String path, int expectedSchemaCount) {
String metadataFile = path + "eclipselink-oxm.xml";
return generateSchemaWithFileName(classes, contextPath, metadataFile, expectedSchemaCount);
}
public void generateSchemaWithFileName(Class[] classes, String contextPath, String metadataFile, int expectedSchemaCount, MyStreamSchemaOutputResolver outputResolver) {
InputStream iStream = loader.getResourceAsStream(metadataFile);
InputStream iStreamCopy = loader.getResourceAsStream(metadataFile);
if (iStream == null) {
fail("Couldn't load metadata file [" + metadataFile + "]");
}
HashMap<String, Source> metadataSourceMap = new HashMap<String, Source>();
metadataSourceMap.put(contextPath, new StreamSource(iStream));
Map<String, Map<String, Source>> properties = new HashMap<String, Map<String, Source>>();
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, metadataSourceMap);
validateBindingsFileAgainstSchema(iStreamCopy);
try {
generateSchema(classes, properties, outputResolver, loader);
} catch (Exception ex) {
ex.printStackTrace();
fail("Schema generation failed unexpectedly: " + ex.toString());
}
if(expectedSchemaCount >0){
assertTrue("No schemas were generated", outputResolver.schemaFiles.size() > 0);
}
assertTrue("Expected schema generation count to be ["+expectedSchemaCount+"], but was [" + outputResolver.schemaFiles.size() + "]", outputResolver.schemaFiles.size() == expectedSchemaCount);
}
public MySchemaOutputResolver generateSchemaWithFileName(Class[] classes, String contextPath, String metadataFile, int expectedSchemaCount) {
InputStream iStream = loader.getResourceAsStream(metadataFile);
InputStream iStreamCopy = loader.getResourceAsStream(metadataFile);
if (iStream == null) {
fail("Couldn't load metadata file [" + metadataFile + "]");
}
HashMap<String, Source> metadataSourceMap = new HashMap<String, Source>();
metadataSourceMap.put(contextPath, new StreamSource(iStream));
Map<String, Map<String, Source>> properties = new HashMap<String, Map<String, Source>>();
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, metadataSourceMap);
MySchemaOutputResolver outputResolver = new MySchemaOutputResolver();
validateBindingsFileAgainstSchema(iStreamCopy);
try {
generateSchema(classes, properties, outputResolver, loader);
} catch (Exception ex) {
ex.printStackTrace();
fail("Schema generation failed unexpectedly: " + ex.toString());
}
if(expectedSchemaCount >0){
assertTrue("No schemas were generated", outputResolver.schemaFiles.size() > 0);
}
assertTrue("Expected schema generation count to be ["+expectedSchemaCount+"], but was [" + outputResolver.schemaFiles.size() + "]", outputResolver.schemaFiles.size() == expectedSchemaCount);
return outputResolver;
}
/**
* Generate the schema(s) for a given set of types, and apply the eclipselink-oxm.xml
* file found on the path. The eclipselink-oxm.xml will be stored in the property map
* using the contextPath as a key (maps package name to xml metadata file).
*
* @param contextPath used as key for storing eclipselink-oxm.xml file Source in properties map
* @param path eclipselink-oxm.xml file will be searched for on this path
*/
public MySchemaOutputResolver generateSchema(Type[] types, String contextPath, String path, int expectedSchemaCount) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
String metadataFile = path + "eclipselink-oxm.xml";
InputStream iStream = classLoader.getResourceAsStream(metadataFile);
InputStream iStreamCopy = classLoader.getResourceAsStream(metadataFile);
if (iStream == null) {
fail("Couldn't load metadata file [" + metadataFile + "]");
}
validateBindingsFileAgainstSchema(iStreamCopy);
HashMap<String, Source> metadataSourceMap = new HashMap<String, Source>();
metadataSourceMap.put(contextPath, new StreamSource(iStream));
Map<String, Map<String, Source>> properties = new HashMap<String, Map<String, Source>>();
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, metadataSourceMap);
MySchemaOutputResolver outputResolver = new MySchemaOutputResolver();
try {
generateSchema(types, properties, outputResolver, classLoader);
} catch (Exception ex) {
ex.printStackTrace();
fail("Schema generation failed unexpectedly: " + ex.toString());
}
assertTrue("No schemas were generated", outputResolver.schemaFiles.size() > 0);
assertTrue("Expected schema generation count to be ["+expectedSchemaCount+"], but was [" + outputResolver.schemaFiles.size() + "]", outputResolver.schemaFiles.size() == expectedSchemaCount);
return outputResolver;
}
/**
* Generate one or more schemas from a context path.
*
*/
protected void generateSchema(String contextPath, SchemaOutputResolver outputResolver, Map<String, Object> properties) throws Exception {
try {
jaxbContext = (JAXBContext) JAXBContextFactory.createContext(contextPath, loader, properties);
jaxbContext.generateSchema(outputResolver);
} catch (JAXBException e) {
e.printStackTrace();
}
}
/**
* Generate one or more schemas from a context path.
*
*/
protected void generateSchema(String contextPath, SchemaOutputResolver outputResolver) throws Exception {
try {
jaxbContext = (JAXBContext) JAXBContextFactory.createContext(contextPath, loader);
jaxbContext.generateSchema(outputResolver);
} catch (JAXBException e) {
e.printStackTrace();
}
}
/**
* Generate one or more schemas from an array of classes and a Map containing zero or more
* eclipselink-oxm.xml entries.
*
*/
protected void generateSchema(Class[] classesToBeBound, java.util.Map properties, SchemaOutputResolver outputResolver, ClassLoader classLoader) throws Exception {
try {
jaxbContext = (JAXBContext) JAXBContextFactory.createContext(classesToBeBound, properties, classLoader);
jaxbContext.generateSchema(outputResolver);
} catch (JAXBException e) {
e.printStackTrace();
}
}
/**
* Generate one or more schemas from an array of types and a Map containing zero or more
* eclipselink-oxm.xml entries.
*
*/
protected void generateSchema(Type[] typesToBeBound, java.util.Map properties, SchemaOutputResolver outputResolver, ClassLoader classLoader) throws Exception {
try {
jaxbContext = (JAXBContext) JAXBContextFactory.createContext(typesToBeBound, properties, classLoader);
jaxbContext.generateSchema(outputResolver);
} catch (JAXBException e) {
e.printStackTrace();
}
}
/**
* Validates a given instance doc against the generated schema.
*
* @param namespace index in output resolver's list of generated schemas
* @param outputResolver contains one or more schemas to validate against
*/
protected String validateAgainstSchema(String src, String namespace, MySchemaOutputResolver outputResolver) {
SchemaFactory sFact = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema theSchema;
try {
theSchema = sFact.newSchema(outputResolver.schemaFiles.get(namespace));
Validator validator = theSchema.newValidator();
StreamSource ss = new StreamSource(new File(src));
validator.validate(ss);
} catch (Exception e) {
//e.printStackTrace();
if (e.getMessage() == null) {
return "An unknown exception occurred.";
}
return e.getMessage();
}
return null;
}
/**
* Validates a given instance doc against the generated schema.
*
* @param namespace index in output resolver's list of generated schemas
* @param outputResolver contains one or more schemas to validate against
*/
protected String validateAgainstSchema(InputStream src, String namespace, MySchemaOutputResolver outputResolver) {
SchemaFactory sFact = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema theSchema;
try {
theSchema = sFact.newSchema(outputResolver.schemaFiles.get(namespace));
Validator validator = theSchema.newValidator();
StreamSource ss = new StreamSource(src);
validator.validate(ss);
} catch (Exception e) {
//e.printStackTrace();
if (e.getMessage() == null) {
return "An unknown exception occurred.";
}
return e.getMessage();
}
return null;
}
/**
* Validates a given instance doc against a given schema.
*
*/
protected String validateAgainstSchema(String src, String schema) {
SchemaFactory sFact = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema theSchema;
try {
theSchema = sFact.newSchema(new File(schema));
Validator validator = theSchema.newValidator();
StreamSource ss = new StreamSource(new File(src));
validator.validate(ss);
} catch (Exception e) {
//e.printStackTrace();
if (e.getMessage() == null) {
return "An unknown exception occurred.";
}
return e.getMessage();
}
return null;
}
/**
* Validates a given instance doc against the generated schema.
*
* @param namespace index in output resolver's list of generated schemas
* @param outputResolver contains one or more schemas to validate against
*/
protected String validateAgainstSchema(String src, String namespace, MyStreamSchemaOutputResolver outputResolver) {
SchemaFactory sFact = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);
sFact.setResourceResolver(new ResourceResolver(outputResolver));
Schema theSchema;
try {
Writer sw = outputResolver.schemaFiles.get(namespace);
theSchema = sFact.newSchema(new StreamSource(new StringReader(sw.toString())));
Validator validator = theSchema.newValidator();
StreamSource ss = new StreamSource(new File(src));
validator.validate(ss);
} catch (Exception e) {
//e.printStackTrace();
if (e.getMessage() == null) {
return "An unknown exception occurred.";
}
return e.getMessage();
}
return null;
}
/**
* Class responsible from resolving schema imports during schema
* validation.
*
*/
class ResourceResolver implements LSResourceResolver {
private MyStreamSchemaOutputResolver oResolver;
public ResourceResolver(MyStreamSchemaOutputResolver 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 MyStreamSchemaOutputResolver oResolver;
public MyLSInput(String value, MyStreamSchemaOutputResolver 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;}
}
/**
* Validates a given bindings file against the eclipselink oxm schema.
*
*/
protected void validateBindingsFileAgainstSchema(InputStream 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_2_6.xsd");
if (bindingsFileXSDInputStream == null){
bindingsFileXSDInputStream = getClass().getClassLoader().getResourceAsStream("org/eclipse/persistence/jaxb/eclipselink_oxm_2_6.xsd");
}
if (bindingsFileXSDInputStream == null){
fail("ERROR LOADING eclipselink_oxm_2_6.xsd");
}
Source bindingsFileXSDSource = new StreamSource(bindingsFileXSDInputStream);
theSchema = sFact.newSchema(bindingsFileXSDSource);
Validator validator = theSchema.newValidator();
StreamSource ss = new StreamSource(src);
validator.validate(ss);
} 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);
}
/**
* Compare two schemas for equality.
*
*/
public static void compareSchemas(File testSchema, File controlSchema) {
if (testSchema == null || controlSchema == null) {
fail("Can't compare null schema file.");
}
try {
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setIgnoringElementContentWhitespace(true);
builderFactory.setNamespaceAware(true);
DocumentBuilder parser = builderFactory.newDocumentBuilder();
InputStream stream = new FileInputStream(testSchema);
Document control = parser.parse(stream);
stream = new FileInputStream(controlSchema);
Document test = parser.parse(stream);
JAXBXMLComparer xmlComparer = new JAXBXMLComparer();
if (!xmlComparer.isSchemaEqual(control, test)) {
fail("The test schema did not match the control schema.\nEXPECTED:\n" + getFileAsText(controlSchema) + "\nACTUAL:\n" + getFileAsText(testSchema));
}
} catch (Exception x) {
fail("An error occurred during schema comparison: " + x.getMessage());
}
}
/**
* Compare two schemas for equality.
*
*/
public static void compareSchemas(String testSchema, File controlSchema) {
if (testSchema == null || controlSchema == null) {
fail("Can't compare null schema file.");
}
try {
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setIgnoringElementContentWhitespace(true);
builderFactory.setNamespaceAware(true);
DocumentBuilder parser = builderFactory.newDocumentBuilder();
InputStream stream = new FileInputStream(controlSchema);
Document control = parser.parse(stream);
InputSource source = new InputSource(new StringReader(testSchema));
Document test = parser.parse(source);
JAXBXMLComparer xmlComparer = new JAXBXMLComparer();
if (!xmlComparer.isSchemaEqual(control, test)) {
fail("The test schema did not match the control schema.\nEXPECTED:\n" + getFileAsText(controlSchema) + "\nACTUAL:\n" + testSchema);
}
} catch (Exception x) {
fail("An error occurred during schema comparison: " + x.getMessage());
}
}
public static boolean compareDocuments(Document ctrlDoc, Document testDoc) {
return new XMLComparer().isNodeEqual(ctrlDoc, testDoc);
}
public static String getFileAsText(String filename) {
return getFileAsText(new File(filename));
}
public static String getFileAsText(File file) {
StringBuilder text = new StringBuilder();
String NL = System.getProperty("line.separator");
Scanner scanner = null;
try {
scanner = new Scanner(new FileInputStream(file));
while (scanner.hasNextLine()) {
text.append(scanner.nextLine() + NL);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
scanner.close();
}
return text.toString();
}
/**
* SchemaOutputResolver for writing out the generated schema. Returns a StreamResult
* wrapping a File.
*
*/
public static class MySchemaOutputResolver extends SchemaOutputResolver {
// keep a list of processed schemas for the validation phase of the test(s)
public Map<String, File> schemaFiles;
public MySchemaOutputResolver() {
schemaFiles = new HashMap<String, File>();
}
@Override
public Result createOutput(String namespaceURI, String suggestedFileName) throws IOException {
//return new StreamResult(System.out);
if (namespaceURI == null) {
namespaceURI = EMPTY_NAMESPACE;
}
File schemaFile = new File(tmpdir, suggestedFileName);
schemaFiles.put(namespaceURI, schemaFile);
return new StreamResult(schemaFile);
}
}
/**
* 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)
public Map<String, Writer> schemaFiles;
public MyStreamSchemaOutputResolver() {
schemaFiles = new HashMap<String, Writer>();
}
@Override
public Result createOutput(String namespaceURI, String suggestedFileName) throws IOException {
//return new StreamResult(System.out);
if (namespaceURI == null) {
namespaceURI = EMPTY_NAMESPACE;
}
StringWriter sw = new StringWriter();
schemaFiles.put(namespaceURI, sw);
Result res = new StreamResult(sw);
res.setSystemId(suggestedFileName);
return res;
}
}
/**
* Convenience method that returns a newly created XMLContext based on an array of classes.
*
*/
protected XMLContext createXmlContext(Class[] classes) {
try {
ClassLoader classLoader = new JaxbClassLoader(Thread.currentThread().getContextClassLoader());
Generator generator = new Generator(new JavaModelInputImpl(classes, new JavaModelImpl(classLoader)));
CoreProject proj = generator.generateProject();
ConversionManager manager = new ConversionManager();
manager.setLoader(classLoader);
for (Iterator<ClassDescriptor> descriptorIt = proj.getOrderedDescriptors().iterator(); descriptorIt.hasNext(); ) {
ClassDescriptor descriptor = descriptorIt.next();
if (descriptor.getJavaClass() == null) {
descriptor.setJavaClass(manager.convertClassNameToClass(descriptor.getJavaClassName()));
}
}
return new XMLContext((Project)proj, classLoader);
} catch (Exception e) {
e.printStackTrace();
fail("XmlContext creation failed");
}
return null;
}
protected Document getControlDocument(String xmlResource) throws Exception {
InputStream inputStream = ClassLoader.getSystemResourceAsStream(xmlResource);
Document document = parser.parse(inputStream);
OXTestCase.removeEmptyTextNodes(document);
return document;
}
/**
* Convenience method for creating a JAXBContext. The XML document is
* validated against the metadata schema.
*
*/
public JAXBContext createContext(Class[] classes, String contextPath, String metadataFile) throws JAXBException {
// validate instance document against the metadata schema
InputStream iStream = loader.getResourceAsStream(metadataFile);
InputStream iStreamCopy = loader.getResourceAsStream(metadataFile);
if (iStream == null) {
fail("Couldn't load metadata file [" + metadataFile + "]");
}
HashMap<String, Source> metadataSourceMap = new HashMap<>();
metadataSourceMap.put(contextPath, new StreamSource(iStream));
Map<String, Object> properties = new HashMap<>();
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, metadataSourceMap);
MySchemaOutputResolver outputResolver = new MySchemaOutputResolver();
validateBindingsFileAgainstSchema(iStreamCopy);
// create the JAXBContext
jaxbContext = (JAXBContext) JAXBContextFactory.createContext(classes, properties, loader);
return jaxbContext;
}
}