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.http.annotation; 014 015import static org.apache.juneau.common.internal.StringUtils.*; 016import static org.apache.juneau.internal.ArrayUtils.*; 017import static java.lang.annotation.ElementType.*; 018import static java.lang.annotation.RetentionPolicy.*; 019import java.lang.annotation.*; 020import java.lang.reflect.*; 021import org.apache.juneau.*; 022import org.apache.juneau.annotation.*; 023import org.apache.juneau.httppart.*; 024import org.apache.juneau.reflect.*; 025import org.apache.juneau.svl.*; 026 027/** 028 * Utility classes and methods for the {@link FormData @FormData} annotation. 029 * 030 * <h5 class='section'>See Also:</h5><ul> 031 * </ul> 032 */ 033public class FormDataAnnotation { 034 035 //----------------------------------------------------------------------------------------------------------------- 036 // Static 037 //----------------------------------------------------------------------------------------------------------------- 038 039 /** Default value */ 040 public static final FormData DEFAULT = create().build(); 041 042 /** 043 * Instantiates a new builder for this class. 044 * 045 * @return A new builder object. 046 */ 047 public static Builder create() { 048 return new Builder(); 049 } 050 051 /** 052 * Instantiates a new builder for this class. 053 * 054 * @param on The targets this annotation applies to. 055 * @return A new builder object. 056 */ 057 public static Builder create(Class<?>...on) { 058 return create().on(on); 059 } 060 061 /** 062 * Instantiates a new builder for this class. 063 * 064 * @param on The targets this annotation applies to. 065 * @return A new builder object. 066 */ 067 public static Builder create(String...on) { 068 return create().on(on); 069 } 070 071 /** 072 * Returns <jk>true</jk> if the specified annotation contains all default values. 073 * 074 * @param a The annotation to check. 075 * @return <jk>true</jk> if the specified annotation contains all default values. 076 */ 077 public static boolean empty(FormData a) { 078 return a == null || DEFAULT.equals(a); 079 } 080 081 /** 082 * Finds the name from the specified lists of annotations. 083 * 084 * <p> 085 * The last matching name found is returned. 086 * 087 * @param pi The parameter. 088 * @return The last matching name, or {@link Value#empty()} if not found. 089 */ 090 public static Value<String> findName(ParamInfo pi) { 091 Value<String> n = Value.empty(); 092 pi.forEachAnnotation(FormData.class, x -> isNotEmpty(x.value()), x -> n.set(x.value())); 093 pi.forEachAnnotation(FormData.class, x -> isNotEmpty(x.name()), x -> n.set(x.name())); 094 return n; 095 } 096 097 /** 098 * Finds the default value from the specified list of annotations. 099 * 100 * @param pi The parameter. 101 * @return The last matching default value, or {@link Value#empty()} if not found. 102 */ 103 public static Value<String> findDef(ParamInfo pi) { 104 Value<String> n = Value.empty(); 105 pi.forEachAnnotation(FormData.class, x -> isNotEmpty(x.def()), x -> n.set(x.def())); 106 return n; 107 } 108 109 //----------------------------------------------------------------------------------------------------------------- 110 // Builder 111 //----------------------------------------------------------------------------------------------------------------- 112 113 /** 114 * Builder class. 115 * 116 * <h5 class='section'>See Also:</h5><ul> 117 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#annotations(Annotation...)} 118 * </ul> 119 */ 120 public static class Builder extends TargetedAnnotationTMFBuilder { 121 122 Class<? extends HttpPartParser> parser = HttpPartParser.Void.class; 123 Class<? extends HttpPartSerializer> serializer = HttpPartSerializer.Void.class; 124 Schema schema = SchemaAnnotation.DEFAULT; 125 String def="", name="", value=""; 126 127 /** 128 * Constructor. 129 */ 130 protected Builder() { 131 super(FormData.class); 132 } 133 134 /** 135 * Instantiates a new {@link FormData @FormData} object initialized with this builder. 136 * 137 * @return A new {@link FormData @FormData} object. 138 */ 139 public FormData build() { 140 return new Impl(this); 141 } 142 143 /** 144 * Sets the {@link FormData#def} property on this annotation. 145 * 146 * @param value The new value for this property. 147 * @return This object. 148 */ 149 public Builder def(String value) { 150 this.def = value; 151 return this; 152 } 153 154 /** 155 * Sets the {@link FormData#name} property on this annotation. 156 * 157 * @param value The new value for this property. 158 * @return This object. 159 */ 160 public Builder name(String value) { 161 this.name = value; 162 return this; 163 } 164 165 /** 166 * Sets the {@link FormData#parser} property on this annotation. 167 * 168 * @param value The new value for this property. 169 * @return This object. 170 */ 171 public Builder parser(Class<? extends HttpPartParser> value) { 172 this.parser = value; 173 return this; 174 } 175 176 /** 177 * Sets the {@link FormData#schema} property on this annotation. 178 * 179 * @param value The new value for this property. 180 * @return This object. 181 */ 182 public Builder schema(Schema value) { 183 this.schema = value; 184 return this; 185 } 186 187 /** 188 * Sets the {@link FormData#serializer} property on this annotation. 189 * 190 * @param value The new value for this property. 191 * @return This object. 192 */ 193 public Builder serializer(Class<? extends HttpPartSerializer> value) { 194 this.serializer = value; 195 return this; 196 } 197 198 /** 199 * Sets the {@link FormData#value} property on this annotation. 200 * 201 * @param value The new value for this property. 202 * @return This object. 203 */ 204 public Builder value(String value) { 205 this.value = value; 206 return this; 207 } 208 209 // <FluentSetters> 210 211 @Override /* GENERATED - TargetedAnnotationBuilder */ 212 public Builder on(String...values) { 213 super.on(values); 214 return this; 215 } 216 217 @Override /* GENERATED - TargetedAnnotationTBuilder */ 218 public Builder on(java.lang.Class<?>...value) { 219 super.on(value); 220 return this; 221 } 222 223 @Override /* GENERATED - TargetedAnnotationTBuilder */ 224 public Builder onClass(java.lang.Class<?>...value) { 225 super.onClass(value); 226 return this; 227 } 228 229 @Override /* GENERATED - TargetedAnnotationTMFBuilder */ 230 public Builder on(Field...value) { 231 super.on(value); 232 return this; 233 } 234 235 @Override /* GENERATED - TargetedAnnotationTMFBuilder */ 236 public Builder on(Method...value) { 237 super.on(value); 238 return this; 239 } 240 241 // </FluentSetters> 242 } 243 244 //----------------------------------------------------------------------------------------------------------------- 245 // Implementation 246 //----------------------------------------------------------------------------------------------------------------- 247 248 private static class Impl extends TargetedAnnotationTImpl implements FormData { 249 250 private final Class<? extends HttpPartParser> parser; 251 private final Class<? extends HttpPartSerializer> serializer; 252 private final String name, value, def; 253 private final Schema schema; 254 255 Impl(Builder b) { 256 super(b); 257 this.def = b.def; 258 this.name = b.name; 259 this.parser = b.parser; 260 this.schema = b.schema; 261 this.serializer = b.serializer; 262 this.value = b.value; 263 postConstruct(); 264 } 265 266 @Override /* FormData */ 267 public String def() { 268 return def; 269 } 270 271 @Override /* FormData */ 272 public String name() { 273 return name; 274 } 275 276 @Override /* FormData */ 277 public Class<? extends HttpPartParser> parser() { 278 return parser; 279 } 280 281 @Override /* FormData */ 282 public Schema schema() { 283 return schema; 284 } 285 286 @Override /* FormData */ 287 public Class<? extends HttpPartSerializer> serializer() { 288 return serializer; 289 } 290 291 @Override 292 public String value() { 293 return value; 294 } 295 } 296 297 //----------------------------------------------------------------------------------------------------------------- 298 // Appliers 299 //----------------------------------------------------------------------------------------------------------------- 300 301 /** 302 * Applies targeted {@link FormData} annotations to a {@link org.apache.juneau.BeanContext.Builder}. 303 */ 304 public static class Applier extends AnnotationApplier<FormData,BeanContext.Builder> { 305 306 /** 307 * Constructor. 308 * 309 * @param vr The resolver for resolving values in annotations. 310 */ 311 public Applier(VarResolverSession vr) { 312 super(FormData.class, BeanContext.Builder.class, vr); 313 } 314 315 @Override 316 public void apply(AnnotationInfo<FormData> ai, BeanContext.Builder b) { 317 FormData a = ai.inner(); 318 if (isEmptyArray(a.on(), a.onClass())) 319 return; 320 b.annotations(a); 321 } 322 } 323 324 //----------------------------------------------------------------------------------------------------------------- 325 // Other 326 //----------------------------------------------------------------------------------------------------------------- 327 328 /** 329 * A collection of {@link FormData @FormData annotations}. 330 */ 331 @Documented 332 @Target({METHOD,TYPE}) 333 @Retention(RUNTIME) 334 @Inherited 335 public static @interface Array { 336 337 /** 338 * The child annotations. 339 * 340 * @return The annotation value. 341 */ 342 FormData[] value(); 343 } 344}