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