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