src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/xmlschema/RawTypeSetBuilder.java

Tue, 09 Apr 2013 14:51:13 +0100

author
alanb
date
Tue, 09 Apr 2013 14:51:13 +0100
changeset 368
0989ad8c0860
parent 0
373ffda63c9a
permissions
-rw-r--r--

8010393: Update JAX-WS RI to 2.2.9-b12941
Reviewed-by: alanb, erikj
Contributed-by: miroslav.kos@oracle.com, martin.grebac@oracle.com

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.tools.internal.xjc.reader.xmlschema;
aoqi@0 27
aoqi@0 28 import java.util.LinkedHashSet;
aoqi@0 29 import java.util.Set;
aoqi@0 30
aoqi@0 31 import javax.activation.MimeType;
aoqi@0 32 import javax.xml.namespace.QName;
aoqi@0 33
aoqi@0 34 import com.sun.tools.internal.xjc.model.CAdapter;
aoqi@0 35 import com.sun.tools.internal.xjc.model.CClass;
aoqi@0 36 import com.sun.tools.internal.xjc.model.CClassInfo;
aoqi@0 37 import com.sun.tools.internal.xjc.model.CCustomizations;
aoqi@0 38 import com.sun.tools.internal.xjc.model.CElement;
aoqi@0 39 import com.sun.tools.internal.xjc.model.CElementInfo;
aoqi@0 40 import com.sun.tools.internal.xjc.model.CElementPropertyInfo;
aoqi@0 41 import com.sun.tools.internal.xjc.model.CReferencePropertyInfo;
aoqi@0 42 import com.sun.tools.internal.xjc.model.CTypeRef;
aoqi@0 43 import com.sun.tools.internal.xjc.model.Model;
aoqi@0 44 import com.sun.tools.internal.xjc.model.Multiplicity;
aoqi@0 45 import com.sun.tools.internal.xjc.model.TypeUse;
aoqi@0 46 import com.sun.tools.internal.xjc.reader.RawTypeSet;
aoqi@0 47 import com.sun.tools.internal.xjc.reader.Ring;
aoqi@0 48 import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIDom;
aoqi@0 49 import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIGlobalBinding;
aoqi@0 50 import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIXSubstitutable;
aoqi@0 51 import com.sun.xml.internal.bind.v2.model.core.ID;
aoqi@0 52 import com.sun.xml.internal.bind.v2.model.core.WildcardMode;
aoqi@0 53 import com.sun.xml.internal.xsom.XSElementDecl;
aoqi@0 54 import com.sun.xml.internal.xsom.XSModelGroup;
aoqi@0 55 import com.sun.xml.internal.xsom.XSModelGroupDecl;
aoqi@0 56 import com.sun.xml.internal.xsom.XSParticle;
aoqi@0 57 import com.sun.xml.internal.xsom.XSWildcard;
aoqi@0 58 import com.sun.xml.internal.xsom.visitor.XSTermVisitor;
aoqi@0 59
aoqi@0 60 /**
aoqi@0 61 * Builds {@link RawTypeSet} for XML Schema.
aoqi@0 62 *
aoqi@0 63 * @author Kohsuke Kawaguchi
aoqi@0 64 */
aoqi@0 65 public class RawTypeSetBuilder implements XSTermVisitor {
aoqi@0 66 /**
aoqi@0 67 * @param optional
aoqi@0 68 * if this whole property is optional due to the
aoqi@0 69 * occurrence constraints on ancestors, set this to true.
aoqi@0 70 * this will prevent the primitive types to be generated.
aoqi@0 71 */
aoqi@0 72 public static RawTypeSet build( XSParticle p, boolean optional ) {
aoqi@0 73 RawTypeSetBuilder rtsb = new RawTypeSetBuilder();
aoqi@0 74 rtsb.particle(p);
aoqi@0 75 Multiplicity mul = MultiplicityCounter.theInstance.particle(p);
aoqi@0 76
aoqi@0 77 if(optional)
aoqi@0 78 mul = mul.makeOptional();
aoqi@0 79
aoqi@0 80 return new RawTypeSet(rtsb.refs,mul);
aoqi@0 81 }
aoqi@0 82
aoqi@0 83 /**
aoqi@0 84 * To avoid declaring the same element twice for a content model like
aoqi@0 85 * (A,A), we keep track of element names here while we are building up
aoqi@0 86 * this instance.
aoqi@0 87 */
aoqi@0 88 private final Set<QName> elementNames = new LinkedHashSet<QName>();
aoqi@0 89
aoqi@0 90 private final Set<RawTypeSet.Ref> refs = new LinkedHashSet<RawTypeSet.Ref>();
aoqi@0 91
aoqi@0 92 protected final BGMBuilder builder = Ring.get(BGMBuilder.class);
aoqi@0 93
aoqi@0 94 public RawTypeSetBuilder() {}
aoqi@0 95
aoqi@0 96
aoqi@0 97 /**
aoqi@0 98 * Gets the {@link RawTypeSet.Ref}s that were built.
aoqi@0 99 */
aoqi@0 100 public Set<RawTypeSet.Ref> getRefs() {
aoqi@0 101 return refs;
aoqi@0 102 }
aoqi@0 103
aoqi@0 104 /**
aoqi@0 105 * Build up {@link #refs} and compute the total multiplicity of this {@link RawTypeSet.Ref} set.
aoqi@0 106 */
aoqi@0 107 private void particle( XSParticle p ) {
aoqi@0 108 // if the DOM customization is present, bind it like a wildcard
aoqi@0 109 BIDom dom = builder.getLocalDomCustomization(p);
aoqi@0 110 if(dom!=null) {
aoqi@0 111 dom.markAsAcknowledged();
aoqi@0 112 refs.add(new WildcardRef(WildcardMode.SKIP));
aoqi@0 113 } else {
aoqi@0 114 p.getTerm().visit(this);
aoqi@0 115 }
aoqi@0 116 }
aoqi@0 117
aoqi@0 118 public void wildcard(XSWildcard wc) {
aoqi@0 119 refs.add(new WildcardRef(wc));
aoqi@0 120 }
aoqi@0 121
aoqi@0 122 public void modelGroupDecl(XSModelGroupDecl decl) {
aoqi@0 123 modelGroup(decl.getModelGroup());
aoqi@0 124 }
aoqi@0 125
aoqi@0 126 public void modelGroup(XSModelGroup group) {
aoqi@0 127 for( XSParticle p : group.getChildren())
aoqi@0 128 particle(p);
aoqi@0 129 }
aoqi@0 130
aoqi@0 131 public void elementDecl(XSElementDecl decl) {
aoqi@0 132
aoqi@0 133 QName n = BGMBuilder.getName(decl);
aoqi@0 134 if(elementNames.add(n)) {
aoqi@0 135 CElement elementBean = Ring.get(ClassSelector.class).bindToType(decl,null);
aoqi@0 136 if(elementBean==null)
aoqi@0 137 refs.add(new XmlTypeRef(decl));
aoqi@0 138 else {
aoqi@0 139 // yikes!
aoqi@0 140 if(elementBean instanceof CClass)
aoqi@0 141 refs.add(new CClassRef(decl,(CClass)elementBean));
aoqi@0 142 else
aoqi@0 143 refs.add(new CElementInfoRef(decl,(CElementInfo)elementBean));
aoqi@0 144 }
aoqi@0 145 }
aoqi@0 146 }
aoqi@0 147
aoqi@0 148 /**
aoqi@0 149 * Reference to a wildcard.
aoqi@0 150 */
aoqi@0 151 public static final class WildcardRef extends RawTypeSet.Ref {
aoqi@0 152 private final WildcardMode mode;
aoqi@0 153
aoqi@0 154 WildcardRef(XSWildcard wildcard) {
aoqi@0 155 this.mode = getMode(wildcard);
aoqi@0 156 }
aoqi@0 157 WildcardRef(WildcardMode mode) {
aoqi@0 158 this.mode = mode;
aoqi@0 159 }
aoqi@0 160
aoqi@0 161 private static WildcardMode getMode(XSWildcard wildcard) {
aoqi@0 162 switch(wildcard.getMode()) {
aoqi@0 163 case XSWildcard.LAX:
aoqi@0 164 return WildcardMode.LAX;
aoqi@0 165 case XSWildcard.STRTICT:
aoqi@0 166 return WildcardMode.STRICT;
aoqi@0 167 case XSWildcard.SKIP:
aoqi@0 168 return WildcardMode.SKIP;
aoqi@0 169 default:
aoqi@0 170 throw new IllegalStateException();
aoqi@0 171 }
aoqi@0 172 }
aoqi@0 173
aoqi@0 174 protected CTypeRef toTypeRef(CElementPropertyInfo ep) {
aoqi@0 175 // we don't allow a mapping to typeRef if the wildcard is present
aoqi@0 176 throw new IllegalStateException();
aoqi@0 177 }
aoqi@0 178
aoqi@0 179 protected void toElementRef(CReferencePropertyInfo prop) {
aoqi@0 180 prop.setWildcard(mode);
aoqi@0 181 }
aoqi@0 182
aoqi@0 183 protected RawTypeSet.Mode canBeType(RawTypeSet parent) {
aoqi@0 184 return RawTypeSet.Mode.MUST_BE_REFERENCE;
aoqi@0 185 }
aoqi@0 186
aoqi@0 187 protected boolean isListOfValues() {
aoqi@0 188 return false;
aoqi@0 189 }
aoqi@0 190
aoqi@0 191 protected ID id() {
aoqi@0 192 return ID.NONE;
aoqi@0 193 }
aoqi@0 194 }
aoqi@0 195
aoqi@0 196 /**
aoqi@0 197 * Reference to a class that maps from an element.
aoqi@0 198 */
aoqi@0 199 public static final class CClassRef extends RawTypeSet.Ref {
aoqi@0 200 public final CClass target;
aoqi@0 201 public final XSElementDecl decl;
aoqi@0 202
aoqi@0 203 CClassRef(XSElementDecl decl, CClass target) {
aoqi@0 204 this.decl = decl;
aoqi@0 205 this.target = target;
aoqi@0 206 }
aoqi@0 207
aoqi@0 208 protected CTypeRef toTypeRef(CElementPropertyInfo ep) {
aoqi@0 209 return new CTypeRef(target,decl);
aoqi@0 210 }
aoqi@0 211
aoqi@0 212 protected void toElementRef(CReferencePropertyInfo prop) {
aoqi@0 213 prop.getElements().add(target);
aoqi@0 214 }
aoqi@0 215
aoqi@0 216 protected RawTypeSet.Mode canBeType(RawTypeSet parent) {
aoqi@0 217 // if element substitution can occur, no way it can be mapped to a list of types
aoqi@0 218 if(decl.getSubstitutables().size()>1)
aoqi@0 219 return RawTypeSet.Mode.MUST_BE_REFERENCE;
aoqi@0 220
aoqi@0 221 return RawTypeSet.Mode.SHOULD_BE_TYPEREF;
aoqi@0 222 }
aoqi@0 223
aoqi@0 224 protected boolean isListOfValues() {
aoqi@0 225 return false;
aoqi@0 226 }
aoqi@0 227
aoqi@0 228 protected ID id() {
aoqi@0 229 return ID.NONE;
aoqi@0 230 }
aoqi@0 231 }
aoqi@0 232
aoqi@0 233 /**
aoqi@0 234 * Reference to a class that maps from an element.
aoqi@0 235 */
aoqi@0 236 public final class CElementInfoRef extends RawTypeSet.Ref {
aoqi@0 237 public final CElementInfo target;
aoqi@0 238 public final XSElementDecl decl;
aoqi@0 239
aoqi@0 240 CElementInfoRef(XSElementDecl decl, CElementInfo target) {
aoqi@0 241 this.decl = decl;
aoqi@0 242 this.target = target;
aoqi@0 243 }
aoqi@0 244
aoqi@0 245 protected CTypeRef toTypeRef(CElementPropertyInfo ep) {
aoqi@0 246 assert !target.isCollection();
aoqi@0 247 CAdapter a = target.getProperty().getAdapter();
aoqi@0 248 if(a!=null && ep!=null) ep.setAdapter(a);
aoqi@0 249
aoqi@0 250 return new CTypeRef(target.getContentType(),decl);
aoqi@0 251 }
aoqi@0 252
aoqi@0 253 protected void toElementRef(CReferencePropertyInfo prop) {
aoqi@0 254 prop.getElements().add(target);
aoqi@0 255 }
aoqi@0 256
aoqi@0 257 protected RawTypeSet.Mode canBeType(RawTypeSet parent) {
aoqi@0 258 // if element substitution can occur, no way it can be mapped to a list of types
aoqi@0 259 if(decl.getSubstitutables().size()>1)
aoqi@0 260 return RawTypeSet.Mode.MUST_BE_REFERENCE;
aoqi@0 261 // BIXSubstitutable also simulates this effect. Useful for separate compilation
aoqi@0 262 BIXSubstitutable subst = builder.getBindInfo(decl).get(BIXSubstitutable.class);
aoqi@0 263 if(subst!=null) {
aoqi@0 264 subst.markAsAcknowledged();
aoqi@0 265 return RawTypeSet.Mode.MUST_BE_REFERENCE;
aoqi@0 266 }
aoqi@0 267
aoqi@0 268 // we have no place to put an adater if this thing maps to a type
aoqi@0 269 CElementPropertyInfo p = target.getProperty();
aoqi@0 270 // if we have an adapter or IDness, which requires special
aoqi@0 271 // annotation, and there's more than one element,
aoqi@0 272 // we have no place to put the special annotation, so we need JAXBElement.
aoqi@0 273 if((parent.refs.size()>1 || !parent.mul.isAtMostOnce()) && p.id()!=ID.NONE)
aoqi@0 274 return RawTypeSet.Mode.MUST_BE_REFERENCE;
aoqi@0 275 if(parent.refs.size() > 1 && p.getAdapter() != null)
aoqi@0 276 return RawTypeSet.Mode.MUST_BE_REFERENCE;
aoqi@0 277
aoqi@0 278 if(target.hasClass())
aoqi@0 279 // if the CElementInfo was explicitly bound to a class (which happen if and only if
aoqi@0 280 // the user requested so, then map that to reference property so that the user sees a class
aoqi@0 281 return RawTypeSet.Mode.CAN_BE_TYPEREF;
aoqi@0 282 else
aoqi@0 283 return RawTypeSet.Mode.SHOULD_BE_TYPEREF;
aoqi@0 284 }
aoqi@0 285
aoqi@0 286 protected boolean isListOfValues() {
aoqi@0 287 return target.getProperty().isValueList();
aoqi@0 288 }
aoqi@0 289
aoqi@0 290 protected ID id() {
aoqi@0 291 return target.getProperty().id();
aoqi@0 292 }
aoqi@0 293
aoqi@0 294 @Override
aoqi@0 295 protected MimeType getExpectedMimeType() {
aoqi@0 296 return target.getProperty().getExpectedMimeType();
aoqi@0 297 }
aoqi@0 298 }
aoqi@0 299
aoqi@0 300 /**
aoqi@0 301 * References to a type. Could be global or local.
aoqi@0 302 */
aoqi@0 303 public static final class XmlTypeRef extends RawTypeSet.Ref {
aoqi@0 304 private final XSElementDecl decl;
aoqi@0 305 private final TypeUse target;
aoqi@0 306
aoqi@0 307 public XmlTypeRef(XSElementDecl decl) {
aoqi@0 308 this.decl = decl;
aoqi@0 309 SimpleTypeBuilder stb = Ring.get(SimpleTypeBuilder.class);
aoqi@0 310 stb.refererStack.push(decl);
aoqi@0 311 TypeUse r = Ring.get(ClassSelector.class).bindToType(decl.getType(),decl);
aoqi@0 312 stb.refererStack.pop();
aoqi@0 313 target = r;
aoqi@0 314 }
aoqi@0 315
aoqi@0 316 protected CTypeRef toTypeRef(CElementPropertyInfo ep) {
aoqi@0 317 if(ep!=null && target.getAdapterUse()!=null)
aoqi@0 318 ep.setAdapter(target.getAdapterUse());
aoqi@0 319 return new CTypeRef(target.getInfo(),decl);
aoqi@0 320 }
aoqi@0 321
aoqi@0 322 /**
aoqi@0 323 * The whole type set can be later bound to a reference property,
aoqi@0 324 * in which case we need to generate additional code to wrap this
aoqi@0 325 * type reference into an element class.
aoqi@0 326 *
aoqi@0 327 * This method generates such an element class and returns it.
aoqi@0 328 */
aoqi@0 329 protected void toElementRef(CReferencePropertyInfo prop) {
aoqi@0 330 CClassInfo scope = Ring.get(ClassSelector.class).getCurrentBean();
aoqi@0 331 Model model = Ring.get(Model.class);
aoqi@0 332
aoqi@0 333 CCustomizations custs = Ring.get(BGMBuilder.class).getBindInfo(decl).toCustomizationList();
aoqi@0 334
aoqi@0 335 if(target instanceof CClassInfo && Ring.get(BIGlobalBinding.class).isSimpleMode()) {
aoqi@0 336 CClassInfo bean = new CClassInfo(model,scope,
aoqi@0 337 model.getNameConverter().toClassName(decl.getName()),
aoqi@0 338 decl.getLocator(), null, BGMBuilder.getName(decl), decl,
aoqi@0 339 custs);
aoqi@0 340 bean.setBaseClass((CClassInfo)target);
aoqi@0 341 prop.getElements().add(bean);
aoqi@0 342 } else {
aoqi@0 343 CElementInfo e = new CElementInfo(model,BGMBuilder.getName(decl),scope,target,
aoqi@0 344 decl.getDefaultValue(), decl, custs, decl.getLocator());
aoqi@0 345 prop.getElements().add(e);
aoqi@0 346 }
aoqi@0 347 }
aoqi@0 348
aoqi@0 349 protected RawTypeSet.Mode canBeType(RawTypeSet parent) {
aoqi@0 350 // if we have an adapter or IDness, which requires special
aoqi@0 351 // annotation, and there's more than one element,
aoqi@0 352 // we have no place to put the special annotation, so we need JAXBElement.
aoqi@0 353 if((parent.refs.size()>1 || !parent.mul.isAtMostOnce()) && target.idUse()!=ID.NONE)
aoqi@0 354 return RawTypeSet.Mode.MUST_BE_REFERENCE;
aoqi@0 355 if(parent.refs.size() > 1 && target.getAdapterUse() != null)
aoqi@0 356 return RawTypeSet.Mode.MUST_BE_REFERENCE;
aoqi@0 357
aoqi@0 358 // nillable and optional at the same time. needs an element wrapper to distinguish those
aoqi@0 359 // two states. But this is not a hard requirement.
aoqi@0 360 if(decl.isNillable() && parent.mul.isOptional())
aoqi@0 361 return RawTypeSet.Mode.CAN_BE_TYPEREF;
aoqi@0 362
aoqi@0 363 return RawTypeSet.Mode.SHOULD_BE_TYPEREF;
aoqi@0 364 }
aoqi@0 365
aoqi@0 366 protected boolean isListOfValues() {
aoqi@0 367 return target.isCollection();
aoqi@0 368 }
aoqi@0 369
aoqi@0 370 protected ID id() {
aoqi@0 371 return target.idUse();
aoqi@0 372 }
aoqi@0 373
aoqi@0 374 @Override
aoqi@0 375 protected MimeType getExpectedMimeType() {
aoqi@0 376 return target.getExpectedMimeType();
aoqi@0 377 }
aoqi@0 378 }
aoqi@0 379 }

mercurial