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

Wed, 27 Apr 2016 01:27:09 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:27:09 +0800
changeset 0
373ffda63c9a
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/jaxws/
changeset: 657:d47a47f961ee
tag: jdk8u25-b17

     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.ArrayList;
    29 import java.util.Collection;
    30 import java.util.HashSet;
    31 import java.util.Iterator;
    32 import java.util.List;
    33 import java.util.Set;
    35 import javax.xml.bind.annotation.XmlElement;
    36 import javax.xml.bind.annotation.XmlID;
    37 import javax.xml.bind.annotation.XmlIDREF;
    38 import javax.xml.bind.annotation.XmlRootElement;
    39 import javax.xml.namespace.QName;
    41 import com.sun.codemodel.internal.JClass;
    42 import com.sun.codemodel.internal.JCodeModel;
    43 import com.sun.codemodel.internal.JPackage;
    44 import com.sun.istack.internal.Nullable;
    45 import com.sun.tools.internal.xjc.Language;
    46 import com.sun.tools.internal.xjc.model.nav.NClass;
    47 import com.sun.tools.internal.xjc.model.nav.NType;
    48 import com.sun.tools.internal.xjc.outline.Aspect;
    49 import com.sun.tools.internal.xjc.outline.Outline;
    50 import com.sun.tools.internal.xjc.reader.Ring;
    51 import com.sun.tools.internal.xjc.reader.xmlschema.BGMBuilder;
    52 import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIFactoryMethod;
    53 import com.sun.xml.internal.bind.v2.model.core.ClassInfo;
    54 import com.sun.xml.internal.bind.v2.model.core.Element;
    55 import com.sun.xml.internal.xsom.XSComponent;
    57 import org.xml.sax.Locator;
    59 /**
    60  * Mutable {@link ClassInfo} represenatation.
    61  *
    62  * <p>
    63  * Schema parsers build these objects.
    64  *
    65  * @author Kohsuke Kawaguchi
    66  */
    67 public final class CClassInfo extends AbstractCElement implements ClassInfo<NType,NClass>, CClassInfoParent, CClass, NClass {
    69     @XmlIDREF
    70     private CClass baseClass;
    72     /**
    73      * List of all subclasses, together with {@link #nextSibling}.
    74      *
    75      * If this class has no sub-class, this field is null. Otherwise,
    76      * this field points to a sub-class of this class. From there you can enumerate
    77      * all the sub-classes by using {@link #nextSibling}.
    78      */
    79     private CClassInfo firstSubclass;
    81     /**
    82      * @see #firstSubclass
    83      */
    84     private CClassInfo nextSibling = null;
    86     /**
    87      * @see #getTypeName()
    88      */
    89     private final QName typeName;
    91     /**
    92      * Custom {@link #getSqueezedName() squeezed name}, if any.
    93      */
    94     private /*almost final*/ @Nullable String squeezedName;
    96     /**
    97      * If this class also gets {@link XmlRootElement}, the class name.
    98      */
    99     private final @Nullable QName elementName;
   101     private boolean isOrdered = true;
   103     private final List<CPropertyInfo> properties = new ArrayList<CPropertyInfo>();
   105     /**
   106      * TODO: revisit this design.
   107      * we should at least do a basic encapsulation to avoid careless
   108      * mistakes. Maybe we should even differ the javadoc generation
   109      * by queueing runners.
   110      */
   111     public String javadoc;
   113     @XmlIDREF
   114     private final CClassInfoParent parent;
   116     /**
   117      * short name.
   118      */
   119     public final String shortName;
   121     /**
   122      * Optional user-specified implementation override class.
   123      */
   124     private @Nullable String implClass;
   126     /**
   127      * The {@link Model} object to which this bean belongs.
   128      */
   129     public final Model model;
   131     /**
   132      * @see #hasAttributeWildcard()
   133      */
   134     private boolean hasAttributeWildcard;
   137     public CClassInfo(Model model,JPackage pkg, String shortName, Locator location, QName typeName, QName elementName, XSComponent source, CCustomizations customizations) {
   138         this(model,model.getPackage(pkg),shortName,location,typeName,elementName,source,customizations);
   139     }
   141     public CClassInfo(Model model,CClassInfoParent p, String shortName, Locator location, QName typeName, QName elementName, XSComponent source, CCustomizations customizations) {
   142         super(model,source,location,customizations);
   143         this.model = model;
   144         this.parent = p;
   145         this.shortName = model.allocator.assignClassName(parent,shortName);
   146         this.typeName = typeName;
   147         this.elementName = elementName;
   149         Language schemaLanguage = model.options.getSchemaLanguage();
   150         if ((schemaLanguage != null) &&
   151             (schemaLanguage.equals(Language.XMLSCHEMA) || schemaLanguage.equals(Language.WSDL))) {
   152             BIFactoryMethod factoryMethod = Ring.get(BGMBuilder.class).getBindInfo(source).get(BIFactoryMethod.class);
   153             if(factoryMethod!=null) {
   154                 factoryMethod.markAsAcknowledged();
   155                 this.squeezedName = factoryMethod.name;
   156             }
   157         }
   159         model.add(this);
   160     }
   162     public CClassInfo(Model model,JCodeModel cm, String fullName, Locator location, QName typeName, QName elementName, XSComponent source, CCustomizations customizations) {
   163         super(model,source,location,customizations);
   164         this.model = model;
   165         int idx = fullName.indexOf('.');
   166         if(idx<0) {
   167             this.parent = model.getPackage(cm.rootPackage());
   168             this.shortName = model.allocator.assignClassName(parent,fullName);
   169         } else {
   170             this.parent = model.getPackage(cm._package(fullName.substring(0,idx)));
   171             this.shortName = model.allocator.assignClassName(parent,fullName.substring(idx+1));
   172         }
   173         this.typeName = typeName;
   174         this.elementName = elementName;
   176         model.add(this);
   177     }
   179     public boolean hasAttributeWildcard() {
   180         return hasAttributeWildcard;
   181     }
   183     public void hasAttributeWildcard(boolean hasAttributeWildcard) {
   184         this.hasAttributeWildcard = hasAttributeWildcard;
   185     }
   187     public boolean hasSubClasses() {
   188         return firstSubclass!=null;
   189     }
   191     /**
   192      * Returns true if a new attribute wildcard property needs to be
   193      * declared on this class.
   194      */
   195     public boolean declaresAttributeWildcard() {
   196         return hasAttributeWildcard && !inheritsAttributeWildcard();
   197     }
   199     /**
   200      * Returns true if this class inherits a wildcard attribute property
   201      * from its ancestor classes.
   202      */
   203     public boolean inheritsAttributeWildcard() {
   204         if (getRefBaseClass() != null) {
   205             CClassRef cref = (CClassRef)baseClass;
   206             if (cref.getSchemaComponent().getForeignAttributes().size() > 0) {
   207                 return true;
   208             }
   209         } else {
   210             for( CClassInfo c=getBaseClass(); c!=null; c=c.getBaseClass() ) {
   211                 if(c.hasAttributeWildcard)
   212                     return true;
   213             }
   214         }
   215         return false;
   216     }
   219     public NClass getClazz() {
   220         return this;
   221     }
   223     public CClassInfo getScope() {
   224         return null;
   225     }
   227     @XmlID
   228     public String getName() {
   229         return fullName();
   230     }
   232     /**
   233      * Returns the "squeezed name" of this bean token.
   234      * <p>
   235      * The squeezed name of a bean is the concatenation of
   236      * the names of its outer classes and itself.
   237      * <p>
   238      * Thus if the bean is "org.acme.foo.Bean", then the squeezed name is "Bean",
   239      * if the bean is "org.acme.foo.Outer1.Outer2.Bean", then "Outer1Outer2Bean".
   240      * <p>
   241      * This is used by the code generator
   242      */
   243     @XmlElement
   244     public String getSqueezedName() {
   245         if (squeezedName != null)  return squeezedName;
   246         return calcSqueezedName.onBean(this);
   247     }
   249     private static final CClassInfoParent.Visitor<String> calcSqueezedName = new Visitor<String>() {
   250         public String onBean(CClassInfo bean) {
   251             return bean.parent.accept(this)+bean.shortName;
   252         }
   254         public String onElement(CElementInfo element) {
   255             return element.parent.accept(this)+element.shortName();
   256         }
   258         public String onPackage(JPackage pkg) {
   259             return "";
   260         }
   261     };
   263     /**
   264      * Returns a mutable list.
   265      */
   266     public List<CPropertyInfo> getProperties() {
   267         return properties;
   268     }
   270     public boolean hasValueProperty() {
   271         throw new UnsupportedOperationException();
   272     }
   274     /**
   275      * Gets a propery by name.
   276      */
   277     public CPropertyInfo getProperty(String name) {
   278         // TODO: does this method need to be fast?
   279         for( CPropertyInfo p : properties )
   280             if(p.getName(false).equals(name))
   281                 return p;
   282         return null;
   283     }
   285     public boolean hasProperties() {
   286         return !getProperties().isEmpty();
   287     }
   289     public boolean isElement() {
   290         return elementName!=null;
   291     }
   293     /**
   294      * Guaranteed to return this.
   295      */
   296     @Deprecated
   297     public CNonElement getInfo() {
   298         return this;
   299     }
   301     public Element<NType,NClass> asElement() {
   302         if(isElement())
   303             return this;
   304         else
   305             return null;
   306     }
   308     public boolean isOrdered() {
   309         return isOrdered;
   310     }
   312     /**
   313      * @deprecated
   314      *      if you are calling this method directly, you must be doing something wrong.
   315      */
   316     public boolean isFinal() {
   317         return false;
   318     }
   320     public void setOrdered(boolean value) {
   321         isOrdered = value;
   322     }
   324     public QName getElementName() {
   325         return elementName;
   326     }
   328     public QName getTypeName() {
   329         return typeName;
   330     }
   332     public boolean isSimpleType() {
   333         throw new UnsupportedOperationException();
   334     }
   336     /**
   337      * Returns the FQCN of this bean.
   338      */
   339     public String fullName() {
   340         String r = parent.fullName();
   341         if(r.length()==0)   return shortName;
   342         else                return r+'.'+shortName;
   343     }
   345     public CClassInfoParent parent() {
   346         return parent;
   347     }
   349     public void setUserSpecifiedImplClass(String implClass) {
   350         assert this.implClass==null;
   351         assert implClass!=null;
   352         this.implClass = implClass;
   353     }
   355     public String getUserSpecifiedImplClass() {
   356         return implClass;
   357     }
   360     /**
   361      * Adds a new property.
   362      */
   363     public void addProperty(CPropertyInfo prop) {
   364         if(prop.ref().isEmpty())
   365             // this property isn't contributing anything
   366             // this happens when you try to map an empty sequence to a property
   367             return;
   368         prop.setParent(this);
   369         properties.add(prop);
   370     }
   372     /**
   373      * This method accepts both {@link CClassInfo} (which means the base class
   374      * is also generated), or {@link CClassRef} (which means the base class is
   375      * already generated and simply referenced.)
   376      *
   377      * The latter is treated somewhat special --- from the rest of the model
   378      * this external base class is invisible. This modeling might need more
   379      * thoughts to get right.
   380      */
   381     public void setBaseClass(CClass base) {
   382         assert baseClass==null;
   383         assert base!=null;
   384         baseClass = base;
   386         assert nextSibling==null;
   387         if (base instanceof CClassInfo) {
   388             CClassInfo realBase = (CClassInfo) base;
   389             this.nextSibling = realBase.firstSubclass;
   390             realBase.firstSubclass = this;
   391         }
   392     }
   394     /**
   395      * This inherited version returns null if this class extends from {@link CClassRef}.
   396      *
   397      * @see #getRefBaseClass()
   398      */
   399     public CClassInfo getBaseClass() {
   400         if (baseClass instanceof CClassInfo) {
   401             return (CClassInfo) baseClass;
   402         } else {
   403             return null;
   404         }
   405     }
   407     public CClassRef getRefBaseClass() {
   408         if (baseClass instanceof CClassRef) {
   409             return (CClassRef) baseClass;
   410         } else {
   411             return null;
   412         }
   413     }
   415     /**
   416      * Enumerates all the sub-classes of this class.
   417      */
   418     public Iterator<CClassInfo> listSubclasses() {
   419         return new Iterator<CClassInfo>() {
   420             CClassInfo cur = firstSubclass;
   421             public boolean hasNext() {
   422                 return cur!=null;
   423             }
   425             public CClassInfo next() {
   426                 CClassInfo r = cur;
   427                 cur = cur.nextSibling;
   428                 return r;
   429             }
   431             public void remove() {
   432                 throw new UnsupportedOperationException();
   433             }
   434         };
   435     }
   437     public CClassInfo getSubstitutionHead() {
   438         CClassInfo c=getBaseClass();
   439         while(c!=null && !c.isElement())
   440             c=c.getBaseClass();
   441         return c;
   442     }
   445     /**
   446      * Interfaces to be implemented.
   447      * Lazily constructed.
   448      */
   449     private Set<JClass> _implements = null;
   451     public void _implements(JClass c) {
   452         if(_implements==null)
   453             _implements = new HashSet<JClass>();
   454         _implements.add(c);
   455     }
   458     /** Constructor declarations. array of {@link Constructor}s. */
   459     private final List<Constructor> constructors = new ArrayList<Constructor>(1);
   461     /** Creates a new constructor declaration and adds it. */
   462     public void addConstructor( String... fieldNames ) {
   463         constructors.add(new Constructor(fieldNames));
   464     }
   466     /** list all constructor declarations. */
   467     public Collection<? extends Constructor> getConstructors() {
   468         return constructors;
   469     }
   471     public final <T> T accept(Visitor<T> visitor) {
   472         return visitor.onBean(this);
   473     }
   475     public JPackage getOwnerPackage() {
   476         return parent.getOwnerPackage();
   477     }
   479     public final NClass getType() {
   480         return this;
   481     }
   483     public final JClass toType(Outline o, Aspect aspect) {
   484         switch(aspect) {
   485         case IMPLEMENTATION:
   486             return o.getClazz(this).implRef;
   487         case EXPOSED:
   488             return o.getClazz(this).ref;
   489         default:
   490             throw new IllegalStateException();
   491         }
   492     }
   494     public boolean isBoxedType() {
   495         return false;
   496     }
   498     public String toString() {
   499         return fullName();
   500     }
   501 }

mercurial