src/share/jaxws_classes/com/sun/tools/internal/xjc/model/Model.java

Thu, 24 May 2018 16:44:14 +0800

author
aoqi
date
Thu, 24 May 2018 16:44:14 +0800
changeset 1288
f4ace6971570
parent 0
373ffda63c9a
permissions
-rw-r--r--

Merge

     1 /*
     2  * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.tools.internal.xjc.model;
    28 import java.util.Collections;
    29 import java.util.HashMap;
    30 import java.util.HashSet;
    31 import java.util.Iterator;
    32 import java.util.LinkedHashMap;
    33 import java.util.Map;
    34 import java.util.Set;
    36 import javax.xml.bind.annotation.XmlAttribute;
    37 import javax.xml.bind.annotation.XmlNsForm;
    38 import javax.xml.bind.annotation.XmlTransient;
    39 import javax.xml.namespace.QName;
    40 import javax.xml.transform.Result;
    42 import com.sun.codemodel.internal.JClass;
    43 import com.sun.codemodel.internal.JCodeModel;
    44 import com.sun.codemodel.internal.JPackage;
    45 import com.sun.tools.internal.xjc.ErrorReceiver;
    46 import com.sun.tools.internal.xjc.Options;
    47 import com.sun.tools.internal.xjc.Plugin;
    48 import com.sun.tools.internal.xjc.api.ClassNameAllocator;
    49 import com.sun.tools.internal.xjc.generator.bean.BeanGenerator;
    50 import com.sun.tools.internal.xjc.generator.bean.ImplStructureStrategy;
    51 import com.sun.tools.internal.xjc.model.nav.NClass;
    52 import com.sun.tools.internal.xjc.model.nav.NType;
    53 import com.sun.tools.internal.xjc.model.nav.NavigatorImpl;
    54 import com.sun.tools.internal.xjc.outline.Outline;
    55 import com.sun.tools.internal.xjc.reader.xmlschema.Messages;
    56 import com.sun.tools.internal.xjc.util.ErrorReceiverFilter;
    57 import com.sun.xml.internal.bind.api.impl.NameConverter;
    58 import com.sun.xml.internal.bind.v2.model.core.Ref;
    59 import com.sun.xml.internal.bind.v2.model.core.TypeInfoSet;
    60 import com.sun.xml.internal.bind.v2.model.nav.Navigator;
    61 import com.sun.xml.internal.bind.v2.util.FlattenIterator;
    62 import com.sun.xml.internal.xsom.XSComponent;
    63 import com.sun.xml.internal.xsom.XSSchemaSet;
    65 import org.xml.sax.Locator;
    66 import org.xml.sax.SAXException;
    67 import org.xml.sax.helpers.LocatorImpl;
    69 /**
    70  * Root of the object model that represents the code that needs to be generated.
    71  *
    72  * <p>
    73  * A {@link Model} is a schema language neutral representation of the
    74  * result of a schema parsing. The back-end then works against this model
    75  * to turn this into a series of Java source code.
    76  *
    77  * @author Kohsuke Kawaguchi
    78  */
    79 public final class Model implements TypeInfoSet<NType,NClass,Void,Void>, CCustomizable {
    81     /**
    82      * Generated beans.
    83      */
    84     private final Map<NClass,CClassInfo> beans = new LinkedHashMap<NClass,CClassInfo>();
    86     /**
    87      * Generated enums.
    88      */
    89     private final Map<NClass,CEnumLeafInfo> enums = new LinkedHashMap<NClass,CEnumLeafInfo>();
    91     /**
    92      * The element mappings.
    93      */
    94     private final Map<NClass/*scope*/,Map<QName,CElementInfo>> elementMappings =
    95         new HashMap<NClass,Map<QName,CElementInfo>>();
    97     private final Iterable<? extends CElementInfo> allElements =
    98         new Iterable<CElementInfo>() {
    99             public Iterator<CElementInfo> iterator() {
   100                 return new FlattenIterator<CElementInfo>(elementMappings.values());
   101             }
   102         };
   104     /**
   105      * {@link TypeUse}s for all named types.
   106      * <p>
   107      * I really don't want to promote the notion of a 'type' in any place except in the XML Schema code,
   108      * but this needs to be exposed for JAX-RPC. A reference to a named XML type will be converted into
   109      * a reference to a Java type with annotations.
   110      */
   111     private final Map<QName,TypeUse> typeUses = new LinkedHashMap<QName, TypeUse>();
   113     /**
   114      * {@link NameConverter} to be used.
   115      */
   116     private NameConverter nameConverter;
   118     /**
   119      * Single linked list that connects all {@link CCustomizations} that belong to this model.
   120      *
   121      * @see CCustomizations#next
   122      */
   123     /*package*/ CCustomizations customizations;
   125     /**
   126      * This field controls the generation of package level annotations for s2j
   127      */
   128     private boolean packageLevelAnnotations = true;
   130     /**
   131      * If this model was built from XML Schema, this field
   132      * stores the root object of the parse schema model.
   133      * Otherwise null.
   134      *
   135      * @sine 2.1.1
   136      */
   137     public final XSSchemaSet schemaComponent;
   139     private CCustomizations gloablCustomizations = new CCustomizations();
   141     /**
   142      * @param nc
   143      *      Usually this should be set in the constructor, but we do allow this parameter
   144      *      to be initially null, and then set later.
   145      * @param schemaComponent
   146      *      The source schema model, if this is built from XSD.
   147      */
   148     public Model( Options opts, JCodeModel cm, NameConverter nc, ClassNameAllocator allocator, XSSchemaSet schemaComponent ) {
   149         this.options = opts;
   150         this.codeModel = cm;
   151         this.nameConverter = nc;
   152         this.defaultSymbolSpace = new SymbolSpace(codeModel);
   153         defaultSymbolSpace.setType(codeModel.ref(Object.class));
   155         elementMappings.put(null,new HashMap<QName,CElementInfo>());
   157         if(opts.automaticNameConflictResolution)
   158             allocator = new AutoClassNameAllocator(allocator);
   159         this.allocator = new ClassNameAllocatorWrapper(allocator);
   160         this.schemaComponent = schemaComponent;
   161         this.gloablCustomizations.setParent(this,this);
   162     }
   164     public void setNameConverter(NameConverter nameConverter) {
   165         assert this.nameConverter==null;
   166         assert nameConverter!=null;
   167         this.nameConverter = nameConverter;
   168     }
   170     /**
   171      * Gets the name converter that shall be used to parse XML names into Java names.
   172      */
   173     public final NameConverter getNameConverter() {
   174         return nameConverter;
   175     }
   177     public boolean isPackageLevelAnnotations() {
   178         return packageLevelAnnotations;
   179     }
   181     public void setPackageLevelAnnotations(boolean packageLevelAnnotations) {
   182         this.packageLevelAnnotations = packageLevelAnnotations;
   183     }
   185     /**
   186      * This model uses this code model exclusively.
   187      */
   188     @XmlTransient
   189     public final JCodeModel codeModel;
   191     /**
   192      * Command-line options used for building this model.
   193      */
   194     public final Options options;
   196     /**
   197      * True to generate serializable classes.
   198      */
   199     @XmlAttribute
   200     public boolean serializable;
   202     /**
   203      * serial version UID to be generated.
   204      *
   205      * null if not to generate serialVersionUID field.
   206      */
   207     @XmlAttribute
   208     public Long serialVersionUID;
   210     /**
   211      * If non-null, all the generated classes should eventually derive from this class.
   212      */
   213     @XmlTransient
   214     public JClass rootClass;
   216     /**
   217      * If non-null, all the generated interfaces should eventually derive from this interface.
   218      */
   219     @XmlTransient
   220     public JClass rootInterface;
   222     /**
   223      * Specifies the code generation strategy.
   224      * Must not be null.
   225      */
   226     public ImplStructureStrategy strategy = ImplStructureStrategy.BEAN_ONLY;
   228     /**
   229      * This allocator has the final say on deciding the class name.
   230      * Must not be null.
   231      *
   232      * <p>
   233      * Model classes are responsible for using the allocator.
   234      * This allocator interaction should be transparent to the user/builder
   235      * of the model.
   236      */
   237     /*package*/ final ClassNameAllocatorWrapper allocator;
   239     /**
   240      * Default ID/IDREF symbol space. Any ID/IDREF without explicit
   241      * reference to a symbol space is assumed to use this default
   242      * symbol space.
   243      */
   244     @XmlTransient
   245     public final SymbolSpace defaultSymbolSpace;
   247     /** All the defined {@link SymbolSpace}s keyed by their name. */
   248     private final Map<String,SymbolSpace> symbolSpaces = new HashMap<String,SymbolSpace>();
   250     public SymbolSpace getSymbolSpace( String name ) {
   251         SymbolSpace ss = symbolSpaces.get(name);
   252         if(ss==null)
   253             symbolSpaces.put(name,ss=new SymbolSpace(codeModel));
   254         return ss;
   255     }
   257     /**
   258      * Fully-generate the source code into the given model.
   259      *
   260      * @return
   261      *      null if there was any errors. Otherwise it returns a valid
   262      *      {@link Outline} object, which captures how the model objects
   263      *      are mapped to the generated source code.
   264      *      <p>
   265      *      Add-ons can use those information to further augment the generated
   266      *      source code.
   267      */
   268     public Outline generateCode(Options opt,ErrorReceiver receiver) {
   269         ErrorReceiverFilter ehf = new ErrorReceiverFilter(receiver);
   271         // run extensions // moved to BGMBuilder._build() - issue with hyperjaxb3
   272 //        for( Plugin ma : opt.activePlugins )
   273 //            ma.postProcessModel(this,ehf);
   275         Outline o = BeanGenerator.generate(this, ehf);
   277         try {// run extensions
   278             for( Plugin ma : opt.activePlugins )
   279                 ma.run(o,opt,ehf);
   280         } catch (SAXException e) {
   281             // fatal error. error should have been reported
   282             return null;
   283         }
   285         // check for unused plug-in customizations.
   286         // these can be only checked after the plug-ins run, so it's here.
   287         // the JAXB bindings are checked by XMLSchema's builder.
   288         Set<CCustomizations> check = new HashSet<CCustomizations>();
   289         for( CCustomizations c=customizations; c!=null; c=c.next ) {
   290             if(!check.add(c)) {
   291                 throw new AssertionError(); // detect a loop
   292             }
   293             for (CPluginCustomization p : c) {
   294                 if(!p.isAcknowledged()) {
   295                     ehf.error(
   296                         p.locator,
   297                         Messages.format(
   298                             Messages.ERR_UNACKNOWLEDGED_CUSTOMIZATION,
   299                             p.element.getNodeName()
   300                         ));
   301                     ehf.error(
   302                         c.getOwner().getLocator(),
   303                         Messages.format(
   304                             Messages.ERR_UNACKNOWLEDGED_CUSTOMIZATION_LOCATION));
   305                 }
   306             }
   307         }
   309         if(ehf.hadError())
   310             o = null;
   311         return o;
   312     }
   314     /**
   315      * Represents the "top-level binding".
   316      *
   317      * <p>
   318      * This is used to support the use of a schema inside WSDL.
   319      * For XML Schema, the top-level binding is a map from
   320      * global element declarations to its representation class.
   321      *
   322      * <p>
   323      * For other schema languages, it should follow the appendicies in
   324      * WSDL (but in practice no one would use WSDL with a schema language
   325      * other than XML Schema, so it doesn't really matter.)
   326      *
   327      * <p>
   328      * This needs to be filled by the front-end.
   329      */
   330     public final Map<QName,CClassInfo> createTopLevelBindings() {
   331         Map<QName,CClassInfo> r = new HashMap<QName,CClassInfo>();
   332         for( CClassInfo b : beans().values() ) {
   333             if(b.isElement())
   334                 r.put(b.getElementName(),b);
   335         }
   336         return r;
   337     }
   339     public Navigator<NType,NClass,Void,Void> getNavigator() {
   340         return NavigatorImpl.theInstance;
   341     }
   343     public CNonElement getTypeInfo(NType type) {
   344         CBuiltinLeafInfo leaf = CBuiltinLeafInfo.LEAVES.get(type);
   345         if(leaf!=null)      return leaf;
   347         return getClassInfo(getNavigator().asDecl(type));
   348     }
   350     public CBuiltinLeafInfo getAnyTypeInfo() {
   351         return CBuiltinLeafInfo.ANYTYPE;
   352     }
   354     public CNonElement getTypeInfo(Ref<NType,NClass> ref) {
   355         // TODO: handle XmlValueList
   356         assert !ref.valueList;
   357         return getTypeInfo(ref.type);
   358     }
   360     public Map<NClass,CClassInfo> beans() {
   361         return beans;
   362     }
   364     public Map<NClass,CEnumLeafInfo> enums() {
   365         return enums;
   366     }
   368     public Map<QName,TypeUse> typeUses() {
   369         return typeUses;
   370     }
   372     /**
   373      * No array mapping generation for XJC.
   374      */
   375     public Map<NType, ? extends CArrayInfo> arrays() {
   376         return Collections.emptyMap();
   377     }
   379     public Map<NType, ? extends CBuiltinLeafInfo> builtins() {
   380         return CBuiltinLeafInfo.LEAVES;
   381     }
   383     public CClassInfo getClassInfo(NClass t) {
   384         return beans.get(t);
   385     }
   387     public CElementInfo getElementInfo(NClass scope,QName name) {
   388         Map<QName,CElementInfo> m = elementMappings.get(scope);
   389         if(m!=null) {
   390             CElementInfo r = m.get(name);
   391             if(r!=null)     return r;
   392         }
   393         return elementMappings.get(null).get(name);
   394     }
   396     public Map<QName,CElementInfo> getElementMappings(NClass scope) {
   397         return elementMappings.get(scope);
   398     }
   400     public Iterable<? extends CElementInfo> getAllElements() {
   401         return allElements;
   402     }
   404     /**
   405      * @deprecated
   406      *      Always return null. Perhaps you are interested in {@link #schemaComponent}?
   407      */
   408     public XSComponent getSchemaComponent() {
   409         return null;
   410     }
   412     /**
   413      * @deprecated
   414      *      No line number available for the "root" component.
   415      */
   416     public Locator getLocator() {
   417         LocatorImpl r = new LocatorImpl();
   418         r.setLineNumber(-1);
   419         r.setColumnNumber(-1);
   420         return r;
   421     }
   423     /**
   424      * Gets the global customizations.
   425      */
   426     public CCustomizations getCustomizations() {
   427         return gloablCustomizations;
   428     }
   430     /**
   431      * Not implemented in the compile-time model.
   432      */
   433     public Map<String, String> getXmlNs(String namespaceUri) {
   434         return Collections.emptyMap();
   435     }
   437     public Map<String, String> getSchemaLocations() {
   438         return Collections.emptyMap();
   439     }
   441     public XmlNsForm getElementFormDefault(String nsUri) {
   442         throw new UnsupportedOperationException();
   443     }
   445     public XmlNsForm getAttributeFormDefault(String nsUri) {
   446         throw new UnsupportedOperationException();
   447     }
   449     public void dump(Result out) {
   450         // TODO
   451         throw new UnsupportedOperationException();
   452     }
   454     /*package*/ void add( CEnumLeafInfo e ) {
   455         enums.put( e.getClazz(), e );
   456     }
   458     /*package*/ void add( CClassInfo ci ) {
   459         beans.put( ci.getClazz(), ci );
   460     }
   462     /*package*/ void add( CElementInfo ei ) {
   463         NClass clazz = null;
   464         if(ei.getScope()!=null)
   465             clazz = ei.getScope().getClazz();
   467         Map<QName,CElementInfo> m = elementMappings.get(clazz);
   468         if(m==null)
   469             elementMappings.put(clazz,m=new HashMap<QName,CElementInfo>());
   470         m.put(ei.getElementName(),ei);
   471     }
   474     private final Map<JPackage,CClassInfoParent.Package> cache = new HashMap<JPackage,CClassInfoParent.Package>();
   476     public CClassInfoParent.Package getPackage(JPackage pkg) {
   477         CClassInfoParent.Package r = cache.get(pkg);
   478         if(r==null)
   479             cache.put(pkg,r=new CClassInfoParent.Package(pkg));
   480         return r;
   481     }
   483     /*package*/ static final Locator EMPTY_LOCATOR;
   485     static {
   486         LocatorImpl l = new LocatorImpl();
   487         l.setColumnNumber(-1);
   488         l.setLineNumber(-1);
   489         EMPTY_LOCATOR = l;
   490     }
   491 }

mercurial