001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.tools.internal.xjc.reader.xmlschema.bindinfo;
027:
028: import java.util.Collection;
029: import java.util.Collections;
030:
031: import javax.xml.bind.annotation.XmlAttribute;
032: import javax.xml.bind.annotation.XmlElement;
033: import javax.xml.bind.annotation.XmlElementRef;
034: import javax.xml.bind.annotation.XmlRootElement;
035: import javax.xml.namespace.QName;
036:
037: import com.sun.codemodel.internal.JJavaName;
038: import com.sun.codemodel.internal.JType;
039: import com.sun.tools.internal.xjc.ErrorReceiver;
040: import com.sun.tools.internal.xjc.generator.bean.field.FieldRenderer;
041: import com.sun.tools.internal.xjc.generator.bean.field.FieldRendererFactory;
042: import com.sun.tools.internal.xjc.generator.bean.field.IsSetFieldRenderer;
043: import com.sun.tools.internal.xjc.model.CAttributePropertyInfo;
044: import com.sun.tools.internal.xjc.model.CCustomizations;
045: import com.sun.tools.internal.xjc.model.CElementPropertyInfo;
046: import com.sun.tools.internal.xjc.model.CPropertyInfo;
047: import com.sun.tools.internal.xjc.model.CReferencePropertyInfo;
048: import com.sun.tools.internal.xjc.model.CValuePropertyInfo;
049: import com.sun.tools.internal.xjc.model.TypeUse;
050: import com.sun.tools.internal.xjc.reader.Const;
051: import com.sun.tools.internal.xjc.reader.RawTypeSet;
052: import com.sun.tools.internal.xjc.reader.Ring;
053: import com.sun.tools.internal.xjc.reader.TypeUtil;
054: import com.sun.tools.internal.xjc.reader.xmlschema.BGMBuilder;
055: import com.sun.xml.internal.bind.api.impl.NameConverter;
056: import com.sun.xml.internal.xsom.XSAnnotation;
057: import com.sun.xml.internal.xsom.XSAttGroupDecl;
058: import com.sun.xml.internal.xsom.XSAttributeDecl;
059: import com.sun.xml.internal.xsom.XSAttributeUse;
060: import com.sun.xml.internal.xsom.XSComplexType;
061: import com.sun.xml.internal.xsom.XSComponent;
062: import com.sun.xml.internal.xsom.XSContentType;
063: import com.sun.xml.internal.xsom.XSElementDecl;
064: import com.sun.xml.internal.xsom.XSFacet;
065: import com.sun.xml.internal.xsom.XSIdentityConstraint;
066: import com.sun.xml.internal.xsom.XSModelGroup;
067: import com.sun.xml.internal.xsom.XSModelGroupDecl;
068: import com.sun.xml.internal.xsom.XSNotation;
069: import com.sun.xml.internal.xsom.XSParticle;
070: import com.sun.xml.internal.xsom.XSSchema;
071: import com.sun.xml.internal.xsom.XSSimpleType;
072: import com.sun.xml.internal.xsom.XSWildcard;
073: import com.sun.xml.internal.xsom.XSXPath;
074: import com.sun.xml.internal.xsom.util.XSFinder;
075: import com.sun.xml.internal.xsom.visitor.XSFunction;
076:
077: import org.xml.sax.Locator;
078:
079: /**
080: * Property customization.
081: *
082: * This customization turns an arbitrary schema component
083: * into a Java property (some restrictions apply.)
084: *
085: * <p>
086: * All the getter methods (such as <code>getBaseType</code> or
087: * <code>getBindStyle</code>) honors the delegation chain of
088: * property customization specified in the spec. Namely,
089: * if two property customizations are attached to an attribute
090: * use and an attribute decl, then anything unspecified in the
091: * attribute use defaults to attribute decl.
092: *
093: * <p>
094: * Property customizations are acknowledged
095: * (1) when they are actually used, and
096: * (2) when they are given at the component, which is mapped to a class.
097: * (so-called "point of declaration" customization)
098: *
099: * @author
100: * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
101: */
102: @XmlRootElement(name="property")
103: public 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: public BIProperty(Locator loc, String _propName, String _javadoc,
122: BaseTypeBean _baseType,
123: CollectionTypeAttribute collectionType, Boolean isConst,
124: OptionalPropertyMode optionalProperty, Boolean genElemProp) {
125: super (loc);
126:
127: this .name = _propName;
128: this .javadoc = _javadoc;
129: this .baseType = _baseType;
130: this .collectionType = collectionType;
131: this .isConstantProperty = isConst;
132: this .optionalProperty = optionalProperty;
133: this .generateElementProperty = genElemProp;
134: }
135:
136: protected BIProperty() {
137: }
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: * Returns the customized property name.
156: *
157: * This method honors the "enableJavaNamingConvention" customization
158: * and formats the property name accordingly if necessary.
159: *
160: * Thus the caller should <em>NOT</em> apply the XML-to-Java name
161: * conversion algorithm to the value returned from this method.
162: *
163: * @param forConstant
164: * If the property name is intended for a constant property name,
165: * set to true. This will change the result
166: *
167: * @return
168: * This method can return null if the customization doesn't
169: * specify the name.
170: */
171: public String getPropertyName(boolean forConstant) {
172: if (name != null) {
173: BIGlobalBinding gb = getBuilder().getGlobalBinding();
174: NameConverter nc = getBuilder().model.getNameConverter();
175:
176: if (gb.isJavaNamingConventionEnabled() && !forConstant)
177: // apply XML->Java conversion
178: return nc.toPropertyName(name);
179: else
180: return name; // ... or don't change the value
181: }
182: BIProperty next = getDefault();
183: if (next != null)
184: return next.getPropertyName(forConstant);
185: else
186: 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(), baseType.name, Ring
203: .get(ErrorReceiver.class), getLocation());
204: }
205: BIProperty next = getDefault();
206: if (next != null)
207: return next.getBaseType();
208: else
209: return null;
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)
222: return collectionType;
223: return getDefault().getCollectionType();
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
233: : OptionalPropertyMode.WRAPPER;
234: }
235:
236: public OptionalPropertyMode getOptionalPropertyMode() {
237: if (optionalProperty != null)
238: return optionalProperty;
239: return getDefault().getOptionalPropertyMode();
240: }
241:
242: // null if delegated
243: @XmlAttribute
244: private Boolean generateElementProperty = null;
245:
246: /**
247: * If true, the property will automatically be a reference property.
248: * (Talk about confusing names!)
249: */
250: private Boolean generateElementProperty() {
251: if (generateElementProperty != null)
252: return generateElementProperty;
253: BIProperty next = getDefault();
254: if (next != null)
255: return next.generateElementProperty();
256:
257: return null;
258: }
259:
260: // true, false, or null (which means the value should be inherited.)
261: @XmlAttribute(name="fixedAttributeAsConstantProperty")
262: private Boolean isConstantProperty;
263:
264: /**
265: * Gets the inherited value of the "fixedAttrToConstantProperty" customization.
266: *
267: * <p>
268: * Note that returning true from this method doesn't necessarily mean
269: * that a property needs to be mapped to a constant property.
270: * It just means that it's mapped to a constant property
271: * <b>if an attribute use carries a fixed value.</b>
272: *
273: * <p>
274: * I don't like this semantics but that's what the spec implies.
275: */
276: public boolean isConstantProperty() {
277: if (isConstantProperty != null)
278: return isConstantProperty;
279:
280: BIProperty next = getDefault();
281: if (next != null)
282: return next.isConstantProperty();
283:
284: // globalBinding always has true or false in this property,
285: // so this can't happen
286: throw new AssertionError();
287: }
288:
289: public CValuePropertyInfo createValueProperty(String defaultName,
290: boolean forConstant, XSComponent source, TypeUse tu) {
291:
292: markAsAcknowledged();
293: constantPropertyErrorCheck();
294:
295: String name = getPropertyName(forConstant);
296: if (name == null) {
297: name = defaultName;
298: if (tu.isCollection()
299: && getBuilder().getGlobalBinding().isSimpleMode())
300: name = JJavaName.getPluralForm(name);
301: }
302:
303: return wrapUp(new CValuePropertyInfo(name, source,
304: getCustomizations(source), source.getLocator(), tu),
305: source);
306: }
307:
308: public CAttributePropertyInfo createAttributeProperty(
309: XSAttributeUse use, TypeUse tu) {
310:
311: boolean forConstant = getCustomization(use)
312: .isConstantProperty()
313: && use.getFixedValue() != null;
314:
315: String name = getPropertyName(forConstant);
316: if (name == null) {
317: NameConverter conv = getBuilder().getNameConverter();
318: if (forConstant)
319: name = conv.toConstantName(use.getDecl().getName());
320: else
321: name = conv.toPropertyName(use.getDecl().getName());
322: if (tu.isCollection()
323: && getBuilder().getGlobalBinding().isSimpleMode())
324: name = JJavaName.getPluralForm(name);
325: }
326:
327: QName n = new QName(use.getDecl().getTargetNamespace(), use
328: .getDecl().getName());
329:
330: markAsAcknowledged();
331: constantPropertyErrorCheck();
332:
333: return wrapUp(new CAttributePropertyInfo(name, use,
334: getCustomizations(use), use.getLocator(), n, tu, use
335: .isRequired()), use);
336: }
337:
338: /**
339: *
340: *
341: * @param defaultName
342: * If the name is not customized, this name will be used
343: * as the default. Note that the name conversion <b>MUST</b>
344: * be applied before this method is called if necessary.
345: * @param source
346: * Source schema component from which a field is built.
347: */
348: public CElementPropertyInfo createElementProperty(
349: String defaultName, boolean forConstant, XSParticle source,
350: RawTypeSet types) {
351:
352: if (!types.refs.isEmpty())
353: // if this property is empty, don't acknowleedge the customization
354: // this allows pointless property customization to be reported as an error
355: markAsAcknowledged();
356: constantPropertyErrorCheck();
357:
358: String name = getPropertyName(forConstant);
359: if (name == null)
360: name = defaultName;
361:
362: CElementPropertyInfo prop = wrapUp(new CElementPropertyInfo(
363: name, types.getCollectionMode(), types.id(), types
364: .getExpectedMimeType(), source,
365: getCustomizations(source), source.getLocator(), types
366: .isRequired()), source);
367:
368: types.addTo(prop);
369:
370: return prop;
371: }
372:
373: public CReferencePropertyInfo createReferenceProperty(
374: String defaultName, boolean forConstant,
375: XSComponent source, RawTypeSet types, boolean isMixed) {
376:
377: if (!types.refs.isEmpty())
378: // if this property is empty, don't acknowleedge the customization
379: // this allows pointless property customization to be reported as an error
380: markAsAcknowledged();
381: constantPropertyErrorCheck();
382:
383: String name = getPropertyName(forConstant);
384: if (name == null)
385: name = defaultName;
386:
387: CReferencePropertyInfo prop = wrapUp(
388: new CReferencePropertyInfo(name, types
389: .getCollectionMode().isRepeated()
390: || isMixed, isMixed, source,
391: getCustomizations(source), source.getLocator()),
392: source);
393:
394: types.addTo(prop);
395:
396: return prop;
397: }
398:
399: public CPropertyInfo createElementOrReferenceProperty(
400: String defaultName, boolean forConstant, XSParticle source,
401: RawTypeSet types) {
402:
403: boolean generateRef;
404:
405: switch (types.canBeTypeRefs) {
406: case CAN_BE_TYPEREF:
407: case SHOULD_BE_TYPEREF:
408: // it's up to the use
409: Boolean b = generateElementProperty();
410: if (b == null) // follow XJC recommendation
411: generateRef = types.canBeTypeRefs == RawTypeSet.Mode.CAN_BE_TYPEREF;
412: else
413: // use the value user gave us
414: generateRef = b;
415: break;
416: case MUST_BE_REFERENCE:
417: generateRef = true;
418: break;
419: default:
420: throw new AssertionError();
421: }
422:
423: if (generateRef) {
424: return createReferenceProperty(defaultName, forConstant,
425: source, types, false);
426: } else {
427: return createElementProperty(defaultName, forConstant,
428: source, types);
429: }
430: }
431:
432: /**
433: * Common finalization of {@link CPropertyInfo} for the create***Property methods.
434: */
435: private <T extends CPropertyInfo> T wrapUp(T prop,
436: XSComponent source) {
437: prop.javadoc = concat(javadoc, getBuilder().getBindInfo(source)
438: .getDocumentation());
439: if (prop.javadoc == null)
440: prop.javadoc = "";
441:
442: // decide the realization.
443: FieldRenderer r;
444: OptionalPropertyMode opm = getOptionalPropertyMode();
445: if (prop.isCollection()) {
446: CollectionTypeAttribute ct = getCollectionType();
447: r = ct.get(getBuilder().model);
448: } else {
449: FieldRendererFactory frf = getBuilder().fieldRendererFactory;
450:
451: if (prop.isOptionalPrimitive()) {
452: // the property type can be primitive type if we are to ignore absence
453: switch (opm) {
454: case PRIMITIVE:
455: r = frf.getRequiredUnboxed();
456: break;
457: case WRAPPER:
458: // force the wrapper type
459: r = frf.getSingle();
460: break;
461: case ISSET:
462: r = frf.getSinglePrimitiveAccess();
463: break;
464: default:
465: throw new Error();
466: }
467: } else {
468: r = frf.getDefault();
469: }
470: }
471: if (opm == OptionalPropertyMode.ISSET) {
472: // only isSet is allowed on a collection. these 3 modes aren't really symmetric.
473:
474: // if the property is a primitive type, we need an explicit unset because
475: // we can't overload the meaning of set(null).
476: // if it's a collection, we need to be able to unset it so that we can distinguish
477: // null list and empty list.
478: r = new IsSetFieldRenderer(r, prop.isOptionalPrimitive()
479: || prop.isCollection(), true);
480: }
481:
482: prop.realization = r;
483:
484: JType bt = getBaseType();
485: if (bt != null)
486: prop.baseType = bt;
487:
488: return prop;
489: }
490:
491: private CCustomizations getCustomizations(XSComponent src) {
492: return getBuilder().getBindInfo(src).toCustomizationList();
493: }
494:
495: private CCustomizations getCustomizations(XSComponent... src) {
496: CCustomizations c = null;
497: for (XSComponent s : src) {
498: CCustomizations r = getCustomizations(s);
499: if (c == null)
500: c = r;
501: else
502: c = CCustomizations.merge(c, r);
503: }
504: return c;
505: }
506:
507: private CCustomizations getCustomizations(XSAttributeUse src) {
508: // customizations for an attribute use should include those defined in the local attribute.
509: // this is so that the schema like:
510: //
511: // <xs:attribute name="foo" type="xs:int">
512: // <xs:annotation><xs:appinfo>
513: // <hyperjaxb:... />
514: //
515: // would be picked up
516: if (src.getDecl().isLocal())
517: return getCustomizations(src, src.getDecl());
518: else
519: return getCustomizations((XSComponent) src);
520: }
521:
522: private CCustomizations getCustomizations(XSParticle src) {
523: // customizations for a particle should include those defined in the term unless it's global
524: // this is so that the schema like:
525: //
526: // <xs:sequence>
527: // <xs:element name="foo" type="xs:int">
528: // <xs:annotation><xs:appinfo>
529: // <hyperjaxb:... />
530: //
531: // would be picked up
532: if (src.getTerm().isElementDecl()) {
533: XSElementDecl xed = src.getTerm().asElementDecl();
534: if (xed.isGlobal())
535: return getCustomizations((XSComponent) src);
536: }
537:
538: return getCustomizations(src, src.getTerm());
539: }
540:
541: public void markAsAcknowledged() {
542: if (isAcknowledged())
543: return;
544:
545: // mark the parent as well.
546: super .markAsAcknowledged();
547:
548: BIProperty def = getDefault();
549: if (def != null)
550: def.markAsAcknowledged();
551: }
552:
553: private void constantPropertyErrorCheck() {
554: if (isConstantProperty != null && getOwner() != null) {
555: // run additional check on the isCOnstantProperty value.
556: // this value is not allowed if the schema component doesn't have
557: // a fixed value constraint.
558: //
559: // the setParent method associates a customization with the rest of
560: // XSOM object graph, so this is the earliest possible moment where
561: // we can test this.
562:
563: if (!hasFixedValue.find(getOwner())) {
564: Ring.get(ErrorReceiver.class).error(getLocation(),
565: Messages.ERR_ILLEGAL_FIXEDATTR.format());
566: // set this value to null to avoid the same error to be reported more than once.
567: isConstantProperty = null;
568: }
569: }
570: }
571:
572: /**
573: * Function object that returns true if a component has
574: * a fixed value constraint.
575: */
576: private final XSFinder hasFixedValue = new XSFinder() {
577: public Boolean attributeDecl(XSAttributeDecl decl) {
578: return decl.getFixedValue() != null;
579: }
580:
581: public Boolean attributeUse(XSAttributeUse use) {
582: return use.getFixedValue() != null;
583: }
584:
585: public Boolean schema(XSSchema s) {
586: // we allow globalBindings to have isConstantProperty==true,
587: // so this method returns true to allow this.
588: return true;
589: }
590: };
591:
592: /**
593: * Finds a BIProperty which this object should delegate to.
594: *
595: * @return
596: * always return non-null for normal BIProperties.
597: * If this object is contained in the BIGlobalBinding, then
598: * this method returns null to indicate that there's no more default.
599: */
600: protected BIProperty getDefault() {
601: if (getOwner() == null)
602: return null;
603: BIProperty next = getDefault(getBuilder(), getOwner());
604: if (next == this )
605: return null; // global.
606: else
607: return next;
608: }
609:
610: private static BIProperty getDefault(BGMBuilder builder,
611: XSComponent c) {
612: while (c != null) {
613: c = c.apply(defaultCustomizationFinder);
614: if (c != null) {
615: BIProperty prop = builder.getBindInfo(c).get(
616: BIProperty.class);
617: if (prop != null)
618: return prop;
619: }
620: }
621:
622: // default to the global one
623: return builder.getGlobalBinding().getDefaultProperty();
624: }
625:
626: /**
627: * Finds a property customization that describes how the given
628: * component should be mapped to a property (if it's mapped to
629: * a property at all.)
630: *
631: * <p>
632: * Consider an attribute use that does NOT carry a property
633: * customization. This schema component is nonetheless considered
634: * to carry a (sort of) implicit property customization, whose values
635: * are defaulted.
636: *
637: * <p>
638: * This method can be think of the method that returns this implied
639: * property customization.
640: *
641: * <p>
642: * Note that this doesn't mean the given component needs to be
643: * mapped to a property. But if it does map to a property, it needs
644: * to follow this customization.
645: *
646: * I think this semantics is next to non-sense but I couldn't think
647: * of any other way to follow the spec.
648: *
649: * @param c
650: * A customization effective on this component will be returned.
651: * Can be null just to get the global customization.
652: * @return
653: * Always return non-null valid object.
654: */
655: public static BIProperty getCustomization(XSComponent c) {
656: BGMBuilder builder = Ring.get(BGMBuilder.class);
657:
658: // look for a customization on this component
659: if (c != null) {
660: BIProperty prop = builder.getBindInfo(c).get(
661: BIProperty.class);
662: if (prop != null)
663: return prop;
664: }
665:
666: // if no such thing exists, defeault.
667: return getDefault(builder, c);
668: }
669:
670: private final static XSFunction<XSComponent> defaultCustomizationFinder = new XSFunction<XSComponent>() {
671:
672: public XSComponent attributeUse(XSAttributeUse use) {
673: return use.getDecl(); // inherit from the declaration
674: }
675:
676: public XSComponent particle(XSParticle particle) {
677: return particle.getTerm(); // inherit from the term
678: }
679:
680: public XSComponent schema(XSSchema schema) {
681: // no more delegation
682: return null;
683: }
684:
685: // delegates to the context schema object
686: public XSComponent attributeDecl(XSAttributeDecl decl) {
687: return decl.getOwnerSchema();
688: }
689:
690: public XSComponent wildcard(XSWildcard wc) {
691: return wc.getOwnerSchema();
692: }
693:
694: public XSComponent modelGroupDecl(XSModelGroupDecl decl) {
695: return decl.getOwnerSchema();
696: }
697:
698: public XSComponent modelGroup(XSModelGroup group) {
699: return group.getOwnerSchema();
700: }
701:
702: public XSComponent elementDecl(XSElementDecl decl) {
703: return decl.getOwnerSchema();
704: }
705:
706: public XSComponent complexType(XSComplexType type) {
707: return type.getOwnerSchema();
708: }
709:
710: public XSComponent simpleType(XSSimpleType st) {
711: return st.getOwnerSchema();
712: }
713:
714: // property customizations are not allowed on these components.
715: public XSComponent attGroupDecl(XSAttGroupDecl decl) {
716: throw new IllegalStateException();
717: }
718:
719: public XSComponent empty(XSContentType empty) {
720: throw new IllegalStateException();
721: }
722:
723: public XSComponent annotation(XSAnnotation xsAnnotation) {
724: throw new IllegalStateException();
725: }
726:
727: public XSComponent facet(XSFacet xsFacet) {
728: throw new IllegalStateException();
729: }
730:
731: public XSComponent notation(XSNotation xsNotation) {
732: throw new IllegalStateException();
733: }
734:
735: public XSComponent identityConstraint(XSIdentityConstraint x) {
736: throw new IllegalStateException();
737: }
738:
739: public XSComponent xpath(XSXPath xsxPath) {
740: throw new IllegalStateException();
741: }
742: };
743:
744: private static String concat(String s1, String s2) {
745: if (s1 == null)
746: return s2;
747: if (s2 == null)
748: return s1;
749: return s1 + "\n\n" + s2;
750: }
751:
752: public QName getName() {
753: return NAME;
754: }
755:
756: /** Name of this declaration. */
757: public static final QName NAME = new QName(Const.JAXB_NSURI,
758: "property");
759:
760: public BIConversion getConv() {
761: if (baseType != null)
762: return baseType.conv;
763: else
764: return null;
765: }
766:
767: private static final class BaseTypeBean {
768: /**
769: * If there's a nested javaType customization, this field
770: * will keep that customization. Otherwise null.
771: *
772: * This customization, if present, is used to customize
773: * the simple type mapping at the point of reference.
774: */
775: @XmlElementRef
776: BIConversion conv;
777:
778: /**
779: * Java type name.
780: */
781: @XmlAttribute
782: String name;
783: }
784: }
|