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<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 * {@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<? extends Operator> term; 187 * } 188 * 189 * @XmlRegistry 190 * class ObjectFactory { 191 * @XmlElementDecl(name="operator") 192 * JAXBElement<Operator> createOperator(Operator o) {...} 193 * @XmlElementDecl(name="add",substitutionHeadName="operator") 194 * JAXBElement<Operator> createAdd(Operator o) {...} 195 * @XmlElementDecl(name="sub",substitutionHeadName="operator") 196 * JAXBElement<Operator> 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 }