1 /*
   2  * Copyright (c) 2004, 2013, 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 
  26 package javax.xml.bind.annotation;
  27 
  28 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
  29 import java.lang.annotation.Retention;
  30 import java.lang.annotation.Target;
  31 
  32 import static java.lang.annotation.RetentionPolicy.RUNTIME;
  33 import static java.lang.annotation.ElementType.FIELD;
  34 import static java.lang.annotation.ElementType.METHOD;
  35 
  36 /**
  37  * <p>
  38  * Maps a JavaBean property to a XML element derived from property's type.
  39  * <p>
  40  * <b>Usage</b>
  41  * <p>
  42  * <tt>@XmlElementRef</tt> annotation can be used with a
  43  * JavaBean property or from within {@link XmlElementRefs}
  44  * <p>
  45  * This annotation dynamically associates an XML element name with the JavaBean
  46  * property. When a JavaBean property is annotated with {@link
  47  * XmlElement}, the XML element name is statically derived from the
  48  * JavaBean property name. However, when this annotation is used, the
  49  * XML element name is derived from the instance of the type of the
  50  * JavaBean property at runtime.
  51  *
  52  * <h3> XML Schema substitution group support </h3>
  53  * XML Schema allows a XML document author to use XML element names
  54  * that were not statically specified in the content model of a
  55  * schema using substitution groups. Schema derived code provides
  56  * support for substitution groups using an <i>element property</i>,
  57  * (section 5.5.5, "Element Property" of JAXB 2.0 specification). An
  58  * element property method signature is of the form:
  59  * <pre>
  60  *     public void setTerm(JAXBElement<? extends Operator>);
  61  *     public JAXBElement<? extends Operator> getTerm();
  62  * </pre>
  63  * <p>
  64  * An element factory method annotated with  {@link XmlElementDecl} is
  65  * used to create a <tt>JAXBElement</tt> instance, containing an XML
  66  * element name. The presence of @XmlElementRef annotation on an
  67  * element property indicates that the element name from <tt>JAXBElement</tt>
  68  * instance be used instead of deriving an XML element name from the
  69  * JavaBean property name.
  70  *
  71  * <p>
  72  * The usage is subject to the following constraints:
  73  * <ul>
  74  *   <li> If the collection item type (for collection property) or
  75  *        property type (for single valued property) is
  76  *        {@link javax.xml.bind.JAXBElement}, then
  77  *        <tt>@XmlElementRef}.name()</tt> and <tt>@XmlElementRef.namespace()</tt> must
  78  *        point an element factory method  with an @XmlElementDecl
  79  *        annotation in a class annotated  with @XmlRegistry (usually
  80  *        ObjectFactory class generated by  the schema compiler) :
  81  *        <ul>
  82  *            <li> @XmlElementDecl.name() must equal @XmlElementRef.name()  </li>
  83  *            <li> @XmlElementDecl.namespace() must equal @XmlElementRef.namespace(). </li>
  84  *        </ul>
  85  *   </li>
  86  *   <li> If the collection item type (for collection property) or
  87  *        property type  (for single valued property) is not
  88  *        {@link javax.xml.bind.JAXBElement}, then the type referenced by the
  89  *        property or field must be annotated  with {@link XmlRootElement}. </li>
  90  *   <li> This annotation can be used with the following annotations:
  91  *        {@link XmlElementWrapper}, {@link XmlJavaTypeAdapter}.
  92  *   </ul>
  93  *
  94  * <p>See "Package Specification" in javax.xml.bind.package javadoc for
  95  * additional common information.</p>
  96  *
  97  * <p><b>Example 1: Ant Task Example</b></p>
  98  * The following Java class hierarchy models an Ant build
  99  * script.  An Ant task corresponds to a class in the class
 100  * hierarchy. The XML element name of an Ant task is indicated by the
 101  * @XmlRootElement annotation on its corresponding class.
 102  * <pre>
 103  *     @XmlRootElement(name="target")
 104  *     class Target {
 105  *         // The presence of @XmlElementRef indicates that the XML
 106  *         // element name will be derived from the @XmlRootElement
 107  *         // annotation on the type (for e.g. "jar" for JarTask).
 108  *         @XmlElementRef
 109  *         List&lt;Task> tasks;
 110  *     }
 111  *
 112  *     abstract class Task {
 113  *     }
 114  *
 115  *     @XmlRootElement(name="jar")
 116  *     class JarTask extends Task {
 117  *         ...
 118  *     }
 119  *
 120  *     @XmlRootElement(name="javac")
 121  *     class JavacTask extends Task {
 122  *         ...
 123  *     }
 124  *
 125  *     &lt;!-- XML Schema fragment -->
 126  *     &lt;xs:element name="target" type="Target">
 127  *     &lt;xs:complexType name="Target">
 128  *       &lt;xs:sequence>
 129  *         &lt;xs:choice maxOccurs="unbounded">
 130  *           &lt;xs:element ref="jar">
 131  *           &lt;xs:element ref="javac">
 132  *         &lt;/xs:choice>
 133  *       &lt;/xs:sequence>
 134  *     &lt;/xs:complexType>
 135  *
 136  * </pre>
 137  * <p>
 138  * Thus the following code fragment:
 139  * <pre>
 140  *     Target target = new Target();
 141  *     target.tasks.add(new JarTask());
 142  *     target.tasks.add(new JavacTask());
 143  *     marshal(target);
 144  * </pre>
 145  * will produce the following XML output:
 146  * <pre>
 147  *     &lt;target>
 148  *       &lt;jar>
 149  *         ....
 150  *       &lt;/jar>
 151  *       &lt;javac>
 152  *         ....
 153  *       &lt;/javac>
 154  *     &lt;/target>
 155  * </pre>
 156  * <p>
 157  * It is not an error to have a class that extends <tt>Task</tt>
 158  * that doesn't have {@link XmlRootElement}. But they can't show up in an
 159  * XML instance (because they don't have XML element names).
 160  *
 161  * <p><b>Example 2: XML Schema Susbstitution group support</b>
 162  * <p> The following example shows the annotations for XML Schema
 163  * substitution groups.  The annotations and the ObjectFactory are
 164  * derived from the schema.
 165  *
 166  * <pre>
 167  *     @XmlElement
 168  *     class Math {
 169  *         //  The value of {@link #type()}is
 170  *         //  JAXBElement.class , which indicates the XML
 171  *         //  element name ObjectFactory - in general a class marked
 172  *         //  with @XmlRegistry. (See ObjectFactory below)
 173  *         //
 174  *         //  The {@link #name()} is "operator", a pointer to a
 175  *         // factory method annotated with a
 176  *         //  {@link XmlElementDecl} with the name "operator". Since
 177  *         //  "operator" is the head of a substitution group that
 178  *         //  contains elements "add" and "sub" elements, "operator"
 179  *         //  element can be substituted in an instance document by
 180  *         //  elements "add" or "sub". At runtime, JAXBElement
 181  *         //  instance contains the element name that has been
 182  *         //  substituted in the XML document.
 183  *         //
 184  *         @XmlElementRef(type=JAXBElement.class,name="operator")
 185  *         JAXBElement&lt;? extends Operator> term;
 186  *     }
 187  *
 188  *     @XmlRegistry
 189  *     class ObjectFactory {
 190  *         @XmlElementDecl(name="operator")
 191  *         JAXBElement&lt;Operator> createOperator(Operator o) {...}
 192  *         @XmlElementDecl(name="add",substitutionHeadName="operator")
 193  *         JAXBElement&lt;Operator> createAdd(Operator o) {...}
 194  *         @XmlElementDecl(name="sub",substitutionHeadName="operator")
 195  *         JAXBElement&lt;Operator> createSub(Operator o) {...}
 196  *     }
 197  *
 198  *     class Operator {
 199  *         ...
 200  *     }
 201  * </pre>
 202  * <p>
 203  * Thus, the following code fragment
 204  * <pre>
 205  *     Math m = new Math();
 206  *     m.term = new ObjectFactory().createAdd(new Operator());
 207  *     marshal(m);
 208  * </pre>
 209  * will produce the following XML output:
 210  * <pre>
 211  *     &lt;math>
 212  *       &lt;add>...&lt;/add>
 213  *     &lt;/math>
 214  * </pre>
 215  *
 216  *
 217  * @author <ul><li>Kohsuke Kawaguchi, Sun Microsystems,Inc. </li><li>Sekhar Vajjhala, Sun Microsystems, Inc.</li></ul>
 218  * @see XmlElementRefs
 219  * @since JAXB2.0
 220  */
 221 @Retention(RUNTIME)
 222 @Target({FIELD,METHOD})
 223 public @interface XmlElementRef {
 224     /**
 225      * The Java type being referenced.
 226      * <p>
 227      * If the value is DEFAULT.class, the type is inferred from the
 228      * the type of the JavaBean property.
 229      */
 230     Class type() default DEFAULT.class;
 231 
 232     /**
 233      * This parameter and {@link #name()} are used to determine the
 234      * XML element for the JavaBean property.
 235      *
 236      * <p> If <tt>type()</tt> is <tt>JAXBElement.class</tt> , then
 237      * <tt>namespace()</tt> and <tt>name()</tt>
 238      * point to a factory method with {@link XmlElementDecl}. The XML
 239      * element name is the element name from the factory method's
 240      * {@link XmlElementDecl} annotation or if an element from its
 241      * substitution group (of which it is a head element) has been
 242      * substituted in the XML document, then the element name is from the
 243      * {@link XmlElementDecl} on the substituted element.
 244      *
 245      * <p> If {@link #type()} is not <tt>JAXBElement.class</tt>, then
 246      * the XML element name is the XML element name statically
 247      * associated with the type using the annotation {@link
 248      * XmlRootElement} on the type. If the type is not annotated with
 249      * an {@link XmlElementDecl}, then it is an error.
 250      *
 251      * <p> If <tt>type()</tt> is not <tt>JAXBElement.class</tt>, then
 252      * this value must be "".
 253      *
 254      */
 255     String namespace() default "";
 256     /**
 257      *
 258      * @see #namespace()
 259      */
 260     String name() default "##default";
 261 
 262     /**
 263      * Used in {@link XmlElementRef#type()} to
 264      * signal that the type be inferred from the signature
 265      * of the property.
 266      */
 267     static final class DEFAULT {}
 268 
 269     /**
 270      * Customize the element declaration to be required.
 271      * <p>
 272      * If required() is true, then Javabean property is mapped to
 273      * an XML schema element declaration with minOccurs="1".
 274      * maxOccurs is "1" for a single valued property and "unbounded"
 275      * for a multivalued property.
 276      *
 277      * <p>
 278      * If required() is false, then the Javabean property is mapped
 279      * to XML Schema element declaration with minOccurs="0".
 280      * maxOccurs is "1" for a single valued property and "unbounded"
 281      * for a multivalued property.
 282      *
 283      * <p>
 284      * For compatibility with JAXB 2.1, this property defaults to <tt>true</tt>,
 285      * despite the fact that {@link XmlElement#required()} defaults to false.
 286      *
 287      * @since 2.2
 288      */
 289     boolean required() default true;
 290 }