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