001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.xml.annotation; 014 015import static java.lang.annotation.ElementType.*; 016import static java.lang.annotation.RetentionPolicy.*; 017 018import java.lang.annotation.*; 019 020import org.apache.juneau.annotation.*; 021 022/** 023 * Annotation for specifying various XML options for the XML and RDF/XML serializers. 024 * 025 * <p> 026 * Can be used in the following locations: 027 * <ul> 028 * <li>Marshalled classes/methods/fields/packages. 029 * <li><ja>@Rest</ja>-annotated classes and <ja>@RestOp</ja>-annotated methods when an {@link #on()} value is specified. 030 * </ul> 031 * 032 * <p> 033 * Can be used for the following: 034 * <ul> 035 * <li>Override the child element name on the XML representation of collection or array properties. 036 * <li>Specify the XML namespace on a package, class, or method. 037 * <li>Override the XML format on a POJO. 038 * </ul> 039 * 040 * <h5 class='section'>See Also:</h5><ul> 041 * <li class='link'><a class="doclink" href="../../../../../index.html#jm.XmlDetails">XML Details</a> 042 * </ul> 043 */ 044@Documented 045@Target({TYPE,FIELD,METHOD}) 046@Retention(RUNTIME) 047@Inherited 048@Repeatable(XmlAnnotation.Array.class) 049@ContextApply(XmlAnnotation.Apply.class) 050public @interface Xml { 051 052 /** 053 * Sets the name of the XML child elements for bean properties of type collection and array. 054 * 055 * <p> 056 * Applies only to collection and array bean properties. 057 * 058 * <h5 class='section'>Example:</h5> 059 * <p class='bjava'> 060 * <jk>public class</jk> MyBean { 061 * <ja>@Xml</ja>(childName=<js>"child"</js>} 062 * <jk>public</jk> String[] <jf>children</jf> = {<js>"foo"</js>,<js>"bar"</js>}; 063 * } 064 * </p> 065 * 066 * <p> 067 * Without the <ja>@Xml</ja> annotation, serializing this bean as XML would have produced the following... 068 * <p class='bxml'> 069 * <xt><object></xt> 070 * <xt><children></xt> 071 * <xt><string></xt>foo<xt></string></xt> 072 * <xt><string></xt>bar<xt></string></xt> 073 * <xt></children></xt> 074 * <xt></object></xt> 075 * </p> 076 * 077 * <p> 078 * With the annotations, serializing this bean as XML produces the following... 079 * <p class='bxml'> 080 * <xt><object></xt> 081 * <xt><children></xt> 082 * <xt><child></xt>foo<xt></child></xt> 083 * <xt><child></xt>bar<xt></child></xt> 084 * <xt></children></xt> 085 * <xt></object></xt> 086 * </p> 087 * 088 * @return The annotation value. 089 */ 090 String childName() default ""; 091 092 /** 093 * The {@link XmlFormat} to use for serializing this object type. 094 * 095 * <h5 class='section'>Example:</h5> 096 * <p class='bjava'> 097 * <jk>public class</jk> MyBean { 098 * 099 * <jc>// Normally, bean properties would be rendered as child elements of the bean element.</jc> 100 * <jc>// Override so that it's rendered as a "f1='123'" attribute on the bean element instead.</jc> 101 * <ja>@Xml</ja>(format=XmlFormat.<jsf>ATTR</jsf>} 102 * <jk>public int</jk> <jf>f1</jf> = 123; 103 * 104 * <jc>// Normally, bean URL properties would be rendered as XML attributes on the bean element.</jc> 105 * <jc>// Override so that it's rendered as an <href>http://foo</href> child element instead.</jc> 106 * <ja>@Beanp</ja>(uri=<jk>true</jk>) 107 * <ja>@Xml</ja>(format=XmlFormat.<jsf>ELEMENT</jsf>} 108 * <jk>public</jk> URL <jf>href</jf> = <jk>new</jk> URL(<js>"http://foo"</js>); 109 * 110 * <jc>// Normally, collection properties would be grouped under a single <children> child element on the bean element.</jc> 111 * <jc>// Override so that entries are directly children of the bean element with each entry having an element name of <child>.</jc> 112 * <ja>@Xml</ja>(format=XmlFormat.<jsf>COLLAPSED</jsf>, childName=<js>"child"</js>} 113 * <jk>public</jk> String[] <jf>children</jf> = <js>"foo"</js>,<js>"bar"</js>}; 114 * } 115 * </p> 116 * 117 * <p> 118 * Without the <ja>@Xml</ja> annotations, serializing this bean as XML would have produced the following... 119 * <p class='bxml'> 120 * <xt><object</xt> <xa>href</xa>=<js>'http://foo'</js><xt>></xt> 121 * <xt><f1></xt>123<xt></f1></xt> 122 * <xt><children></xt> 123 * <xt><string></xt>foo<xt></string></xt> 124 * <xt><string></xt>bar<xt></string></xt> 125 * <xt></children></xt> 126 * <xt></object></xt> 127 * </p> 128 * 129 * <p> 130 * With the annotations, serializing this bean as XML produces the following... 131 * <p class='bxml'> 132 * <xt><object</xt> <xa>f1</xa>=<js>'123'</js><xt>></xt> 133 * <xt><href></xt>http://foo<xt></href></xt> 134 * <xt><child></xt>foo<xt></child></xt> 135 * <xt><child></xt>bar<xt></child></xt> 136 * <xt></object></xt> 137 * </p> 138 * 139 * @return The annotation value. 140 */ 141 XmlFormat format() default XmlFormat.DEFAULT; 142 143 /** 144 * Sets the namespace URI of this property or class. 145 * 146 * <p> 147 * Must be matched with a {@link #prefix()} annotation on this object, a parent object, or a {@link XmlNs @XmlNs} with the 148 * same name through the {@link XmlSchema#xmlNs() @XmlSchema(xmlNs)} annotation on the package. 149 * 150 * @return The annotation value. 151 */ 152 String namespace() default ""; 153 154 /** 155 * Dynamically apply this annotation to the specified classes/methods/fields. 156 * 157 * <p> 158 * Used in conjunction with {@link org.apache.juneau.BeanContext.Builder#applyAnnotations(Class...)} to dynamically apply an annotation to an existing class/method/field. 159 * It is ignored when the annotation is applied directly to classes/methods/fields. 160 * 161 * <h5 class='section'>Valid patterns:</h5> 162 * <ul class='spaced-list'> 163 * <li>Classes: 164 * <ul> 165 * <li>Fully qualified: 166 * <ul> 167 * <li><js>"com.foo.MyClass"</js> 168 * </ul> 169 * <li>Fully qualified inner class: 170 * <ul> 171 * <li><js>"com.foo.MyClass$Inner1$Inner2"</js> 172 * </ul> 173 * <li>Simple: 174 * <ul> 175 * <li><js>"MyClass"</js> 176 * </ul> 177 * <li>Simple inner: 178 * <ul> 179 * <li><js>"MyClass$Inner1$Inner2"</js> 180 * <li><js>"Inner1$Inner2"</js> 181 * <li><js>"Inner2"</js> 182 * </ul> 183 * </ul> 184 * <li>Methods: 185 * <ul> 186 * <li>Fully qualified with args: 187 * <ul> 188 * <li><js>"com.foo.MyClass.myMethod(String,int)"</js> 189 * <li><js>"com.foo.MyClass.myMethod(java.lang.String,int)"</js> 190 * <li><js>"com.foo.MyClass.myMethod()"</js> 191 * </ul> 192 * <li>Fully qualified: 193 * <ul> 194 * <li><js>"com.foo.MyClass.myMethod"</js> 195 * </ul> 196 * <li>Simple with args: 197 * <ul> 198 * <li><js>"MyClass.myMethod(String,int)"</js> 199 * <li><js>"MyClass.myMethod(java.lang.String,int)"</js> 200 * <li><js>"MyClass.myMethod()"</js> 201 * </ul> 202 * <li>Simple: 203 * <ul> 204 * <li><js>"MyClass.myMethod"</js> 205 * </ul> 206 * <li>Simple inner class: 207 * <ul> 208 * <li><js>"MyClass$Inner1$Inner2.myMethod"</js> 209 * <li><js>"Inner1$Inner2.myMethod"</js> 210 * <li><js>"Inner2.myMethod"</js> 211 * </ul> 212 * </ul> 213 * <li>Fields: 214 * <ul> 215 * <li>Fully qualified: 216 * <ul> 217 * <li><js>"com.foo.MyClass.myField"</js> 218 * </ul> 219 * <li>Simple: 220 * <ul> 221 * <li><js>"MyClass.myField"</js> 222 * </ul> 223 * <li>Simple inner class: 224 * <ul> 225 * <li><js>"MyClass$Inner1$Inner2.myField"</js> 226 * <li><js>"Inner1$Inner2.myField"</js> 227 * <li><js>"Inner2.myField"</js> 228 * </ul> 229 * </ul> 230 * <li>A comma-delimited list of anything on this list. 231 * </ul> 232 * 233 * <h5 class='section'>See Also:</h5><ul> 234 * <li class='link'><a class="doclink" href="../../../../../index.html#jm.DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a> 235 * </ul> 236 * 237 * @return The annotation value. 238 */ 239 String[] on() default {}; 240 241 /** 242 * Dynamically apply this annotation to the specified classes. 243 * 244 * <p> 245 * Identical to {@link #on()} except allows you to specify class objects instead of a strings. 246 * 247 * <h5 class='section'>See Also:</h5><ul> 248 * <li class='link'><a class="doclink" href="../../../../../index.html#jm.DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a> 249 * </ul> 250 * 251 * @return The annotation value. 252 */ 253 Class<?>[] onClass() default {}; 254 255 /** 256 * Sets the XML prefix of this property or class. 257 * 258 * <ul class='spaced-list'> 259 * <li> 260 * When applied to a {@link ElementType#TYPE}, namespace is applied to all properties in the class, and all 261 * subclasses of the class. 262 * <li> 263 * When applied to bean properties on {@link ElementType#METHOD} and {@link ElementType#FIELD}, applies 264 * to the bean property. 265 * </ul> 266 * 267 * <p> 268 * Must either be matched to a {@link #namespace()} annotation on the same object, parent object, or a 269 * {@link XmlNs @XmlNs} with the same name through the {@link XmlSchema#xmlNs() @XmlSchema(xmlNs)} annotation on the package. 270 * 271 * @return The annotation value. 272 */ 273 String prefix() default ""; 274}