1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/jaxws_classes/com/sun/tools/internal/xjc/model/CClassInfo.java Wed Apr 27 01:27:09 2016 +0800 1.3 @@ -0,0 +1,501 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package com.sun.tools.internal.xjc.model; 1.30 + 1.31 +import java.util.ArrayList; 1.32 +import java.util.Collection; 1.33 +import java.util.HashSet; 1.34 +import java.util.Iterator; 1.35 +import java.util.List; 1.36 +import java.util.Set; 1.37 + 1.38 +import javax.xml.bind.annotation.XmlElement; 1.39 +import javax.xml.bind.annotation.XmlID; 1.40 +import javax.xml.bind.annotation.XmlIDREF; 1.41 +import javax.xml.bind.annotation.XmlRootElement; 1.42 +import javax.xml.namespace.QName; 1.43 + 1.44 +import com.sun.codemodel.internal.JClass; 1.45 +import com.sun.codemodel.internal.JCodeModel; 1.46 +import com.sun.codemodel.internal.JPackage; 1.47 +import com.sun.istack.internal.Nullable; 1.48 +import com.sun.tools.internal.xjc.Language; 1.49 +import com.sun.tools.internal.xjc.model.nav.NClass; 1.50 +import com.sun.tools.internal.xjc.model.nav.NType; 1.51 +import com.sun.tools.internal.xjc.outline.Aspect; 1.52 +import com.sun.tools.internal.xjc.outline.Outline; 1.53 +import com.sun.tools.internal.xjc.reader.Ring; 1.54 +import com.sun.tools.internal.xjc.reader.xmlschema.BGMBuilder; 1.55 +import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIFactoryMethod; 1.56 +import com.sun.xml.internal.bind.v2.model.core.ClassInfo; 1.57 +import com.sun.xml.internal.bind.v2.model.core.Element; 1.58 +import com.sun.xml.internal.xsom.XSComponent; 1.59 + 1.60 +import org.xml.sax.Locator; 1.61 + 1.62 +/** 1.63 + * Mutable {@link ClassInfo} represenatation. 1.64 + * 1.65 + * <p> 1.66 + * Schema parsers build these objects. 1.67 + * 1.68 + * @author Kohsuke Kawaguchi 1.69 + */ 1.70 +public final class CClassInfo extends AbstractCElement implements ClassInfo<NType,NClass>, CClassInfoParent, CClass, NClass { 1.71 + 1.72 + @XmlIDREF 1.73 + private CClass baseClass; 1.74 + 1.75 + /** 1.76 + * List of all subclasses, together with {@link #nextSibling}. 1.77 + * 1.78 + * If this class has no sub-class, this field is null. Otherwise, 1.79 + * this field points to a sub-class of this class. From there you can enumerate 1.80 + * all the sub-classes by using {@link #nextSibling}. 1.81 + */ 1.82 + private CClassInfo firstSubclass; 1.83 + 1.84 + /** 1.85 + * @see #firstSubclass 1.86 + */ 1.87 + private CClassInfo nextSibling = null; 1.88 + 1.89 + /** 1.90 + * @see #getTypeName() 1.91 + */ 1.92 + private final QName typeName; 1.93 + 1.94 + /** 1.95 + * Custom {@link #getSqueezedName() squeezed name}, if any. 1.96 + */ 1.97 + private /*almost final*/ @Nullable String squeezedName; 1.98 + 1.99 + /** 1.100 + * If this class also gets {@link XmlRootElement}, the class name. 1.101 + */ 1.102 + private final @Nullable QName elementName; 1.103 + 1.104 + private boolean isOrdered = true; 1.105 + 1.106 + private final List<CPropertyInfo> properties = new ArrayList<CPropertyInfo>(); 1.107 + 1.108 + /** 1.109 + * TODO: revisit this design. 1.110 + * we should at least do a basic encapsulation to avoid careless 1.111 + * mistakes. Maybe we should even differ the javadoc generation 1.112 + * by queueing runners. 1.113 + */ 1.114 + public String javadoc; 1.115 + 1.116 + @XmlIDREF 1.117 + private final CClassInfoParent parent; 1.118 + 1.119 + /** 1.120 + * short name. 1.121 + */ 1.122 + public final String shortName; 1.123 + 1.124 + /** 1.125 + * Optional user-specified implementation override class. 1.126 + */ 1.127 + private @Nullable String implClass; 1.128 + 1.129 + /** 1.130 + * The {@link Model} object to which this bean belongs. 1.131 + */ 1.132 + public final Model model; 1.133 + 1.134 + /** 1.135 + * @see #hasAttributeWildcard() 1.136 + */ 1.137 + private boolean hasAttributeWildcard; 1.138 + 1.139 + 1.140 + public CClassInfo(Model model,JPackage pkg, String shortName, Locator location, QName typeName, QName elementName, XSComponent source, CCustomizations customizations) { 1.141 + this(model,model.getPackage(pkg),shortName,location,typeName,elementName,source,customizations); 1.142 + } 1.143 + 1.144 + public CClassInfo(Model model,CClassInfoParent p, String shortName, Locator location, QName typeName, QName elementName, XSComponent source, CCustomizations customizations) { 1.145 + super(model,source,location,customizations); 1.146 + this.model = model; 1.147 + this.parent = p; 1.148 + this.shortName = model.allocator.assignClassName(parent,shortName); 1.149 + this.typeName = typeName; 1.150 + this.elementName = elementName; 1.151 + 1.152 + Language schemaLanguage = model.options.getSchemaLanguage(); 1.153 + if ((schemaLanguage != null) && 1.154 + (schemaLanguage.equals(Language.XMLSCHEMA) || schemaLanguage.equals(Language.WSDL))) { 1.155 + BIFactoryMethod factoryMethod = Ring.get(BGMBuilder.class).getBindInfo(source).get(BIFactoryMethod.class); 1.156 + if(factoryMethod!=null) { 1.157 + factoryMethod.markAsAcknowledged(); 1.158 + this.squeezedName = factoryMethod.name; 1.159 + } 1.160 + } 1.161 + 1.162 + model.add(this); 1.163 + } 1.164 + 1.165 + public CClassInfo(Model model,JCodeModel cm, String fullName, Locator location, QName typeName, QName elementName, XSComponent source, CCustomizations customizations) { 1.166 + super(model,source,location,customizations); 1.167 + this.model = model; 1.168 + int idx = fullName.indexOf('.'); 1.169 + if(idx<0) { 1.170 + this.parent = model.getPackage(cm.rootPackage()); 1.171 + this.shortName = model.allocator.assignClassName(parent,fullName); 1.172 + } else { 1.173 + this.parent = model.getPackage(cm._package(fullName.substring(0,idx))); 1.174 + this.shortName = model.allocator.assignClassName(parent,fullName.substring(idx+1)); 1.175 + } 1.176 + this.typeName = typeName; 1.177 + this.elementName = elementName; 1.178 + 1.179 + model.add(this); 1.180 + } 1.181 + 1.182 + public boolean hasAttributeWildcard() { 1.183 + return hasAttributeWildcard; 1.184 + } 1.185 + 1.186 + public void hasAttributeWildcard(boolean hasAttributeWildcard) { 1.187 + this.hasAttributeWildcard = hasAttributeWildcard; 1.188 + } 1.189 + 1.190 + public boolean hasSubClasses() { 1.191 + return firstSubclass!=null; 1.192 + } 1.193 + 1.194 + /** 1.195 + * Returns true if a new attribute wildcard property needs to be 1.196 + * declared on this class. 1.197 + */ 1.198 + public boolean declaresAttributeWildcard() { 1.199 + return hasAttributeWildcard && !inheritsAttributeWildcard(); 1.200 + } 1.201 + 1.202 + /** 1.203 + * Returns true if this class inherits a wildcard attribute property 1.204 + * from its ancestor classes. 1.205 + */ 1.206 + public boolean inheritsAttributeWildcard() { 1.207 + if (getRefBaseClass() != null) { 1.208 + CClassRef cref = (CClassRef)baseClass; 1.209 + if (cref.getSchemaComponent().getForeignAttributes().size() > 0) { 1.210 + return true; 1.211 + } 1.212 + } else { 1.213 + for( CClassInfo c=getBaseClass(); c!=null; c=c.getBaseClass() ) { 1.214 + if(c.hasAttributeWildcard) 1.215 + return true; 1.216 + } 1.217 + } 1.218 + return false; 1.219 + } 1.220 + 1.221 + 1.222 + public NClass getClazz() { 1.223 + return this; 1.224 + } 1.225 + 1.226 + public CClassInfo getScope() { 1.227 + return null; 1.228 + } 1.229 + 1.230 + @XmlID 1.231 + public String getName() { 1.232 + return fullName(); 1.233 + } 1.234 + 1.235 + /** 1.236 + * Returns the "squeezed name" of this bean token. 1.237 + * <p> 1.238 + * The squeezed name of a bean is the concatenation of 1.239 + * the names of its outer classes and itself. 1.240 + * <p> 1.241 + * Thus if the bean is "org.acme.foo.Bean", then the squeezed name is "Bean", 1.242 + * if the bean is "org.acme.foo.Outer1.Outer2.Bean", then "Outer1Outer2Bean". 1.243 + * <p> 1.244 + * This is used by the code generator 1.245 + */ 1.246 + @XmlElement 1.247 + public String getSqueezedName() { 1.248 + if (squeezedName != null) return squeezedName; 1.249 + return calcSqueezedName.onBean(this); 1.250 + } 1.251 + 1.252 + private static final CClassInfoParent.Visitor<String> calcSqueezedName = new Visitor<String>() { 1.253 + public String onBean(CClassInfo bean) { 1.254 + return bean.parent.accept(this)+bean.shortName; 1.255 + } 1.256 + 1.257 + public String onElement(CElementInfo element) { 1.258 + return element.parent.accept(this)+element.shortName(); 1.259 + } 1.260 + 1.261 + public String onPackage(JPackage pkg) { 1.262 + return ""; 1.263 + } 1.264 + }; 1.265 + 1.266 + /** 1.267 + * Returns a mutable list. 1.268 + */ 1.269 + public List<CPropertyInfo> getProperties() { 1.270 + return properties; 1.271 + } 1.272 + 1.273 + public boolean hasValueProperty() { 1.274 + throw new UnsupportedOperationException(); 1.275 + } 1.276 + 1.277 + /** 1.278 + * Gets a propery by name. 1.279 + */ 1.280 + public CPropertyInfo getProperty(String name) { 1.281 + // TODO: does this method need to be fast? 1.282 + for( CPropertyInfo p : properties ) 1.283 + if(p.getName(false).equals(name)) 1.284 + return p; 1.285 + return null; 1.286 + } 1.287 + 1.288 + public boolean hasProperties() { 1.289 + return !getProperties().isEmpty(); 1.290 + } 1.291 + 1.292 + public boolean isElement() { 1.293 + return elementName!=null; 1.294 + } 1.295 + 1.296 + /** 1.297 + * Guaranteed to return this. 1.298 + */ 1.299 + @Deprecated 1.300 + public CNonElement getInfo() { 1.301 + return this; 1.302 + } 1.303 + 1.304 + public Element<NType,NClass> asElement() { 1.305 + if(isElement()) 1.306 + return this; 1.307 + else 1.308 + return null; 1.309 + } 1.310 + 1.311 + public boolean isOrdered() { 1.312 + return isOrdered; 1.313 + } 1.314 + 1.315 + /** 1.316 + * @deprecated 1.317 + * if you are calling this method directly, you must be doing something wrong. 1.318 + */ 1.319 + public boolean isFinal() { 1.320 + return false; 1.321 + } 1.322 + 1.323 + public void setOrdered(boolean value) { 1.324 + isOrdered = value; 1.325 + } 1.326 + 1.327 + public QName getElementName() { 1.328 + return elementName; 1.329 + } 1.330 + 1.331 + public QName getTypeName() { 1.332 + return typeName; 1.333 + } 1.334 + 1.335 + public boolean isSimpleType() { 1.336 + throw new UnsupportedOperationException(); 1.337 + } 1.338 + 1.339 + /** 1.340 + * Returns the FQCN of this bean. 1.341 + */ 1.342 + public String fullName() { 1.343 + String r = parent.fullName(); 1.344 + if(r.length()==0) return shortName; 1.345 + else return r+'.'+shortName; 1.346 + } 1.347 + 1.348 + public CClassInfoParent parent() { 1.349 + return parent; 1.350 + } 1.351 + 1.352 + public void setUserSpecifiedImplClass(String implClass) { 1.353 + assert this.implClass==null; 1.354 + assert implClass!=null; 1.355 + this.implClass = implClass; 1.356 + } 1.357 + 1.358 + public String getUserSpecifiedImplClass() { 1.359 + return implClass; 1.360 + } 1.361 + 1.362 + 1.363 + /** 1.364 + * Adds a new property. 1.365 + */ 1.366 + public void addProperty(CPropertyInfo prop) { 1.367 + if(prop.ref().isEmpty()) 1.368 + // this property isn't contributing anything 1.369 + // this happens when you try to map an empty sequence to a property 1.370 + return; 1.371 + prop.setParent(this); 1.372 + properties.add(prop); 1.373 + } 1.374 + 1.375 + /** 1.376 + * This method accepts both {@link CClassInfo} (which means the base class 1.377 + * is also generated), or {@link CClassRef} (which means the base class is 1.378 + * already generated and simply referenced.) 1.379 + * 1.380 + * The latter is treated somewhat special --- from the rest of the model 1.381 + * this external base class is invisible. This modeling might need more 1.382 + * thoughts to get right. 1.383 + */ 1.384 + public void setBaseClass(CClass base) { 1.385 + assert baseClass==null; 1.386 + assert base!=null; 1.387 + baseClass = base; 1.388 + 1.389 + assert nextSibling==null; 1.390 + if (base instanceof CClassInfo) { 1.391 + CClassInfo realBase = (CClassInfo) base; 1.392 + this.nextSibling = realBase.firstSubclass; 1.393 + realBase.firstSubclass = this; 1.394 + } 1.395 + } 1.396 + 1.397 + /** 1.398 + * This inherited version returns null if this class extends from {@link CClassRef}. 1.399 + * 1.400 + * @see #getRefBaseClass() 1.401 + */ 1.402 + public CClassInfo getBaseClass() { 1.403 + if (baseClass instanceof CClassInfo) { 1.404 + return (CClassInfo) baseClass; 1.405 + } else { 1.406 + return null; 1.407 + } 1.408 + } 1.409 + 1.410 + public CClassRef getRefBaseClass() { 1.411 + if (baseClass instanceof CClassRef) { 1.412 + return (CClassRef) baseClass; 1.413 + } else { 1.414 + return null; 1.415 + } 1.416 + } 1.417 + 1.418 + /** 1.419 + * Enumerates all the sub-classes of this class. 1.420 + */ 1.421 + public Iterator<CClassInfo> listSubclasses() { 1.422 + return new Iterator<CClassInfo>() { 1.423 + CClassInfo cur = firstSubclass; 1.424 + public boolean hasNext() { 1.425 + return cur!=null; 1.426 + } 1.427 + 1.428 + public CClassInfo next() { 1.429 + CClassInfo r = cur; 1.430 + cur = cur.nextSibling; 1.431 + return r; 1.432 + } 1.433 + 1.434 + public void remove() { 1.435 + throw new UnsupportedOperationException(); 1.436 + } 1.437 + }; 1.438 + } 1.439 + 1.440 + public CClassInfo getSubstitutionHead() { 1.441 + CClassInfo c=getBaseClass(); 1.442 + while(c!=null && !c.isElement()) 1.443 + c=c.getBaseClass(); 1.444 + return c; 1.445 + } 1.446 + 1.447 + 1.448 + /** 1.449 + * Interfaces to be implemented. 1.450 + * Lazily constructed. 1.451 + */ 1.452 + private Set<JClass> _implements = null; 1.453 + 1.454 + public void _implements(JClass c) { 1.455 + if(_implements==null) 1.456 + _implements = new HashSet<JClass>(); 1.457 + _implements.add(c); 1.458 + } 1.459 + 1.460 + 1.461 + /** Constructor declarations. array of {@link Constructor}s. */ 1.462 + private final List<Constructor> constructors = new ArrayList<Constructor>(1); 1.463 + 1.464 + /** Creates a new constructor declaration and adds it. */ 1.465 + public void addConstructor( String... fieldNames ) { 1.466 + constructors.add(new Constructor(fieldNames)); 1.467 + } 1.468 + 1.469 + /** list all constructor declarations. */ 1.470 + public Collection<? extends Constructor> getConstructors() { 1.471 + return constructors; 1.472 + } 1.473 + 1.474 + public final <T> T accept(Visitor<T> visitor) { 1.475 + return visitor.onBean(this); 1.476 + } 1.477 + 1.478 + public JPackage getOwnerPackage() { 1.479 + return parent.getOwnerPackage(); 1.480 + } 1.481 + 1.482 + public final NClass getType() { 1.483 + return this; 1.484 + } 1.485 + 1.486 + public final JClass toType(Outline o, Aspect aspect) { 1.487 + switch(aspect) { 1.488 + case IMPLEMENTATION: 1.489 + return o.getClazz(this).implRef; 1.490 + case EXPOSED: 1.491 + return o.getClazz(this).ref; 1.492 + default: 1.493 + throw new IllegalStateException(); 1.494 + } 1.495 + } 1.496 + 1.497 + public boolean isBoxedType() { 1.498 + return false; 1.499 + } 1.500 + 1.501 + public String toString() { 1.502 + return fullName(); 1.503 + } 1.504 +}