diff -r 000000000000 -r 373ffda63c9a src/share/jaxws_classes/com/sun/tools/internal/xjc/model/Model.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/jaxws_classes/com/sun/tools/internal/xjc/model/Model.java Wed Apr 27 01:27:09 2016 +0800 @@ -0,0 +1,491 @@ +/* + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.tools.internal.xjc.model; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlNsForm; +import javax.xml.bind.annotation.XmlTransient; +import javax.xml.namespace.QName; +import javax.xml.transform.Result; + +import com.sun.codemodel.internal.JClass; +import com.sun.codemodel.internal.JCodeModel; +import com.sun.codemodel.internal.JPackage; +import com.sun.tools.internal.xjc.ErrorReceiver; +import com.sun.tools.internal.xjc.Options; +import com.sun.tools.internal.xjc.Plugin; +import com.sun.tools.internal.xjc.api.ClassNameAllocator; +import com.sun.tools.internal.xjc.generator.bean.BeanGenerator; +import com.sun.tools.internal.xjc.generator.bean.ImplStructureStrategy; +import com.sun.tools.internal.xjc.model.nav.NClass; +import com.sun.tools.internal.xjc.model.nav.NType; +import com.sun.tools.internal.xjc.model.nav.NavigatorImpl; +import com.sun.tools.internal.xjc.outline.Outline; +import com.sun.tools.internal.xjc.reader.xmlschema.Messages; +import com.sun.tools.internal.xjc.util.ErrorReceiverFilter; +import com.sun.xml.internal.bind.api.impl.NameConverter; +import com.sun.xml.internal.bind.v2.model.core.Ref; +import com.sun.xml.internal.bind.v2.model.core.TypeInfoSet; +import com.sun.xml.internal.bind.v2.model.nav.Navigator; +import com.sun.xml.internal.bind.v2.util.FlattenIterator; +import com.sun.xml.internal.xsom.XSComponent; +import com.sun.xml.internal.xsom.XSSchemaSet; + +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.LocatorImpl; + +/** + * Root of the object model that represents the code that needs to be generated. + * + *

+ * A {@link Model} is a schema language neutral representation of the + * result of a schema parsing. The back-end then works against this model + * to turn this into a series of Java source code. + * + * @author Kohsuke Kawaguchi + */ +public final class Model implements TypeInfoSet, CCustomizable { + + /** + * Generated beans. + */ + private final Map beans = new LinkedHashMap(); + + /** + * Generated enums. + */ + private final Map enums = new LinkedHashMap(); + + /** + * The element mappings. + */ + private final Map> elementMappings = + new HashMap>(); + + private final Iterable allElements = + new Iterable() { + public Iterator iterator() { + return new FlattenIterator(elementMappings.values()); + } + }; + + /** + * {@link TypeUse}s for all named types. + *

+ * I really don't want to promote the notion of a 'type' in any place except in the XML Schema code, + * but this needs to be exposed for JAX-RPC. A reference to a named XML type will be converted into + * a reference to a Java type with annotations. + */ + private final Map typeUses = new LinkedHashMap(); + + /** + * {@link NameConverter} to be used. + */ + private NameConverter nameConverter; + + /** + * Single linked list that connects all {@link CCustomizations} that belong to this model. + * + * @see CCustomizations#next + */ + /*package*/ CCustomizations customizations; + + /** + * This field controls the generation of package level annotations for s2j + */ + private boolean packageLevelAnnotations = true; + + /** + * If this model was built from XML Schema, this field + * stores the root object of the parse schema model. + * Otherwise null. + * + * @sine 2.1.1 + */ + public final XSSchemaSet schemaComponent; + + private CCustomizations gloablCustomizations = new CCustomizations(); + + /** + * @param nc + * Usually this should be set in the constructor, but we do allow this parameter + * to be initially null, and then set later. + * @param schemaComponent + * The source schema model, if this is built from XSD. + */ + public Model( Options opts, JCodeModel cm, NameConverter nc, ClassNameAllocator allocator, XSSchemaSet schemaComponent ) { + this.options = opts; + this.codeModel = cm; + this.nameConverter = nc; + this.defaultSymbolSpace = new SymbolSpace(codeModel); + defaultSymbolSpace.setType(codeModel.ref(Object.class)); + + elementMappings.put(null,new HashMap()); + + if(opts.automaticNameConflictResolution) + allocator = new AutoClassNameAllocator(allocator); + this.allocator = new ClassNameAllocatorWrapper(allocator); + this.schemaComponent = schemaComponent; + this.gloablCustomizations.setParent(this,this); + } + + public void setNameConverter(NameConverter nameConverter) { + assert this.nameConverter==null; + assert nameConverter!=null; + this.nameConverter = nameConverter; + } + + /** + * Gets the name converter that shall be used to parse XML names into Java names. + */ + public final NameConverter getNameConverter() { + return nameConverter; + } + + public boolean isPackageLevelAnnotations() { + return packageLevelAnnotations; + } + + public void setPackageLevelAnnotations(boolean packageLevelAnnotations) { + this.packageLevelAnnotations = packageLevelAnnotations; + } + + /** + * This model uses this code model exclusively. + */ + @XmlTransient + public final JCodeModel codeModel; + + /** + * Command-line options used for building this model. + */ + public final Options options; + + /** + * True to generate serializable classes. + */ + @XmlAttribute + public boolean serializable; + + /** + * serial version UID to be generated. + * + * null if not to generate serialVersionUID field. + */ + @XmlAttribute + public Long serialVersionUID; + + /** + * If non-null, all the generated classes should eventually derive from this class. + */ + @XmlTransient + public JClass rootClass; + + /** + * If non-null, all the generated interfaces should eventually derive from this interface. + */ + @XmlTransient + public JClass rootInterface; + + /** + * Specifies the code generation strategy. + * Must not be null. + */ + public ImplStructureStrategy strategy = ImplStructureStrategy.BEAN_ONLY; + + /** + * This allocator has the final say on deciding the class name. + * Must not be null. + * + *

+ * Model classes are responsible for using the allocator. + * This allocator interaction should be transparent to the user/builder + * of the model. + */ + /*package*/ final ClassNameAllocatorWrapper allocator; + + /** + * Default ID/IDREF symbol space. Any ID/IDREF without explicit + * reference to a symbol space is assumed to use this default + * symbol space. + */ + @XmlTransient + public final SymbolSpace defaultSymbolSpace; + + /** All the defined {@link SymbolSpace}s keyed by their name. */ + private final Map symbolSpaces = new HashMap(); + + public SymbolSpace getSymbolSpace( String name ) { + SymbolSpace ss = symbolSpaces.get(name); + if(ss==null) + symbolSpaces.put(name,ss=new SymbolSpace(codeModel)); + return ss; + } + + /** + * Fully-generate the source code into the given model. + * + * @return + * null if there was any errors. Otherwise it returns a valid + * {@link Outline} object, which captures how the model objects + * are mapped to the generated source code. + *

+ * Add-ons can use those information to further augment the generated + * source code. + */ + public Outline generateCode(Options opt,ErrorReceiver receiver) { + ErrorReceiverFilter ehf = new ErrorReceiverFilter(receiver); + + // run extensions // moved to BGMBuilder._build() - issue with hyperjaxb3 +// for( Plugin ma : opt.activePlugins ) +// ma.postProcessModel(this,ehf); + + Outline o = BeanGenerator.generate(this, ehf); + + try {// run extensions + for( Plugin ma : opt.activePlugins ) + ma.run(o,opt,ehf); + } catch (SAXException e) { + // fatal error. error should have been reported + return null; + } + + // check for unused plug-in customizations. + // these can be only checked after the plug-ins run, so it's here. + // the JAXB bindings are checked by XMLSchema's builder. + Set check = new HashSet(); + for( CCustomizations c=customizations; c!=null; c=c.next ) { + if(!check.add(c)) { + throw new AssertionError(); // detect a loop + } + for (CPluginCustomization p : c) { + if(!p.isAcknowledged()) { + ehf.error( + p.locator, + Messages.format( + Messages.ERR_UNACKNOWLEDGED_CUSTOMIZATION, + p.element.getNodeName() + )); + ehf.error( + c.getOwner().getLocator(), + Messages.format( + Messages.ERR_UNACKNOWLEDGED_CUSTOMIZATION_LOCATION)); + } + } + } + + if(ehf.hadError()) + o = null; + return o; + } + + /** + * Represents the "top-level binding". + * + *

+ * This is used to support the use of a schema inside WSDL. + * For XML Schema, the top-level binding is a map from + * global element declarations to its representation class. + * + *

+ * For other schema languages, it should follow the appendicies in + * WSDL (but in practice no one would use WSDL with a schema language + * other than XML Schema, so it doesn't really matter.) + * + *

+ * This needs to be filled by the front-end. + */ + public final Map createTopLevelBindings() { + Map r = new HashMap(); + for( CClassInfo b : beans().values() ) { + if(b.isElement()) + r.put(b.getElementName(),b); + } + return r; + } + + public Navigator getNavigator() { + return NavigatorImpl.theInstance; + } + + public CNonElement getTypeInfo(NType type) { + CBuiltinLeafInfo leaf = CBuiltinLeafInfo.LEAVES.get(type); + if(leaf!=null) return leaf; + + return getClassInfo(getNavigator().asDecl(type)); + } + + public CBuiltinLeafInfo getAnyTypeInfo() { + return CBuiltinLeafInfo.ANYTYPE; + } + + public CNonElement getTypeInfo(Ref ref) { + // TODO: handle XmlValueList + assert !ref.valueList; + return getTypeInfo(ref.type); + } + + public Map beans() { + return beans; + } + + public Map enums() { + return enums; + } + + public Map typeUses() { + return typeUses; + } + + /** + * No array mapping generation for XJC. + */ + public Map arrays() { + return Collections.emptyMap(); + } + + public Map builtins() { + return CBuiltinLeafInfo.LEAVES; + } + + public CClassInfo getClassInfo(NClass t) { + return beans.get(t); + } + + public CElementInfo getElementInfo(NClass scope,QName name) { + Map m = elementMappings.get(scope); + if(m!=null) { + CElementInfo r = m.get(name); + if(r!=null) return r; + } + return elementMappings.get(null).get(name); + } + + public Map getElementMappings(NClass scope) { + return elementMappings.get(scope); + } + + public Iterable getAllElements() { + return allElements; + } + + /** + * @deprecated + * Always return null. Perhaps you are interested in {@link #schemaComponent}? + */ + public XSComponent getSchemaComponent() { + return null; + } + + /** + * @deprecated + * No line number available for the "root" component. + */ + public Locator getLocator() { + LocatorImpl r = new LocatorImpl(); + r.setLineNumber(-1); + r.setColumnNumber(-1); + return r; + } + + /** + * Gets the global customizations. + */ + public CCustomizations getCustomizations() { + return gloablCustomizations; + } + + /** + * Not implemented in the compile-time model. + */ + public Map getXmlNs(String namespaceUri) { + return Collections.emptyMap(); + } + + public Map getSchemaLocations() { + return Collections.emptyMap(); + } + + public XmlNsForm getElementFormDefault(String nsUri) { + throw new UnsupportedOperationException(); + } + + public XmlNsForm getAttributeFormDefault(String nsUri) { + throw new UnsupportedOperationException(); + } + + public void dump(Result out) { + // TODO + throw new UnsupportedOperationException(); + } + + /*package*/ void add( CEnumLeafInfo e ) { + enums.put( e.getClazz(), e ); + } + + /*package*/ void add( CClassInfo ci ) { + beans.put( ci.getClazz(), ci ); + } + + /*package*/ void add( CElementInfo ei ) { + NClass clazz = null; + if(ei.getScope()!=null) + clazz = ei.getScope().getClazz(); + + Map m = elementMappings.get(clazz); + if(m==null) + elementMappings.put(clazz,m=new HashMap()); + m.put(ei.getElementName(),ei); + } + + + private final Map cache = new HashMap(); + + public CClassInfoParent.Package getPackage(JPackage pkg) { + CClassInfoParent.Package r = cache.get(pkg); + if(r==null) + cache.put(pkg,r=new CClassInfoParent.Package(pkg)); + return r; + } + + /*package*/ static final Locator EMPTY_LOCATOR; + + static { + LocatorImpl l = new LocatorImpl(); + l.setColumnNumber(-1); + l.setLineNumber(-1); + EMPTY_LOCATOR = l; + } +}