All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.jaxb.compiler.Generator Maven / Gradle / Ivy

There is a newer version: 4.0.2
Show newest version
/*
 * Copyright (c) 1998, 2018 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.jaxb.compiler;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Map.Entry;

import javax.xml.XMLConstants;
import javax.xml.bind.SchemaOutputResolver;
import javax.xml.namespace.QName;

import org.eclipse.persistence.core.sessions.CoreProject;
import org.eclipse.persistence.internal.oxm.Constants;
import org.eclipse.persistence.internal.oxm.mappings.Descriptor;
import org.eclipse.persistence.internal.oxm.schema.SchemaModelProject;
import org.eclipse.persistence.internal.oxm.schema.model.Schema;
import org.eclipse.persistence.jaxb.TypeMappingInfo;
import org.eclipse.persistence.jaxb.javamodel.Helper;
import org.eclipse.persistence.jaxb.javamodel.JavaClass;
import org.eclipse.persistence.jaxb.javamodel.JavaModelInput;
import org.eclipse.persistence.jaxb.javamodel.reflection.JavaModelInputImpl;
import org.eclipse.persistence.jaxb.xmlmodel.XmlBindings;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLContext;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.sessions.Project;

/**
 * INTERNAL:
 *  

Purpose:The purpose of this class is to act as an entry point into the * TopLink JAXB 2.0 Generation framework *

Responsibilities:

    *
  • Run initial processing on a list of classes to create TypeInfo meta data
  • *
  • Provide API to generate Schema Files
  • *
  • Provide API to generate a TopLink Project
  • *
  • Act as an integration point with WebServices
  • *
*

This class acts as an entry point into JAXB 2.0 Generation. A Generator is created with a * specific set of JAXB 2.0 Annotated classes and then performs actions on those, such as * generating schema files, or generating TopLink Projects. Additional information is returned * from the schema generation methods as a means of integration with WebServices. * * @author mmacivor * @since Oracle TopLink 11.1.1.0.0 * @see AnnotationsProcessor * @see MappingsGenerator * @see SchemaGenerator */ public class Generator { private AnnotationsProcessor annotationsProcessor; private SchemaGenerator schemaGenerator; private MappingsGenerator mappingsGenerator; private Helper helper; private Map typeToTypeMappingInfo; /** * This constructor creates a Helper using the JavaModelInput * instance's JavaModel. Annotations are processed here as well. * * @param jModelInput */ public Generator(JavaModelInput jModelInput) { helper = new Helper(jModelInput.getJavaModel()); configureFacetsGeneration(jModelInput); annotationsProcessor = new AnnotationsProcessor(helper); schemaGenerator = new SchemaGenerator(helper); mappingsGenerator = new MappingsGenerator(helper); annotationsProcessor.processClassesAndProperties(jModelInput.getJavaClasses(), null); } /** * This constructor will process and apply the given XmlBindings as appropriate. Classes * declared in the bindings will be amalgamated with any classes in the JavaModelInput. * * If xmlBindings is null or empty, AnnotationsProcessor will be used to process * annotations as per usual. * * @param jModelInput * @param xmlBindings map of XmlBindings keyed on package name * @param cLoader */ public Generator(JavaModelInput jModelInput, Map xmlBindings, ClassLoader cLoader, String defaultTargetNamespace, boolean enableXmlAccessorFactory) { helper = new Helper(jModelInput.getJavaModel()); configureFacetsGeneration(jModelInput); annotationsProcessor = new AnnotationsProcessor(helper); annotationsProcessor.setXmlAccessorFactorySupport(enableXmlAccessorFactory); annotationsProcessor.setDefaultTargetNamespace(defaultTargetNamespace); schemaGenerator = new SchemaGenerator(helper); mappingsGenerator = new MappingsGenerator(helper); if (xmlBindings != null && !xmlBindings.isEmpty()) { new XMLProcessor(xmlBindings).processXML(annotationsProcessor, jModelInput, null, null); } else { annotationsProcessor.processClassesAndProperties(jModelInput.getJavaClasses(), null); } } /** * This constructor creates a Helper using the JavaModelInput * instance's JavaModel and a map of javaclasses that were generated from Type objects. * Annotations are processed here as well. * * @param jModelInput */ public Generator(JavaModelInput jModelInput, TypeMappingInfo[] typeMappingInfos, JavaClass[] javaClasses, Map typeToTypeMappingInfo, String defaultTargetNamespace) { helper = new Helper(jModelInput.getJavaModel()); configureFacetsGeneration(jModelInput); annotationsProcessor = new AnnotationsProcessor(helper); annotationsProcessor.setDefaultTargetNamespace(defaultTargetNamespace); schemaGenerator = new SchemaGenerator(helper); mappingsGenerator = new MappingsGenerator(helper); this.typeToTypeMappingInfo = typeToTypeMappingInfo; annotationsProcessor.processClassesAndProperties(javaClasses, typeMappingInfos); } /** * This constructor will process and apply the given XmlBindings as appropriate. Classes * declared in the bindings will be amalgamated with any classes in the JavaModelInput. * * If xmlBindings is null or empty, AnnotationsProcessor will be used to process * annotations as per usual. * * @param jModelInput * @param defaultTargetNamespace * @param enableXmlAccessorFactory * @param javaClasses * @param typeMappingInfos * @param typeToTypeMappingInfo * @param xmlBindings map of XmlBindings keyed on package name * @param cLoader */ public Generator(JavaModelInput jModelInput, TypeMappingInfo[] typeMappingInfos, JavaClass[] javaClasses, Map typeToTypeMappingInfo, Map xmlBindings, ClassLoader cLoader, String defaultTargetNamespace, boolean enableXmlAccessorFactory) { helper = new Helper(jModelInput.getJavaModel()); configureFacetsGeneration(jModelInput); annotationsProcessor = new AnnotationsProcessor(helper); annotationsProcessor.setXmlAccessorFactorySupport(enableXmlAccessorFactory); annotationsProcessor.setDefaultTargetNamespace(defaultTargetNamespace); schemaGenerator = new SchemaGenerator(helper); mappingsGenerator = new MappingsGenerator(helper); this.typeToTypeMappingInfo = typeToTypeMappingInfo; if (xmlBindings != null && !xmlBindings.isEmpty()) { new XMLProcessor(xmlBindings).processXML(annotationsProcessor, jModelInput, typeMappingInfos, javaClasses); } else { annotationsProcessor.processClassesAndProperties(javaClasses, typeMappingInfos); } } /** * This event is called when mappings generation is completed, * and provides a chance to deference anything that is no longer * needed (to reduce the memory footprint of this object). */ public void postInitialize() { mappingsGenerator = null; annotationsProcessor.postInitialize(); schemaGenerator = null; } /** * */ public boolean hasMarshalCallbacks() { return getMarshalCallbacks()!=null && !getMarshalCallbacks().isEmpty(); } public boolean hasUnmarshalCallbacks() { return getUnmarshalCallbacks()!=null && !getUnmarshalCallbacks().isEmpty(); } public CoreProject generateProject() throws Exception { mappingsGenerator.getClassToGeneratedClasses().putAll(annotationsProcessor.getArrayClassesToGeneratedClasses()); CoreProject p = mappingsGenerator.generateProject(annotationsProcessor.getTypeInfoClasses(), annotationsProcessor.getTypeInfos(), annotationsProcessor.getUserDefinedSchemaTypes(), annotationsProcessor.getPackageToPackageInfoMappings(), annotationsProcessor.getGlobalElements(), annotationsProcessor.getLocalElements(), annotationsProcessor.getTypeMappingInfosToGeneratedClasses(), annotationsProcessor.getTypeMappingInfoToAdapterClasses(),annotationsProcessor.isDefaultNamespaceAllowed()); annotationsProcessor.getArrayClassesToGeneratedClasses().putAll(mappingsGenerator.getClassToGeneratedClasses()); return p; } public java.util.Collection generateSchema() { schemaGenerator.generateSchema(annotationsProcessor.getTypeInfoClasses(), annotationsProcessor.getTypeInfos(), annotationsProcessor.getUserDefinedSchemaTypes(), annotationsProcessor.getPackageToPackageInfoMappings(), null, annotationsProcessor.getArrayClassesToGeneratedClasses()); return schemaGenerator.getAllSchemas(); } public Map generateSchemaFiles(String schemaPath, Map additionalGlobalElements) throws FileNotFoundException { // process any additional global elements processAdditionalElements(additionalGlobalElements, annotationsProcessor); schemaGenerator.generateSchema(annotationsProcessor.getTypeInfoClasses(), annotationsProcessor.getTypeInfos(), annotationsProcessor.getUserDefinedSchemaTypes(), annotationsProcessor.getPackageToPackageInfoMappings(), annotationsProcessor.getGlobalElements(), annotationsProcessor.getArrayClassesToGeneratedClasses()); CoreProject proj = new SchemaModelProject(); XMLContext context = new XMLContext((Project)proj); XMLMarshaller marshaller = context.createMarshaller(); Descriptor schemaDescriptor = (Descriptor)proj.getDescriptor(Schema.class); java.util.Collection schemas = schemaGenerator.getAllSchemas(); for(Schema schema : schemas) { File file = new File(schemaPath + "/" + schema.getName()); NamespaceResolver schemaNamespaces = schema.getNamespaceResolver(); schemaNamespaces.put(Constants.SCHEMA_PREFIX, XMLConstants.W3C_XML_SCHEMA_NS_URI); schemaDescriptor.setNamespaceResolver(schemaNamespaces); marshaller.marshal(schema, new FileOutputStream(file)); } return schemaGenerator.getSchemaTypeInfo(); } public Map generateSchemaFiles(SchemaOutputResolver outputResolver, Map additionalGlobalElements) { // process any additional global elements processAdditionalElements(additionalGlobalElements, annotationsProcessor); schemaGenerator.generateSchema(annotationsProcessor.getTypeInfoClasses(), annotationsProcessor.getTypeInfos(), annotationsProcessor.getUserDefinedSchemaTypes(), annotationsProcessor.getPackageToPackageInfoMappings(), annotationsProcessor.getGlobalElements(), annotationsProcessor.getArrayClassesToGeneratedClasses(), outputResolver); CoreProject proj = new SchemaModelProject(); XMLContext context = new XMLContext((Project)proj); XMLMarshaller marshaller = context.createMarshaller(); Descriptor schemaDescriptor = (Descriptor)proj.getDescriptor(Schema.class); java.util.Collection schemas = schemaGenerator.getAllSchemas(); for(Schema schema : schemas) { try { NamespaceResolver schemaNamespaces = schema.getNamespaceResolver(); schemaNamespaces.put(Constants.SCHEMA_PREFIX, XMLConstants.W3C_XML_SCHEMA_NS_URI); schemaDescriptor.setNamespaceResolver(schemaNamespaces); // make sure we don't call into the provided output resolver more than once javax.xml.transform.Result target; if (schema.hasResult()) { target = schema.getResult(); } else { target = outputResolver.createOutput(schema.getTargetNamespace(), schema.getName()); } marshaller.marshal(schema, target); } catch (IOException ex) { ex.printStackTrace(); } } return schemaGenerator.getSchemaTypeInfo(); } /** * Convenience method that processes a given map of QName-Type entries. For each an ElementDeclaration * is created and added to the given AnnotationsProcessor instance's map of global elements. * * It is assumed that the map of QName-Type entries contains Type instances that are either a Class or * a ParameterizedType. * * @param additionalGlobalElements * @param annotationsProcessor */ private void processAdditionalElements(Map additionalGlobalElements, AnnotationsProcessor annotationsProcessor) { if (additionalGlobalElements != null) { ElementDeclaration declaration; for(Entry entry : additionalGlobalElements.entrySet()) { QName key = entry.getKey(); Type type = entry.getValue(); TypeMappingInfo tmi = null; if(this.typeToTypeMappingInfo != null) { tmi = this.typeToTypeMappingInfo.get(type); } if(tmi != null) { if(annotationsProcessor.getTypeMappingInfosToGeneratedClasses().get(tmi) != null) { type = annotationsProcessor.getTypeMappingInfosToGeneratedClasses().get(tmi); } } JavaClass jClass = null; if (type instanceof Class) { Class tClass = (Class) type; jClass = helper.getJavaClass(tClass); } // if no type is available don't do anything if (jClass != null) { declaration = new ElementDeclaration(key, jClass, jClass.getQualifiedName(), false); annotationsProcessor.getGlobalElements().put(key, declaration); } } } } public Map getUnmarshalCallbacks() { return annotationsProcessor.getUnmarshalCallbacks(); } public Map getMarshalCallbacks() { return annotationsProcessor.getMarshalCallbacks(); } public MappingsGenerator getMappingsGenerator() { return this.mappingsGenerator; } public AnnotationsProcessor getAnnotationsProcessor() { return annotationsProcessor; } public void setTypeToTypeMappingInfo(Map typesToTypeMapping) { this.typeToTypeMappingInfo = typesToTypeMapping; } public Map getTypeToTypeMappingInfo() { return this.typeToTypeMappingInfo; } private void configureFacetsGeneration(JavaModelInput jModelInput) { if (jModelInput instanceof JavaModelInputImpl) { helper.setFacets(((JavaModelInputImpl) jModelInput).isFacets()); } else { String msg = "MOXy BV: Facets generation could not be configured. EclipseLink''s JavaModelInputImpl was " + "not detected, instead JavaModelInput is of class: {0}"; AbstractSessionLog.getLog().log(SessionLog.WARNING, SessionLog.MOXY, msg, new Object[] {jModelInput.getClass()}, false); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy