| /* |
| * 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.schemagen.imports; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.nio.file.Files; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import jakarta.xml.bind.JAXBContext; |
| import jakarta.xml.bind.SchemaOutputResolver; |
| import javax.xml.transform.Result; |
| 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.jaxb.JAXBContextFactory; |
| 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.testing.jaxb.externalizedmetadata.ExternalizedMetadataTestCases; |
| import org.eclipse.persistence.testing.jaxb.schemagen.imports.address.Address; |
| import org.eclipse.persistence.testing.jaxb.schemagen.imports.relativeschemalocation.test.Foo; |
| import org.eclipse.persistence.testing.jaxb.schemagen.imports.relativeschemalocation.test2.Bar; |
| import org.xml.sax.SAXException; |
| |
| import junit.framework.TestCase; |
| |
| public class SchemaGenImportTestCases extends TestCase { |
| |
| private static final String PACKAGE_RESOURCE = "org/eclipse/persistence/testing/jaxb/schemagen/imports/"; |
| private static final String IMPORTS_XML = "imports.xml"; |
| private static final String XML_RESOURCE = PACKAGE_RESOURCE + IMPORTS_XML; |
| private static final String INVALID_XML_RESOURCE = PACKAGE_RESOURCE + "invalid_imports.xml"; |
| private static final String EMPLOYEE_XSD_RESOURCE = PACKAGE_RESOURCE + "employee.xsd"; |
| private static final String ADDRESS_XSD_RESOURCE = PACKAGE_RESOURCE + "address.xsd"; |
| |
| private static final String EMPLOYEE_NS = "employeeNamespace"; |
| private static final String ADDRESS_NS = "addressNamespace"; |
| private static final String FILE = "file:///"; |
| private static final String FOO_URI = "http://test.org"; |
| private static final String FOO_SCHEMA = PACKAGE_RESOURCE + "foo.xsd"; |
| private static final String BAR_URI = "http://test2.org"; |
| private static final String BAR_SCHEMA = PACKAGE_RESOURCE + "bar.xsd"; |
| |
| private static final String tmpdir = System.getenv("T_WORK") == null |
| ? System.getProperty("java.io.tmpdir") : System.getenv("T_WORK"); |
| |
| public SchemaGenImportTestCases(String name) throws Exception { |
| super(name); |
| } |
| |
| public void testSchemaGenerationWithImport() { |
| Class[] jClasses = new Class[] { Address.class, Employee.class}; |
| |
| Generator gen = new Generator(new JavaModelInputImpl(jClasses, new JavaModelImpl(Thread.currentThread().getContextClassLoader()))); |
| File outDir = setOutDir(); |
| try { |
| Files.copy(getFile(PACKAGE_RESOURCE + "someExistingSchema.xsd").toPath(), new File(outDir, "someExistingSchema.xsd").toPath()); |
| } catch (IOException e1) { |
| throw new RuntimeException(e1); |
| } |
| MySystemIDSchemaOutputResolver mysor = new MySystemIDSchemaOutputResolver(outDir); |
| gen.generateSchemaFiles(mysor, null); |
| |
| // validate a valid instance doc against the generated employee schema |
| SchemaFactory sFact = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI); |
| Schema employeeSchema = null; |
| try { |
| employeeSchema = sFact.newSchema(mysor.schemaFiles.get(EMPLOYEE_NS)); |
| } catch (SAXException e) { |
| e.printStackTrace(); |
| fail("SchemaFactory could not create Employee schema"); |
| } |
| |
| StreamSource ss; |
| Validator validator = employeeSchema.newValidator(); |
| try { |
| ss = new StreamSource(getFile(XML_RESOURCE)); |
| validator.validate(ss); |
| } catch (Exception ex) { |
| ex.printStackTrace(); |
| fail("An unexpected exception occurred"); |
| } |
| try { |
| ss = new StreamSource(getFile(INVALID_XML_RESOURCE)); |
| validator.validate(ss); |
| } catch (Exception ex) { |
| return; |
| } |
| fail("The expected exception never occurred"); |
| } |
| |
| /** |
| * SchemaOutputResolver for writing out the generated schema. Sets |
| * the SystemID on the returned result. |
| */ |
| public static class MySystemIDSchemaOutputResolver extends SchemaOutputResolver { |
| // keep a list of processed schemas for the validation phase of the test(s) |
| public Map<String, File> schemaFiles; |
| private final File outputDir; |
| |
| public MySystemIDSchemaOutputResolver(File dir) { |
| schemaFiles = new HashMap<String, File>(); |
| outputDir = dir; |
| } |
| |
| @Override |
| public Result createOutput(String namespaceURI, String suggestedFileName) throws IOException { |
| File schemaFile = null; |
| Result res = null; |
| if (namespaceURI == null) { |
| namespaceURI = ""; |
| } else if (namespaceURI.equals(EMPLOYEE_NS)) { |
| schemaFile = new File(outputDir, "employee.xsd"); |
| } else if (namespaceURI.equals(ADDRESS_NS)) { |
| schemaFile = new File(outputDir, "address.xsd"); |
| } |
| schemaFiles.put(namespaceURI, schemaFile); |
| res = new StreamResult(schemaFile); |
| return res; |
| } |
| } |
| |
| /** |
| * Test's that the import schema location can be relativized given a |
| * source schema with no path info in the name, i.e. "employee.xsd". |
| * No exception should occur. |
| * |
| */ |
| public void testRelativeSchemaLocationWithNoSlash() { |
| File outDir = setOutDir(); |
| try { |
| Class[] jClasses = new Class[] { Address.class, Employee.class}; |
| Generator gen = new Generator(new JavaModelInputImpl(jClasses, new JavaModelImpl(Thread.currentThread().getContextClassLoader()))); |
| gen.generateSchemaFiles(outDir.getAbsolutePath(), null); |
| } catch (Exception x) { |
| x.printStackTrace(); |
| fail("An unexpected exception occurred during schema generation: " + x.getMessage()); |
| } |
| } |
| |
| public void testRelativeSchemaLocation() throws Exception { |
| JAXBContext jctx = JAXBContextFactory.createContext(new Class[] { Foo.class, Bar.class}, null ); |
| File outDir = setOutDir(); |
| MyStreamSchemaOutputResolver resolver = new MyStreamSchemaOutputResolver(outDir); |
| jctx.generateSchema(resolver); |
| Map<String, File> map = resolver.schemaFiles; |
| assertTrue("No schemas were generated", map.size() > 0); |
| File fooFile = map.get(FOO_URI); |
| File barFile = map.get(BAR_URI); |
| assertTrue("No schema was generated for Foo", fooFile != null); |
| assertTrue("No schema was generated for Bar", barFile != null); |
| |
| ExternalizedMetadataTestCases.compareSchemas(fooFile, getFile(FOO_SCHEMA)); |
| ExternalizedMetadataTestCases.compareSchemas(barFile, getFile(BAR_SCHEMA)); |
| } |
| |
| private File setOutDir() { |
| File outDir = new File(tmpdir, getName()); |
| if (!outDir.mkdirs()) { |
| for (File f : outDir.listFiles()) { |
| f.delete(); |
| } |
| } |
| return outDir; |
| } |
| |
| private static File getFile(String resourceName) { |
| return new File(Thread.currentThread().getContextClassLoader().getResource(resourceName).getPath()); |
| } |
| |
| /** |
| * 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, File> schemaFiles; |
| private final File outputDir; |
| |
| public MyStreamSchemaOutputResolver(File dir) { |
| schemaFiles = new HashMap<String, File>(); |
| outputDir = dir; |
| } |
| @Override |
| public Result createOutput(String namespaceURI, String suggestedFileName) throws IOException { |
| String filePath = this.modifyFileName(namespaceURI); |
| File file = new File(outputDir, filePath); |
| StreamResult result = new StreamResult(file); |
| result.setSystemId(file.toURI().toURL().toString()); |
| schemaFiles.put(namespaceURI, file); |
| return result; |
| } |
| |
| private String modifyFileName(String namespaceURI) throws IOException { |
| String fileName = namespaceURI.startsWith("http://") ? namespaceURI.substring(7) : namespaceURI; |
| fileName = fileName.replaceAll("/", "_"); |
| return fileName + ".xsd"; |
| } |
| } |
| } |