001: /*
002: * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
003: * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
004: */
005:
006: package javax.xml.bind.annotation;
007:
008: import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
009: import java.lang.annotation.Retention;
010: import java.lang.annotation.Target;
011:
012: import static java.lang.annotation.RetentionPolicy.RUNTIME;
013: import static java.lang.annotation.ElementType.FIELD;
014: import static java.lang.annotation.ElementType.METHOD;
015:
016: /**
017: * <p>
018: * Maps a JavaBean property to a XML element derived from property's type.
019: * <p>
020: * <b>Usage</b>
021: * <p>
022: * <tt>@XmlElementRef</tt> annotation can be used with a
023: * JavaBean property or from within {@link XmlElementRefs}
024: * <p>
025: * This annotation dynamically associates an XML element name with the JavaBean
026: * property. When a JavaBean property is annotated with {@link
027: * XmlElement}, the XML element name is statically derived from the
028: * JavaBean property name. However, when this annotation is used, the
029: * XML element name is derived from the instance of the type of the
030: * JavaBean property at runtime.
031: *
032: * <h3> XML Schema substitution group support </h3>
033: * XML Schema allows a XML document author to use XML element names
034: * that were not statically specified in the content model of a
035: * schema using substitution groups. Schema derived code provides
036: * support for substitution groups using an <i>element property</i>,
037: * (section 5.5.5, "Element Property" of JAXB 2.0 specification). An
038: * element property method signature is of the form:
039: * <pre><xmp>
040: * public void setTerm(JAXBElement<? extends Operator>);
041: * public JAXBElement<? extends Operator> getTerm();
042: * </xmp></pre>
043: * <p>
044: * An element factory method annotated with {@link XmlElementDecl} is
045: * used to create a <tt>JAXBElement</tt> instance, containing an XML
046: * element name. The presence of @XmlElementRef annotation on an
047: * element property indicates that the element name from <tt>JAXBElement</tt>
048: * instance be used instead of deriving an XML element name from the
049: * JavaBean property name.
050: *
051: * <p>
052: * The usage is subject to the following constraints:
053: * <ul>
054: * <li> If the collection item type (for collection property) or
055: * property type (for single valued property) is
056: * {@link javax.xml.bind.JAXBElement}, then
057: * <tt>@XmlElementRef}.name()</tt> and <tt>@XmlElementRef.namespace()</tt> must
058: * point an element factory method with an @XmlElementDecl
059: * annotation in a class annotated with @XmlRegistry (usually
060: * ObjectFactory class generated by the schema compiler) :
061: * <ul>
062: * <li> @XmlElementDecl.name() must equal @XmlElementRef.name() </li>
063: * <li> @XmlElementDecl.namespace() must equal @XmlElementRef.namespace(). </li>
064: * </ul>
065: * </li>
066: * <li> If the collection item type (for collection property) or
067: * property type (for single valued property) is not
068: * {@link javax.xml.bind.JAXBElement}, then the type referenced by the
069: * property or field must be annotated with {@link XmlRootElement}. </li>
070: * <li> This annotation can be used with the following annotations:
071: * {@link XmlElementWrapper}, {@link XmlJavaTypeAdapter}.
072: * </ul>
073: *
074: * <p>See "Package Specification" in javax.xml.bind.package javadoc for
075: * additional common information.</p>
076: *
077: * <p><b>Example 1: </b>Ant Task Example</b></p>
078: * The following Java class hierarchy models an Ant build
079: * script. An Ant task corresponds to a class in the class
080: * hierarchy. The XML element name of an Ant task is indicated by the
081: * @XmlRootElement annotation on its corresponding class.
082: * <pre>
083: * @XmlRootElement(name="target")
084: * class Target {
085: * // The presence of @XmlElementRef indicates that the XML
086: * // element name will be derived from the @XmlRootElement
087: * // annotation on the type (for e.g. "jar" for JarTask).
088: * @XmlElementRef
089: * List<Task> tasks;
090: * }
091: *
092: * abstract class Task {
093: * }
094: *
095: * @XmlRootElement(name="jar")
096: * class JarTask extends Task {
097: * ...
098: * }
099: *
100: * @XmlRootElement(name="javac")
101: * class JavacTask extends Task {
102: * ...
103: * }
104: *
105: * <!-- XML Schema fragment -->
106: * <xs:element name="target" type="Target">
107: * <xs:complexType name="Target">
108: * <xs:sequence>
109: * <xs:choice maxOccurs="unbounded">
110: * <xs:element ref="jar">
111: * <xs:element ref="javac">
112: * </xs:choice>
113: * </xs:sequence>
114: * </xs:complexType>
115: *
116: * </pre>
117: * <p>
118: * Thus the following code fragment:
119: * <pre>
120: * Target target = new Target();
121: * target.tasks.add(new JarTask());
122: * target.tasks.add(new JavacTask());
123: * marshal(target);
124: * </pre>
125: * will produce the following XML output:
126: * <pre><xmp>
127: * <target>
128: * <jar>
129: * ....
130: * </jar>
131: * <javac>
132: * ....
133: * </javac>
134: * </target>
135: * </xmp></pre>
136: * <p>
137: * It is not an error to have a class that extends <tt>Task</tt>
138: * that doesn't have {@link XmlRootElement}. But they can't show up in an
139: * XML instance (because they don't have XML element names).
140: *
141: * <p><b>Example 2: XML Schema Susbstitution group support</b>
142: * <p> The following example shows the annotations for XML Schema
143: * substitution groups. The annotations and the ObjectFactory are
144: * derived from the schema.
145: *
146: * <pre>
147: * @XmlElement
148: * class Math {
149: * // The value of {@link #type()}is
150: * // JAXBElement.class , which indicates the XML
151: * // element name ObjectFactory - in general a class marked
152: * // with @XmlRegistry. (See ObjectFactory below)
153: * //
154: * // The {@link #name()} is "operator", a pointer to a
155: * // factory method annotated with a
156: * // {@link XmlElementDecl} with the name "operator". Since
157: * // "operator" is the head of a substitution group that
158: * // contains elements "add" and "sub" elements, "operator"
159: * // element can be substituted in an instance document by
160: * // elements "add" or "sub". At runtime, JAXBElement
161: * // instance contains the element name that has been
162: * // substituted in the XML document.
163: * //
164: * @XmlElementRef(type=JAXBElement.class,name="operator")
165: * JAXBElement<? extends Operator> term;
166: * }
167: *
168: * @XmlRegistry
169: * class ObjectFactory {
170: * @XmlElementDecl(name="operator")
171: * JAXBElement<Operator> createOperator(Operator o) {...}
172: * @XmlElementDecl(name="add",substitutionHeadName="operator")
173: * JAXBElement<Operator> createAdd(Operator o) {...}
174: * @XmlElementDecl(name="sub",substitutionHeadName="operator")
175: * JAXBElement<Operator> createSub(Operator o) {...}
176: * }
177: *
178: * class Operator {
179: * ...
180: * }
181: * </pre>
182: * <p>
183: * Thus, the following code fragment
184: * <pre>
185: * Math m = new Math();
186: * m.term = new ObjectFactory().createAdd(new Operator());
187: * marshal(m);
188: * </pre>
189: * will produce the following XML output:
190: * <pre>
191: * <math>
192: * <add>...</add>
193: * </math>
194: * </pre>
195: *
196: *
197: * @author <ul><li>Kohsuke Kawaguchi, Sun Microsystems,Inc. </li><li>Sekhar Vajjhala, Sun Microsystems, Inc.</li></ul>
198: * @see XmlElementRefs
199: * @since JAXB2.0
200: */
201: @Retention(RUNTIME)
202: @Target({FIELD,METHOD})
203: public @interface XmlElementRef {
204: /**
205: * The Java type being referenced.
206: * <p>
207: * If the value is DEFAULT.class, the type is inferred from the
208: * the type of the JavaBean property.
209: */
210: Class type() default DEFAULT.class;
211:
212: /**
213: * This parameter and {@link #name()} are used to determine the
214: * XML element for the JavaBean property.
215: *
216: * <p> If <tt>type()</tt> is <tt>JAXBElement.class</tt> , then
217: * <tt>namespace()</tt> and <tt>name()</tt>
218: * point to a factory method with {@link XmlElementDecl}. The XML
219: * element name is the element name from the factory method's
220: * {@link XmlElementDecl} annotation or if an element from its
221: * substitution group (of which it is a head element) has been
222: * substituted in the XML document, then the element name is from the
223: * {@link XmlElementDecl} on the substituted element.
224: *
225: * <p> If {@link #type()} is not <tt>JAXBElement.class</tt>, then
226: * the XML element name is the XML element name statically
227: * associated with the type using the annotation {@link
228: * XmlRootElement} on the type. If the type is not annotated with
229: * an {@link XmlElementDecl}, then it is an error.
230: *
231: * <p> If <tt>type()</tt> is not <tt>JAXBElement.class</tt>, then
232: * this value must be "".
233: *
234: */
235: String namespace() default "";
236:
237: /**
238: *
239: * @see #namespace()
240: */
241: String name() default "##default";
242:
243: /**
244: * Used in {@link XmlElementRef#type()} to
245: * signal that the type be inferred from the signature
246: * of the property.
247: */
248: static final class DEFAULT {
249: }
250: }
|