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.*; 021import static org.apache.juneau.commons.utils.CollectionUtils.*; 022 023import java.lang.annotation.*; 024import java.lang.reflect.*; 025 026import org.apache.juneau.*; 027import org.apache.juneau.commons.annotation.*; 028import org.apache.juneau.commons.reflect.*; 029import org.apache.juneau.svl.*; 030 031/** 032 * Utility classes and methods for the {@link Xml @Xml} annotation. 033 * 034 * <h5 class='section'>See Also:</h5><ul> 035 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/XmlBasics">XML Basics</a> 036 * </ul> 037 */ 038public class XmlAnnotation { 039 /** 040 * Applies targeted {@link Xml} annotations to a {@link org.apache.juneau.Context.Builder}. 041 */ 042 public static class Apply extends AnnotationApplier<Xml,Context.Builder> { 043 044 /** 045 * Constructor. 046 * 047 * @param vr The resolver for resolving values in annotations. 048 */ 049 public Apply(VarResolverSession vr) { 050 super(Xml.class, Context.Builder.class, vr); 051 } 052 053 @Override 054 public void apply(AnnotationInfo<Xml> ai, Context.Builder b) { 055 Xml a = ai.inner(); 056 if (isEmptyArray(a.on()) && isEmptyArray(a.onClass())) 057 return; 058 b.annotations(copy(a, vr())); 059 } 060 } 061 062 /** 063 * A collection of {@link Xml @Xml annotations}. 064 */ 065 @Documented 066 @Target({ METHOD, TYPE }) 067 @Retention(RUNTIME) 068 @Inherited 069 public static @interface Array { 070 071 /** 072 * The child annotations. 073 * 074 * @return The annotation value. 075 */ 076 Xml[] value(); 077 } 078 079 /** 080 * Builder class. 081 * 082 * <h5 class='section'>See Also:</h5><ul> 083 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#annotations(Annotation...)} 084 * </ul> 085 */ 086 public static class Builder extends AppliedAnnotationObject.BuilderTMF { 087 088 private String[] description = {}; 089 private String childName = "", namespace = "", prefix = ""; 090 private XmlFormat format = XmlFormat.DEFAULT; 091 092 /** 093 * Constructor. 094 */ 095 protected Builder() { 096 super(Xml.class); 097 } 098 099 /** 100 * Instantiates a new {@link Xml @Xml} object initialized with this builder. 101 * 102 * @return A new {@link Xml @Xml} object. 103 */ 104 public Xml build() { 105 return new Object(this); 106 } 107 108 /** 109 * Sets the description property on this annotation. 110 * 111 * @param value The new value for this property. 112 * @return This object. 113 */ 114 public Builder description(String...value) { 115 description = value; 116 return this; 117 } 118 119 /** 120 * Sets the {@link Xml#childName} property on this annotation. 121 * 122 * @param value The new value for this property. 123 * @return This object. 124 */ 125 public Builder childName(String value) { 126 childName = value; 127 return this; 128 } 129 130 /** 131 * Sets the {@link Xml#format} property on this annotation. 132 * 133 * @param value The new value for this property. 134 * @return This object. 135 */ 136 public Builder format(XmlFormat value) { 137 format = value; 138 return this; 139 } 140 141 /** 142 * Sets the {@link Xml#namespace} property on this annotation. 143 * 144 * @param value The new value for this property. 145 * @return This object. 146 */ 147 public Builder namespace(String value) { 148 namespace = value; 149 return this; 150 } 151 152 /** 153 * Sets the {@link Xml#prefix} property on this annotation. 154 * 155 * @param value The new value for this property. 156 * @return This object. 157 */ 158 public Builder prefix(String value) { 159 prefix = value; 160 return this; 161 } 162 163 @Override /* Overridden from AppliedAnnotationObject.Builder */ 164 public Builder on(String...value) { 165 super.on(value); 166 return this; 167 } 168 169 @Override /* Overridden from AppliedAnnotationObject.BuilderT */ 170 public Builder on(Class<?>...value) { 171 super.on(value); 172 return this; 173 } 174 175 @Override /* Overridden from AppliedOnClassAnnotationObject.Builder */ 176 public Builder onClass(Class<?>...value) { 177 super.onClass(value); 178 return this; 179 } 180 181 @Override /* Overridden from AppliedAnnotationObject.BuilderM */ 182 public Builder on(Method...value) { 183 super.on(value); 184 return this; 185 } 186 187 @Override /* Overridden from AppliedAnnotationObject.BuilderMF */ 188 public Builder on(Field...value) { 189 super.on(value); 190 return this; 191 } 192 193 @Override /* Overridden from AppliedAnnotationObject.BuilderT */ 194 public Builder on(ClassInfo...value) { 195 super.on(value); 196 return this; 197 } 198 199 @Override /* Overridden from AppliedAnnotationObject.BuilderT */ 200 public Builder onClass(ClassInfo...value) { 201 super.onClass(value); 202 return this; 203 } 204 205 @Override /* Overridden from AppliedAnnotationObject.BuilderTMF */ 206 public Builder on(FieldInfo...value) { 207 super.on(value); 208 return this; 209 } 210 211 @Override /* Overridden from AppliedAnnotationObject.BuilderTMF */ 212 public Builder on(MethodInfo...value) { 213 super.on(value); 214 return this; 215 } 216 217 } 218 219 private static class Object extends AppliedOnClassAnnotationObject implements Xml { 220 221 private final String[] description; 222 private final String childName, namespace, prefix; 223 private final XmlFormat format; 224 225 Object(XmlAnnotation.Builder b) { 226 super(b); 227 description = copyOf(b.description); 228 childName = b.childName; 229 format = b.format; 230 namespace = b.namespace; 231 prefix = b.prefix; 232 } 233 234 @Override /* Overridden from Xml */ 235 public String childName() { 236 return childName; 237 } 238 239 @Override /* Overridden from Xml */ 240 public XmlFormat format() { 241 return format; 242 } 243 244 @Override /* Overridden from Xml */ 245 public String namespace() { 246 return namespace; 247 } 248 249 @Override /* Overridden from Xml */ 250 public String prefix() { 251 return prefix; 252 } 253 254 @Override /* Overridden from annotation */ 255 public String[] description() { 256 return description; 257 } 258 } 259 260 /** Default value */ 261 public static final Xml DEFAULT = create().build(); 262 263 /** 264 * Creates a copy of the specified annotation. 265 * 266 * @param a The annotation to copy.s 267 * @param r The var resolver for resolving any variables. 268 * @return A copy of the specified annotation. 269 */ 270 public static Xml copy(Xml a, VarResolverSession r) { 271 // @formatter:off 272 return 273 create() 274 .childName(r.resolve(a.childName())) 275 .format(a.format()) 276 .namespace(r.resolve(a.namespace())) 277 .on(r.resolve(a.on())) 278 .onClass(a.onClass()) 279 .prefix(r.resolve(a.prefix())) 280 .build(); 281 // @formatter:on 282 } 283 284 /** 285 * Instantiates a new builder for this class. 286 * 287 * @return A new builder object. 288 */ 289 public static Builder create() { 290 return new Builder(); 291 } 292 293 /** 294 * Instantiates a new builder for this class. 295 * 296 * @param on The targets this annotation applies to. 297 * @return A new builder object. 298 */ 299 public static Builder create(Class<?>...on) { 300 return create().on(on); 301 } 302 303 /** 304 * Instantiates a new builder for this class. 305 * 306 * @param on The targets this annotation applies to. 307 * @return A new builder object. 308 */ 309 public static Builder create(String...on) { 310 return create().on(on); 311 } 312}