src/share/jaxws_classes/com/sun/tools/internal/xjc/reader/xmlschema/bindinfo/BIProperty.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.bindinfo;
aoqi@0 27
aoqi@0 28 import java.util.Collection;
aoqi@0 29 import java.util.Collections;
aoqi@0 30
aoqi@0 31 import javax.xml.bind.annotation.XmlAttribute;
aoqi@0 32 import javax.xml.bind.annotation.XmlElement;
aoqi@0 33 import javax.xml.bind.annotation.XmlElementRef;
aoqi@0 34 import javax.xml.bind.annotation.XmlRootElement;
aoqi@0 35 import javax.xml.namespace.QName;
aoqi@0 36
aoqi@0 37 import com.sun.codemodel.internal.JJavaName;
aoqi@0 38 import com.sun.codemodel.internal.JType;
aoqi@0 39 import com.sun.tools.internal.xjc.ErrorReceiver;
aoqi@0 40 import com.sun.tools.internal.xjc.generator.bean.field.FieldRenderer;
aoqi@0 41 import com.sun.tools.internal.xjc.generator.bean.field.FieldRendererFactory;
aoqi@0 42 import com.sun.tools.internal.xjc.generator.bean.field.IsSetFieldRenderer;
aoqi@0 43 import com.sun.tools.internal.xjc.model.CAttributePropertyInfo;
aoqi@0 44 import com.sun.tools.internal.xjc.model.CCustomizations;
aoqi@0 45 import com.sun.tools.internal.xjc.model.CElementPropertyInfo;
aoqi@0 46 import com.sun.tools.internal.xjc.model.CPropertyInfo;
aoqi@0 47 import com.sun.tools.internal.xjc.model.CReferencePropertyInfo;
aoqi@0 48 import com.sun.tools.internal.xjc.model.CValuePropertyInfo;
aoqi@0 49 import com.sun.tools.internal.xjc.model.TypeUse;
aoqi@0 50 import com.sun.tools.internal.xjc.reader.Const;
aoqi@0 51 import com.sun.tools.internal.xjc.reader.RawTypeSet;
aoqi@0 52 import com.sun.tools.internal.xjc.reader.Ring;
aoqi@0 53 import com.sun.tools.internal.xjc.reader.TypeUtil;
aoqi@0 54 import com.sun.tools.internal.xjc.reader.xmlschema.BGMBuilder;
aoqi@0 55 import com.sun.xml.internal.bind.api.impl.NameConverter;
aoqi@0 56 import com.sun.xml.internal.xsom.XSAnnotation;
aoqi@0 57 import com.sun.xml.internal.xsom.XSAttGroupDecl;
aoqi@0 58 import com.sun.xml.internal.xsom.XSAttributeDecl;
aoqi@0 59 import com.sun.xml.internal.xsom.XSAttributeUse;
aoqi@0 60 import com.sun.xml.internal.xsom.XSComplexType;
aoqi@0 61 import com.sun.xml.internal.xsom.XSComponent;
aoqi@0 62 import com.sun.xml.internal.xsom.XSContentType;
aoqi@0 63 import com.sun.xml.internal.xsom.XSElementDecl;
aoqi@0 64 import com.sun.xml.internal.xsom.XSFacet;
aoqi@0 65 import com.sun.xml.internal.xsom.XSIdentityConstraint;
aoqi@0 66 import com.sun.xml.internal.xsom.XSModelGroup;
aoqi@0 67 import com.sun.xml.internal.xsom.XSModelGroupDecl;
aoqi@0 68 import com.sun.xml.internal.xsom.XSNotation;
aoqi@0 69 import com.sun.xml.internal.xsom.XSParticle;
aoqi@0 70 import com.sun.xml.internal.xsom.XSSchema;
aoqi@0 71 import com.sun.xml.internal.xsom.XSSimpleType;
aoqi@0 72 import com.sun.xml.internal.xsom.XSWildcard;
aoqi@0 73 import com.sun.xml.internal.xsom.XSXPath;
aoqi@0 74 import com.sun.xml.internal.xsom.util.XSFinder;
aoqi@0 75 import com.sun.xml.internal.xsom.visitor.XSFunction;
aoqi@0 76
aoqi@0 77 import org.xml.sax.Locator;
aoqi@0 78
aoqi@0 79 /**
aoqi@0 80 * Property customization.
aoqi@0 81 *
aoqi@0 82 * This customization turns an arbitrary schema component
aoqi@0 83 * into a Java property (some restrictions apply.)
aoqi@0 84 *
aoqi@0 85 * <p>
aoqi@0 86 * All the getter methods (such as <code>getBaseType</code> or
aoqi@0 87 * <code>getBindStyle</code>) honors the delegation chain of
aoqi@0 88 * property customization specified in the spec. Namely,
aoqi@0 89 * if two property customizations are attached to an attribute
aoqi@0 90 * use and an attribute decl, then anything unspecified in the
aoqi@0 91 * attribute use defaults to attribute decl.
aoqi@0 92 *
aoqi@0 93 * <p>
aoqi@0 94 * Property customizations are acknowledged
aoqi@0 95 * (1) when they are actually used, and
aoqi@0 96 * (2) when they are given at the component, which is mapped to a class.
aoqi@0 97 * (so-called "point of declaration" customization)
aoqi@0 98 *
aoqi@0 99 * @author
aoqi@0 100 * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
aoqi@0 101 */
aoqi@0 102 @XmlRootElement(name="property")
aoqi@0 103 public final class BIProperty extends AbstractDeclarationImpl {
aoqi@0 104
aoqi@0 105 // can be null
aoqi@0 106 @XmlAttribute
aoqi@0 107 private String name = null;
aoqi@0 108
aoqi@0 109 // can be null
aoqi@0 110 @XmlElement
aoqi@0 111 private String javadoc = null;
aoqi@0 112
aoqi@0 113 // can be null
aoqi@0 114 @XmlElement
aoqi@0 115 private BaseTypeBean baseType = null;
aoqi@0 116
aoqi@0 117 // TODO: report 'unsupported' error if this is true
aoqi@0 118 @XmlAttribute
aoqi@0 119 private boolean generateFailFastSetterMethod = false;
aoqi@0 120
aoqi@0 121
aoqi@0 122
aoqi@0 123 public BIProperty(Locator loc, String _propName, String _javadoc,
aoqi@0 124 BaseTypeBean _baseType, CollectionTypeAttribute collectionType, Boolean isConst,
aoqi@0 125 OptionalPropertyMode optionalProperty, Boolean genElemProp) {
aoqi@0 126 super(loc);
aoqi@0 127
aoqi@0 128 this.name = _propName;
aoqi@0 129 this.javadoc = _javadoc;
aoqi@0 130 this.baseType = _baseType;
aoqi@0 131 this.collectionType = collectionType;
aoqi@0 132 this.isConstantProperty = isConst;
aoqi@0 133 this.optionalProperty = optionalProperty;
aoqi@0 134 this.generateElementProperty = genElemProp;
aoqi@0 135 }
aoqi@0 136
aoqi@0 137 protected BIProperty() {}
aoqi@0 138
aoqi@0 139 @Override
aoqi@0 140 public Collection<BIDeclaration> getChildren() {
aoqi@0 141 BIConversion conv = getConv();
aoqi@0 142 if(conv==null)
aoqi@0 143 return super.getChildren();
aoqi@0 144 else
aoqi@0 145 return Collections.<BIDeclaration>singleton(conv);
aoqi@0 146 }
aoqi@0 147
aoqi@0 148 public void setParent( BindInfo parent ) {
aoqi@0 149 super.setParent(parent);
aoqi@0 150 if(baseType!=null && baseType.conv!=null)
aoqi@0 151 baseType.conv.setParent(parent);
aoqi@0 152 }
aoqi@0 153
aoqi@0 154
aoqi@0 155
aoqi@0 156 /**
aoqi@0 157 * Returns the customized property name.
aoqi@0 158 *
aoqi@0 159 * This method honors the "enableJavaNamingConvention" customization
aoqi@0 160 * and formats the property name accordingly if necessary.
aoqi@0 161 *
aoqi@0 162 * Thus the caller should <em>NOT</em> apply the XML-to-Java name
aoqi@0 163 * conversion algorithm to the value returned from this method.
aoqi@0 164 *
aoqi@0 165 * @param forConstant
aoqi@0 166 * If the property name is intended for a constant property name,
aoqi@0 167 * set to true. This will change the result
aoqi@0 168 *
aoqi@0 169 * @return
aoqi@0 170 * This method can return null if the customization doesn't
aoqi@0 171 * specify the name.
aoqi@0 172 */
aoqi@0 173 public String getPropertyName( boolean forConstant ) {
aoqi@0 174 if(name!=null) {
aoqi@0 175 BIGlobalBinding gb = getBuilder().getGlobalBinding();
aoqi@0 176 NameConverter nc = getBuilder().model.getNameConverter();
aoqi@0 177
aoqi@0 178 if( gb.isJavaNamingConventionEnabled() && !forConstant )
aoqi@0 179 // apply XML->Java conversion
aoqi@0 180 return nc.toPropertyName(name);
aoqi@0 181 else
aoqi@0 182 return name; // ... or don't change the value
aoqi@0 183 }
aoqi@0 184 BIProperty next = getDefault();
aoqi@0 185 if(next!=null) return next.getPropertyName(forConstant);
aoqi@0 186 else return null;
aoqi@0 187 }
aoqi@0 188
aoqi@0 189 /**
aoqi@0 190 * Gets the associated javadoc.
aoqi@0 191 *
aoqi@0 192 * @return
aoqi@0 193 * null if none is specfieid.
aoqi@0 194 */
aoqi@0 195 public String getJavadoc() {
aoqi@0 196 return javadoc;
aoqi@0 197 }
aoqi@0 198
aoqi@0 199 // can be null
aoqi@0 200 public JType getBaseType() {
aoqi@0 201 if(baseType!=null && baseType.name!=null) {
aoqi@0 202 return TypeUtil.getType(getCodeModel(),
aoqi@0 203 baseType.name,
aoqi@0 204 Ring.get(ErrorReceiver.class),getLocation());
aoqi@0 205 }
aoqi@0 206 BIProperty next = getDefault();
aoqi@0 207 if(next!=null) return next.getBaseType();
aoqi@0 208 else return null;
aoqi@0 209 }
aoqi@0 210
aoqi@0 211
aoqi@0 212 // can be null
aoqi@0 213 @XmlAttribute
aoqi@0 214 private CollectionTypeAttribute collectionType = null;
aoqi@0 215
aoqi@0 216 /**
aoqi@0 217 * Gets the realization of this field.
aoqi@0 218 * @return Always return non-null.
aoqi@0 219 */
aoqi@0 220 CollectionTypeAttribute getCollectionType() {
aoqi@0 221 if(collectionType!=null) return collectionType;
aoqi@0 222 return getDefault().getCollectionType();
aoqi@0 223 }
aoqi@0 224
aoqi@0 225
aoqi@0 226 @XmlAttribute
aoqi@0 227 private OptionalPropertyMode optionalProperty = null;
aoqi@0 228
aoqi@0 229 // virtual property for @generateIsSetMethod
aoqi@0 230 @XmlAttribute
aoqi@0 231 void setGenerateIsSetMethod(boolean b) {
aoqi@0 232 optionalProperty = b ? OptionalPropertyMode.ISSET : OptionalPropertyMode.WRAPPER;
aoqi@0 233 }
aoqi@0 234
aoqi@0 235 public OptionalPropertyMode getOptionalPropertyMode() {
aoqi@0 236 if(optionalProperty!=null) return optionalProperty;
aoqi@0 237 return getDefault().getOptionalPropertyMode();
aoqi@0 238 }
aoqi@0 239
aoqi@0 240 // null if delegated
aoqi@0 241 @XmlAttribute
aoqi@0 242 private Boolean generateElementProperty = null;
aoqi@0 243 /**
aoqi@0 244 * If true, the property will automatically be a reference property.
aoqi@0 245 * (Talk about confusing names!)
aoqi@0 246 */
aoqi@0 247 private Boolean generateElementProperty() {
aoqi@0 248 if(generateElementProperty!=null) return generateElementProperty;
aoqi@0 249 BIProperty next = getDefault();
aoqi@0 250 if(next!=null) return next.generateElementProperty();
aoqi@0 251
aoqi@0 252 return null;
aoqi@0 253 }
aoqi@0 254
aoqi@0 255
aoqi@0 256 // true, false, or null (which means the value should be inherited.)
aoqi@0 257 @XmlAttribute(name="fixedAttributeAsConstantProperty")
aoqi@0 258 private Boolean isConstantProperty;
aoqi@0 259 /**
aoqi@0 260 * Gets the inherited value of the "fixedAttrToConstantProperty" customization.
aoqi@0 261 *
aoqi@0 262 * <p>
aoqi@0 263 * Note that returning true from this method doesn't necessarily mean
aoqi@0 264 * that a property needs to be mapped to a constant property.
aoqi@0 265 * It just means that it's mapped to a constant property
aoqi@0 266 * <b>if an attribute use carries a fixed value.</b>
aoqi@0 267 *
aoqi@0 268 * <p>
aoqi@0 269 * I don't like this semantics but that's what the spec implies.
aoqi@0 270 */
aoqi@0 271 public boolean isConstantProperty() {
aoqi@0 272 if(isConstantProperty!=null) return isConstantProperty;
aoqi@0 273
aoqi@0 274 BIProperty next = getDefault();
aoqi@0 275 if(next!=null) return next.isConstantProperty();
aoqi@0 276
aoqi@0 277 // globalBinding always has true or false in this property,
aoqi@0 278 // so this can't happen
aoqi@0 279 throw new AssertionError();
aoqi@0 280 }
aoqi@0 281
aoqi@0 282 public CValuePropertyInfo createValueProperty(String defaultName,boolean forConstant,
aoqi@0 283 XSComponent source,TypeUse tu, QName typeName) {
aoqi@0 284
aoqi@0 285 markAsAcknowledged();
aoqi@0 286 constantPropertyErrorCheck();
aoqi@0 287
aoqi@0 288 String name = getPropertyName(forConstant);
aoqi@0 289 if(name==null) {
aoqi@0 290 name = defaultName;
aoqi@0 291 if(tu.isCollection() && getBuilder().getGlobalBinding().isSimpleMode())
aoqi@0 292 name = JJavaName.getPluralForm(name);
aoqi@0 293 }
aoqi@0 294
aoqi@0 295 CValuePropertyInfo prop = wrapUp(new CValuePropertyInfo(name, source, getCustomizations(source), source.getLocator(), tu, typeName), source);
aoqi@0 296 BIInlineBinaryData.handle(source, prop);
aoqi@0 297 return prop;
aoqi@0 298 }
aoqi@0 299
aoqi@0 300 public CAttributePropertyInfo createAttributeProperty( XSAttributeUse use, TypeUse tu ) {
aoqi@0 301
aoqi@0 302 boolean forConstant =
aoqi@0 303 getCustomization(use).isConstantProperty() &&
aoqi@0 304 use.getFixedValue()!=null;
aoqi@0 305
aoqi@0 306 String name = getPropertyName(forConstant);
aoqi@0 307 if(name==null) {
aoqi@0 308 NameConverter conv = getBuilder().getNameConverter();
aoqi@0 309 if(forConstant)
aoqi@0 310 name = conv.toConstantName(use.getDecl().getName());
aoqi@0 311 else
aoqi@0 312 name = conv.toPropertyName(use.getDecl().getName());
aoqi@0 313 if(tu.isCollection() && getBuilder().getGlobalBinding().isSimpleMode())
aoqi@0 314 name = JJavaName.getPluralForm(name);
aoqi@0 315 }
aoqi@0 316
aoqi@0 317 markAsAcknowledged();
aoqi@0 318 constantPropertyErrorCheck();
aoqi@0 319
aoqi@0 320 return wrapUp(new CAttributePropertyInfo(name,use,getCustomizations(use),use.getLocator(),
aoqi@0 321 BGMBuilder.getName(use.getDecl()), tu,
aoqi@0 322 BGMBuilder.getName(use.getDecl().getType()), use.isRequired() ),use);
aoqi@0 323 }
aoqi@0 324
aoqi@0 325 /**
aoqi@0 326 *
aoqi@0 327 *
aoqi@0 328 * @param defaultName
aoqi@0 329 * If the name is not customized, this name will be used
aoqi@0 330 * as the default. Note that the name conversion <b>MUST</b>
aoqi@0 331 * be applied before this method is called if necessary.
aoqi@0 332 * @param source
aoqi@0 333 * Source schema component from which a field is built.
aoqi@0 334 */
aoqi@0 335 public CElementPropertyInfo createElementProperty(String defaultName, boolean forConstant, XSParticle source,
aoqi@0 336 RawTypeSet types) {
aoqi@0 337
aoqi@0 338 if(!types.refs.isEmpty())
aoqi@0 339 // if this property is empty, don't acknowleedge the customization
aoqi@0 340 // this allows pointless property customization to be reported as an error
aoqi@0 341 markAsAcknowledged();
aoqi@0 342 constantPropertyErrorCheck();
aoqi@0 343
aoqi@0 344 String name = getPropertyName(forConstant);
aoqi@0 345 if(name==null)
aoqi@0 346 name = defaultName;
aoqi@0 347
aoqi@0 348 CElementPropertyInfo prop = wrapUp(
aoqi@0 349 new CElementPropertyInfo(
aoqi@0 350 name, types.getCollectionMode(),
aoqi@0 351 types.id(),
aoqi@0 352 types.getExpectedMimeType(),
aoqi@0 353 source, getCustomizations(source),
aoqi@0 354 source.getLocator(), types.isRequired()),
aoqi@0 355 source);
aoqi@0 356
aoqi@0 357 types.addTo(prop);
aoqi@0 358
aoqi@0 359 BIInlineBinaryData.handle(source.getTerm(), prop);
aoqi@0 360 return prop;
aoqi@0 361 }
aoqi@0 362
aoqi@0 363 public CReferencePropertyInfo createDummyExtendedMixedReferenceProperty(
aoqi@0 364 String defaultName, XSComponent source, RawTypeSet types) {
aoqi@0 365 return createReferenceProperty(
aoqi@0 366 defaultName,
aoqi@0 367 false,
aoqi@0 368 source,
aoqi@0 369 types,
aoqi@0 370 true,
aoqi@0 371 true,
aoqi@0 372 false,
aoqi@0 373 true);
aoqi@0 374 }
aoqi@0 375
aoqi@0 376 public CReferencePropertyInfo createContentExtendedMixedReferenceProperty(
aoqi@0 377 String defaultName, XSComponent source, RawTypeSet types) {
aoqi@0 378 return createReferenceProperty(
aoqi@0 379 defaultName,
aoqi@0 380 false,
aoqi@0 381 source,
aoqi@0 382 types,
aoqi@0 383 true,
aoqi@0 384 false,
aoqi@0 385 true,
aoqi@0 386 true);
aoqi@0 387 }
aoqi@0 388
aoqi@0 389 public CReferencePropertyInfo createReferenceProperty(
aoqi@0 390 String defaultName, boolean forConstant, XSComponent source,
aoqi@0 391 RawTypeSet types, boolean isMixed, boolean dummy, boolean content, boolean isMixedExtended) {
aoqi@0 392
aoqi@0 393 if (types == null) { // this is a special case where we need to generate content because potential subtypes would need to be able to override what's store inside
aoqi@0 394 content = true;
aoqi@0 395 } else {
aoqi@0 396 if(!types.refs.isEmpty())
aoqi@0 397 // if this property is empty, don't acknowleedge the customization
aoqi@0 398 // this allows pointless property customization to be reported as an error
aoqi@0 399 markAsAcknowledged();
aoqi@0 400 }
aoqi@0 401 constantPropertyErrorCheck();
aoqi@0 402
aoqi@0 403 String name = getPropertyName(forConstant);
aoqi@0 404 if(name==null)
aoqi@0 405 name = defaultName;
aoqi@0 406
aoqi@0 407 CReferencePropertyInfo prop = wrapUp(
aoqi@0 408 new CReferencePropertyInfo(
aoqi@0 409 name,
aoqi@0 410 (types == null) ? true : types.getCollectionMode().isRepeated()||isMixed,
aoqi@0 411 (types == null) ? false : types.isRequired(),
aoqi@0 412 isMixed,
aoqi@0 413 source,
aoqi@0 414 getCustomizations(source), source.getLocator(), dummy, content, isMixedExtended),
aoqi@0 415 source);
aoqi@0 416 if (types != null) {
aoqi@0 417 types.addTo(prop);
aoqi@0 418 }
aoqi@0 419
aoqi@0 420 BIInlineBinaryData.handle(source, prop);
aoqi@0 421 return prop;
aoqi@0 422 }
aoqi@0 423
aoqi@0 424 public CPropertyInfo createElementOrReferenceProperty(
aoqi@0 425 String defaultName, boolean forConstant, XSParticle source,
aoqi@0 426 RawTypeSet types) {
aoqi@0 427
aoqi@0 428 boolean generateRef;
aoqi@0 429
aoqi@0 430 switch(types.canBeTypeRefs) {
aoqi@0 431 case CAN_BE_TYPEREF:
aoqi@0 432 case SHOULD_BE_TYPEREF:
aoqi@0 433 // it's up to the use
aoqi@0 434 Boolean b = generateElementProperty();
aoqi@0 435 if(b==null) // follow XJC recommendation
aoqi@0 436 generateRef = types.canBeTypeRefs== RawTypeSet.Mode.CAN_BE_TYPEREF;
aoqi@0 437 else // use the value user gave us
aoqi@0 438 generateRef = b;
aoqi@0 439 break;
aoqi@0 440 case MUST_BE_REFERENCE:
aoqi@0 441 generateRef = true;
aoqi@0 442 break;
aoqi@0 443 default:
aoqi@0 444 throw new AssertionError();
aoqi@0 445 }
aoqi@0 446
aoqi@0 447 if(generateRef) {
aoqi@0 448 return createReferenceProperty(defaultName,forConstant,source,types, false, false, false, false);
aoqi@0 449 } else {
aoqi@0 450 return createElementProperty(defaultName,forConstant,source,types);
aoqi@0 451 }
aoqi@0 452 }
aoqi@0 453
aoqi@0 454 /**
aoqi@0 455 * Common finalization of {@link CPropertyInfo} for the create***Property methods.
aoqi@0 456 */
aoqi@0 457 private <T extends CPropertyInfo> T wrapUp(T prop, XSComponent source) {
aoqi@0 458 prop.javadoc = concat(javadoc,
aoqi@0 459 getBuilder().getBindInfo(source).getDocumentation());
aoqi@0 460 if(prop.javadoc==null)
aoqi@0 461 prop.javadoc="";
aoqi@0 462
aoqi@0 463 // decide the realization.
aoqi@0 464 FieldRenderer r;
aoqi@0 465 OptionalPropertyMode opm = getOptionalPropertyMode();
aoqi@0 466 if(prop.isCollection()) {
aoqi@0 467 CollectionTypeAttribute ct = getCollectionType();
aoqi@0 468 r = ct.get(getBuilder().model);
aoqi@0 469 } else {
aoqi@0 470 FieldRendererFactory frf = getBuilder().fieldRendererFactory;
aoqi@0 471
aoqi@0 472 if(prop.isOptionalPrimitive()) {
aoqi@0 473 // the property type can be primitive type if we are to ignore absence
aoqi@0 474 switch(opm) {
aoqi@0 475 case PRIMITIVE:
aoqi@0 476 r = frf.getRequiredUnboxed();
aoqi@0 477 break;
aoqi@0 478 case WRAPPER:
aoqi@0 479 // force the wrapper type
aoqi@0 480 r = frf.getSingle();
aoqi@0 481 break;
aoqi@0 482 case ISSET:
aoqi@0 483 r = frf.getSinglePrimitiveAccess();
aoqi@0 484 break;
aoqi@0 485 default:
aoqi@0 486 throw new Error();
aoqi@0 487 }
aoqi@0 488 } else {
aoqi@0 489 r = frf.getDefault();
aoqi@0 490 }
aoqi@0 491 }
aoqi@0 492 if(opm==OptionalPropertyMode.ISSET) {
aoqi@0 493 // only isSet is allowed on a collection. these 3 modes aren't really symmetric.
aoqi@0 494
aoqi@0 495 // if the property is a primitive type, we need an explicit unset because
aoqi@0 496 // we can't overload the meaning of set(null).
aoqi@0 497 // if it's a collection, we need to be able to unset it so that we can distinguish
aoqi@0 498 // null list and empty list.
aoqi@0 499 r = new IsSetFieldRenderer( r, prop.isOptionalPrimitive()||prop.isCollection(), true );
aoqi@0 500 }
aoqi@0 501
aoqi@0 502 prop.realization = r;
aoqi@0 503
aoqi@0 504 JType bt = getBaseType();
aoqi@0 505 if(bt!=null)
aoqi@0 506 prop.baseType = bt;
aoqi@0 507
aoqi@0 508 return prop;
aoqi@0 509 }
aoqi@0 510
aoqi@0 511 private CCustomizations getCustomizations( XSComponent src ) {
aoqi@0 512 return getBuilder().getBindInfo(src).toCustomizationList();
aoqi@0 513 }
aoqi@0 514
aoqi@0 515 private CCustomizations getCustomizations( XSComponent... src ) {
aoqi@0 516 CCustomizations c = null;
aoqi@0 517 for (XSComponent s : src) {
aoqi@0 518 CCustomizations r = getCustomizations(s);
aoqi@0 519 if(c==null) c = r;
aoqi@0 520 else c = CCustomizations.merge(c,r);
aoqi@0 521 }
aoqi@0 522 return c;
aoqi@0 523 }
aoqi@0 524
aoqi@0 525 private CCustomizations getCustomizations( XSAttributeUse src ) {
aoqi@0 526 // customizations for an attribute use should include those defined in the local attribute.
aoqi@0 527 // this is so that the schema like:
aoqi@0 528 //
aoqi@0 529 // <xs:attribute name="foo" type="xs:int">
aoqi@0 530 // <xs:annotation><xs:appinfo>
aoqi@0 531 // <hyperjaxb:... />
aoqi@0 532 //
aoqi@0 533 // would be picked up
aoqi@0 534 if(src.getDecl().isLocal())
aoqi@0 535 return getCustomizations(src,src.getDecl());
aoqi@0 536 else
aoqi@0 537 return getCustomizations((XSComponent)src);
aoqi@0 538 }
aoqi@0 539
aoqi@0 540 private CCustomizations getCustomizations( XSParticle src ) {
aoqi@0 541 // customizations for a particle should include those defined in the term unless it's global
aoqi@0 542 // this is so that the schema like:
aoqi@0 543 //
aoqi@0 544 // <xs:sequence>
aoqi@0 545 // <xs:element name="foo" type="xs:int">
aoqi@0 546 // <xs:annotation><xs:appinfo>
aoqi@0 547 // <hyperjaxb:... />
aoqi@0 548 //
aoqi@0 549 // would be picked up
aoqi@0 550 if(src.getTerm().isElementDecl()) {
aoqi@0 551 XSElementDecl xed = src.getTerm().asElementDecl();
aoqi@0 552 if(xed.isGlobal())
aoqi@0 553 return getCustomizations((XSComponent)src);
aoqi@0 554 }
aoqi@0 555
aoqi@0 556 return getCustomizations(src,src.getTerm());
aoqi@0 557 }
aoqi@0 558
aoqi@0 559
aoqi@0 560
aoqi@0 561 public void markAsAcknowledged() {
aoqi@0 562 if( isAcknowledged() ) return;
aoqi@0 563
aoqi@0 564 // mark the parent as well.
aoqi@0 565 super.markAsAcknowledged();
aoqi@0 566
aoqi@0 567 BIProperty def = getDefault();
aoqi@0 568 if(def!=null) def.markAsAcknowledged();
aoqi@0 569 }
aoqi@0 570
aoqi@0 571 private void constantPropertyErrorCheck() {
aoqi@0 572 if( isConstantProperty!=null && getOwner()!=null ) {
aoqi@0 573 // run additional check on the isCOnstantProperty value.
aoqi@0 574 // this value is not allowed if the schema component doesn't have
aoqi@0 575 // a fixed value constraint.
aoqi@0 576 //
aoqi@0 577 // the setParent method associates a customization with the rest of
aoqi@0 578 // XSOM object graph, so this is the earliest possible moment where
aoqi@0 579 // we can test this.
aoqi@0 580
aoqi@0 581 if( !hasFixedValue.find(getOwner()) ) {
aoqi@0 582 Ring.get(ErrorReceiver.class).error(
aoqi@0 583 getLocation(),
aoqi@0 584 Messages.ERR_ILLEGAL_FIXEDATTR.format()
aoqi@0 585 );
aoqi@0 586 // set this value to null to avoid the same error to be reported more than once.
aoqi@0 587 isConstantProperty = null;
aoqi@0 588 }
aoqi@0 589 }
aoqi@0 590 }
aoqi@0 591
aoqi@0 592 /**
aoqi@0 593 * Function object that returns true if a component has
aoqi@0 594 * a fixed value constraint.
aoqi@0 595 */
aoqi@0 596 private final XSFinder hasFixedValue = new XSFinder() {
aoqi@0 597 public Boolean attributeDecl(XSAttributeDecl decl) {
aoqi@0 598 return decl.getFixedValue()!=null;
aoqi@0 599 }
aoqi@0 600
aoqi@0 601 public Boolean attributeUse(XSAttributeUse use) {
aoqi@0 602 return use.getFixedValue()!=null;
aoqi@0 603 }
aoqi@0 604
aoqi@0 605 public Boolean schema(XSSchema s) {
aoqi@0 606 // we allow globalBindings to have isConstantProperty==true,
aoqi@0 607 // so this method returns true to allow this.
aoqi@0 608 return true;
aoqi@0 609 }
aoqi@0 610 };
aoqi@0 611
aoqi@0 612 /**
aoqi@0 613 * Finds a BIProperty which this object should delegate to.
aoqi@0 614 *
aoqi@0 615 * @return
aoqi@0 616 * always return non-null for normal BIProperties.
aoqi@0 617 * If this object is contained in the BIGlobalBinding, then
aoqi@0 618 * this method returns null to indicate that there's no more default.
aoqi@0 619 */
aoqi@0 620 protected BIProperty getDefault() {
aoqi@0 621 if(getOwner()==null) return null;
aoqi@0 622 BIProperty next = getDefault(getBuilder(),getOwner());
aoqi@0 623 if(next==this) return null; // global.
aoqi@0 624 else return next;
aoqi@0 625 }
aoqi@0 626
aoqi@0 627 private static BIProperty getDefault( BGMBuilder builder, XSComponent c ) {
aoqi@0 628 while(c!=null) {
aoqi@0 629 c = c.apply(defaultCustomizationFinder);
aoqi@0 630 if(c!=null) {
aoqi@0 631 BIProperty prop = builder.getBindInfo(c).get(BIProperty.class);
aoqi@0 632 if(prop!=null) return prop;
aoqi@0 633 }
aoqi@0 634 }
aoqi@0 635
aoqi@0 636 // default to the global one
aoqi@0 637 return builder.getGlobalBinding().getDefaultProperty();
aoqi@0 638 }
aoqi@0 639
aoqi@0 640
aoqi@0 641 /**
aoqi@0 642 * Finds a property customization that describes how the given
aoqi@0 643 * component should be mapped to a property (if it's mapped to
aoqi@0 644 * a property at all.)
aoqi@0 645 *
aoqi@0 646 * <p>
aoqi@0 647 * Consider an attribute use that does NOT carry a property
aoqi@0 648 * customization. This schema component is nonetheless considered
aoqi@0 649 * to carry a (sort of) implicit property customization, whose values
aoqi@0 650 * are defaulted.
aoqi@0 651 *
aoqi@0 652 * <p>
aoqi@0 653 * This method can be think of the method that returns this implied
aoqi@0 654 * property customization.
aoqi@0 655 *
aoqi@0 656 * <p>
aoqi@0 657 * Note that this doesn't mean the given component needs to be
aoqi@0 658 * mapped to a property. But if it does map to a property, it needs
aoqi@0 659 * to follow this customization.
aoqi@0 660 *
aoqi@0 661 * I think this semantics is next to non-sense but I couldn't think
aoqi@0 662 * of any other way to follow the spec.
aoqi@0 663 *
aoqi@0 664 * @param c
aoqi@0 665 * A customization effective on this component will be returned.
aoqi@0 666 * Can be null just to get the global customization.
aoqi@0 667 * @return
aoqi@0 668 * Always return non-null valid object.
aoqi@0 669 */
aoqi@0 670 public static BIProperty getCustomization( XSComponent c ) {
aoqi@0 671 BGMBuilder builder = Ring.get(BGMBuilder.class);
aoqi@0 672
aoqi@0 673 // look for a customization on this component
aoqi@0 674 if( c!=null ) {
aoqi@0 675 BIProperty prop = builder.getBindInfo(c).get(BIProperty.class);
aoqi@0 676 if(prop!=null) return prop;
aoqi@0 677 }
aoqi@0 678
aoqi@0 679 // if no such thing exists, defeault.
aoqi@0 680 return getDefault(builder,c);
aoqi@0 681 }
aoqi@0 682
aoqi@0 683 private final static XSFunction<XSComponent> defaultCustomizationFinder = new XSFunction<XSComponent>() {
aoqi@0 684
aoqi@0 685 public XSComponent attributeUse(XSAttributeUse use) {
aoqi@0 686 return use.getDecl(); // inherit from the declaration
aoqi@0 687 }
aoqi@0 688
aoqi@0 689 public XSComponent particle(XSParticle particle) {
aoqi@0 690 return particle.getTerm(); // inherit from the term
aoqi@0 691 }
aoqi@0 692
aoqi@0 693 public XSComponent schema(XSSchema schema) {
aoqi@0 694 // no more delegation
aoqi@0 695 return null;
aoqi@0 696 }
aoqi@0 697
aoqi@0 698 // delegates to the context schema object
aoqi@0 699 public XSComponent attributeDecl(XSAttributeDecl decl) { return decl.getOwnerSchema(); }
aoqi@0 700 public XSComponent wildcard(XSWildcard wc) { return wc.getOwnerSchema(); }
aoqi@0 701 public XSComponent modelGroupDecl(XSModelGroupDecl decl) { return decl.getOwnerSchema(); }
aoqi@0 702 public XSComponent modelGroup(XSModelGroup group) { return group.getOwnerSchema(); }
aoqi@0 703 public XSComponent elementDecl(XSElementDecl decl) { return decl.getOwnerSchema(); }
aoqi@0 704 public XSComponent complexType(XSComplexType type) { return type.getOwnerSchema(); }
aoqi@0 705 public XSComponent simpleType(XSSimpleType st) { return st.getOwnerSchema(); }
aoqi@0 706
aoqi@0 707 // property customizations are not allowed on these components.
aoqi@0 708 public XSComponent attGroupDecl(XSAttGroupDecl decl) { throw new IllegalStateException(); }
aoqi@0 709 public XSComponent empty(XSContentType empty) { throw new IllegalStateException(); }
aoqi@0 710 public XSComponent annotation(XSAnnotation xsAnnotation) { throw new IllegalStateException(); }
aoqi@0 711 public XSComponent facet(XSFacet xsFacet) { throw new IllegalStateException(); }
aoqi@0 712 public XSComponent notation(XSNotation xsNotation) { throw new IllegalStateException(); }
aoqi@0 713 public XSComponent identityConstraint(XSIdentityConstraint x) { throw new IllegalStateException(); }
aoqi@0 714 public XSComponent xpath(XSXPath xsxPath) { throw new IllegalStateException(); }
aoqi@0 715 };
aoqi@0 716
aoqi@0 717
aoqi@0 718 private static String concat( String s1, String s2 ) {
aoqi@0 719 if(s1==null) return s2;
aoqi@0 720 if(s2==null) return s1;
aoqi@0 721 return s1+"\n\n"+s2;
aoqi@0 722 }
aoqi@0 723
aoqi@0 724 public QName getName() { return NAME; }
aoqi@0 725
aoqi@0 726 /** Name of this declaration. */
aoqi@0 727 public static final QName NAME = new QName(
aoqi@0 728 Const.JAXB_NSURI, "property" );
aoqi@0 729
aoqi@0 730 public BIConversion getConv() {
aoqi@0 731 if(baseType!=null)
aoqi@0 732 return baseType.conv;
aoqi@0 733 else
aoqi@0 734 return null;
aoqi@0 735 }
aoqi@0 736
aoqi@0 737 private static final class BaseTypeBean {
aoqi@0 738 /**
aoqi@0 739 * If there's a nested javaType customization, this field
aoqi@0 740 * will keep that customization. Otherwise null.
aoqi@0 741 *
aoqi@0 742 * This customization, if present, is used to customize
aoqi@0 743 * the simple type mapping at the point of reference.
aoqi@0 744 */
aoqi@0 745 @XmlElementRef
aoqi@0 746 BIConversion conv;
aoqi@0 747
aoqi@0 748 /**
aoqi@0 749 * Java type name.
aoqi@0 750 */
aoqi@0 751 @XmlAttribute
aoqi@0 752 String name;
aoqi@0 753 }
aoqi@0 754 }

mercurial