1 /*
   2  * Copyright (c) 2004, 2015, 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>{@code
  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&gt; 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  * {@code
 125  *
 126  *     <!-- XML Schema fragment -->
 127  *     <xs:element name="target" type="Target">
 128  *     <xs:complexType name="Target">
 129  *       <xs:sequence>
 130  *         <xs:choice maxOccurs="unbounded">
 131  *           <xs:element ref="jar">
 132  *           <xs:element ref="javac">
 133  *         </xs:choice>
 134  *       </xs:sequence>
 135  *     </xs:complexType>
 136  *
 137  * }</pre>
 138  * <p>
 139  * Thus the following code fragment:
 140  * <pre>
 141  *     Target target = new Target();
 142  *     target.tasks.add(new JarTask());
 143  *     target.tasks.add(new JavacTask());
 144  *     marshal(target);
 145  * </pre>
 146  * will produce the following XML output:
 147  * <pre>{@code
 148  *     <target>
 149  *       <jar>
 150  *         ....
 151  *       </jar>
 152  *       <javac>
 153  *         ....
 154  *       </javac>
 155  *     </target>
 156  * }</pre>
 157  * <p>
 158  * It is not an error to have a class that extends <tt>Task</tt>
 159  * that doesn't have {@link XmlRootElement}. But they can't show up in an
 160  * XML instance (because they don't have XML element names).
 161  *
 162  * <p><b>Example 2: XML Schema Susbstitution group support</b>
 163  * <p> The following example shows the annotations for XML Schema
 164  * substitution groups.  The annotations and the ObjectFactory are
 165  * derived from the schema.
 166  *
 167  * <pre>
 168  *     @XmlElement
 169  *     class Math {
 170  *         //  The value of {@link #type()}is
 171  *         //  JAXBElement.class , which indicates the XML
 172  *         //  element name ObjectFactory - in general a class marked
 173  *         //  with @XmlRegistry. (See ObjectFactory below)
 174  *         //
 175  *         //  The {@link #name()} is "operator", a pointer to a
 176  *         // factory method annotated with a
 177  *         //  {@link XmlElementDecl} with the name "operator". Since
 178  *         //  "operator" is the head of a substitution group that
 179  *         //  contains elements "add" and "sub" elements, "operator"
 180  *         //  element can be substituted in an instance document by
 181  *         //  elements "add" or "sub". At runtime, JAXBElement
 182  *         //  instance contains the element name that has been
 183  *         //  substituted in the XML document.
 184  *         //
 185  *         @XmlElementRef(type=JAXBElement.class,name="operator")
 186  *         JAXBElement&lt;? extends Operator&gt; term;
 187  *     }
 188  *
 189  *     @XmlRegistry
 190  *     class ObjectFactory {
 191  *         @XmlElementDecl(name="operator")
 192  *         JAXBElement&lt;Operator&gt; createOperator(Operator o) {...}
 193  *         @XmlElementDecl(name="add",substitutionHeadName="operator")
 194  *         JAXBElement&lt;Operator&gt; createAdd(Operator o) {...}
 195  *         @XmlElementDecl(name="sub",substitutionHeadName="operator")
 196  *         JAXBElement&lt;Operator&gt; createSub(Operator o) {...}
 197  *     }
 198  *
 199  *     class Operator {
 200  *         ...
 201  *     }
 202  * </pre>
 203  * <p>
 204  * Thus, the following code fragment
 205  * <pre>
 206  *     Math m = new Math();
 207  *     m.term = new ObjectFactory().createAdd(new Operator());
 208  *     marshal(m);
 209  * </pre>
 210  * will produce the following XML output:
 211  * <pre>{@code
 212  *     <math>
 213  *       <add>...</add>
 214  *     </math>
 215  * }</pre>
 216  *
 217  *
 218  * @author <ul><li>Kohsuke Kawaguchi, Sun Microsystems,Inc. </li><li>Sekhar Vajjhala, Sun Microsystems, Inc.</li></ul>
 219  * @see XmlElementRefs
 220  * @since 1.6, JAXB 2.0
 221  */
 222 @Retention(RUNTIME)
 223 @Target({FIELD,METHOD})
 224 public @interface XmlElementRef {
 225     /**
 226      * The Java type being referenced.
 227      * <p>
 228      * If the value is DEFAULT.class, the type is inferred from the
 229      * the type of the JavaBean property.
 230      */
 231     Class type() default DEFAULT.class;
 232 
 233     /**
 234      * This parameter and {@link #name()} are used to determine the
 235      * XML element for the JavaBean property.
 236      *
 237      * <p> If <tt>type()</tt> is <tt>JAXBElement.class</tt> , then
 238      * <tt>namespace()</tt> and <tt>name()</tt>
 239      * point to a factory method with {@link XmlElementDecl}. The XML
 240      * element name is the element name from the factory method's
 241      * {@link XmlElementDecl} annotation or if an element from its
 242      * substitution group (of which it is a head element) has been
 243      * substituted in the XML document, then the element name is from the
 244      * {@link XmlElementDecl} on the substituted element.
 245      *
 246      * <p> If {@link #type()} is not <tt>JAXBElement.class</tt>, then
 247      * the XML element name is the XML element name statically
 248      * associated with the type using the annotation {@link
 249      * XmlRootElement} on the type. If the type is not annotated with
 250      * an {@link XmlElementDecl}, then it is an error.
 251      *
 252      * <p> If <tt>type()</tt> is not <tt>JAXBElement.class</tt>, then
 253      * this value must be "".
 254      *
 255      */
 256     String namespace() default "";
 257     /**
 258      *
 259      * @see #namespace()
 260      */
 261     String name() default "##default";
 262 
 263     /**
 264      * Used in {@link XmlElementRef#type()} to
 265      * signal that the type be inferred from the signature
 266      * of the property.
 267      */
 268     static final class DEFAULT {}
 269 
 270     /**
 271      * Customize the element declaration to be required.
 272      * <p>
 273      * If required() is true, then Javabean property is mapped to
 274      * an XML schema element declaration with minOccurs="1".
 275      * maxOccurs is "1" for a single valued property and "unbounded"
 276      * for a multivalued property.
 277      *
 278      * <p>
 279      * If required() is false, then the Javabean property is mapped
 280      * to XML Schema element declaration with minOccurs="0".
 281      * maxOccurs is "1" for a single valued property and "unbounded"
 282      * for a multivalued property.
 283      *
 284      * <p>
 285      * For compatibility with JAXB 2.1, this property defaults to <tt>true</tt>,
 286      * despite the fact that {@link XmlElement#required()} defaults to false.
 287      *
 288      * @since 1.7, JAXB 2.2
 289      */
 290     boolean required() default true;
 291 }