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.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.*; 024 025import org.apache.juneau.*; 026import org.apache.juneau.commons.annotation.*; 027import org.apache.juneau.commons.reflect.*; 028import org.apache.juneau.svl.*; 029import org.apache.juneau.swap.*; 030 031/** 032 * Utility classes and methods for the {@link Bean @Bean} annotation. 033 * 034 */ 035public class BeanAnnotation { 036 /** 037 * Applies targeted {@link Bean} annotations to a {@link org.apache.juneau.BeanContext.Builder}. 038 */ 039 public static class Applier extends AnnotationApplier<Bean,BeanContext.Builder> { 040 041 /** 042 * Constructor. 043 * 044 * @param vr The resolver for resolving values in annotations. 045 */ 046 public Applier(VarResolverSession vr) { 047 super(Bean.class, BeanContext.Builder.class, vr); 048 } 049 050 @Override 051 public void apply(AnnotationInfo<Bean> ai, BeanContext.Builder b) { 052 Bean a = ai.inner(); 053 if (isEmptyArray(a.on()) && isEmptyArray(a.onClass())) 054 return; 055 b.annotations(copy(a, vr())); 056 } 057 } 058 059 /** 060 * A collection of {@link Bean @Bean annotations}. 061 */ 062 @Documented 063 @Target({ METHOD, TYPE }) 064 @Retention(RUNTIME) 065 @Inherited 066 public static @interface Array { 067 068 /** 069 * The child annotations. 070 * 071 * @return The annotation value. 072 */ 073 Bean[] value(); 074 } 075 076 /** 077 * Builder class. 078 * 079 * <h5 class='section'>See Also:</h5><ul> 080 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#annotations(Annotation...)} 081 * </ul> 082 */ 083 public static class Builder extends AppliedAnnotationObject.BuilderT { 084 085 private String[] description = {}; 086 private Class<?>[] dictionary = new Class[0]; 087 private Class<?> implClass = void.class; 088 private Class<?> interfaceClass = void.class; 089 private Class<?> stopClass = void.class; 090 private Class<? extends BeanInterceptor<?>> interceptor = BeanInterceptor.Void.class; 091 private Class<? extends PropertyNamer> propertyNamer = BasicPropertyNamer.class; 092 private String example = "", excludeProperties = "", p = "", properties = "", readOnlyProperties = "", ro = "", typeName = "", typePropertyName = "", wo = "", writeOnlyProperties = "", 093 xp = ""; 094 private boolean findFluentSetters, sort; 095 096 /** 097 * Constructor. 098 */ 099 protected Builder() { 100 super(Bean.class); 101 } 102 103 /** 104 * Instantiates a new {@link Bean @Bean} object initialized with this builder. 105 * 106 * @return A new {@link Bean @Bean} object. 107 */ 108 public Bean build() { 109 return new Object(this); 110 } 111 112 /** 113 * Sets the description property on this annotation. 114 * 115 * @param value The new value for this property. 116 * @return This object. 117 */ 118 public Builder description(String...value) { 119 description = value; 120 return this; 121 } 122 123 /** 124 * Sets the {@link Bean#dictionary()} property on this annotation. 125 * 126 * @param value The new value for this property. 127 * @return This object. 128 */ 129 public Builder dictionary(Class<?>...value) { 130 dictionary = value; 131 return this; 132 } 133 134 /** 135 * Sets the {@link Bean#example()} property on this annotation. 136 * 137 * @param value The new value for this property. 138 * @return This object. 139 */ 140 public Builder example(String value) { 141 example = value; 142 return this; 143 } 144 145 /** 146 * Sets the {@link Bean#excludeProperties()} property on this annotation. 147 * 148 * @param value The new value for this property. 149 * @return This object. 150 */ 151 public Builder excludeProperties(String value) { 152 excludeProperties = value; 153 return this; 154 } 155 156 /** 157 * Sets the {@link Bean#findFluentSetters()} property on this annotation. 158 * 159 * @param value The new value for this property. 160 * @return This object. 161 */ 162 public Builder findFluentSetters(boolean value) { 163 findFluentSetters = value; 164 return this; 165 } 166 167 /** 168 * Sets the {@link Bean#implClass()} property on this annotation. 169 * 170 * @param value The new value for this property. 171 * @return This object. 172 */ 173 public Builder implClass(Class<?> value) { 174 implClass = value; 175 return this; 176 } 177 178 /** 179 * Sets the {@link Bean#interceptor()} property on this annotation. 180 * 181 * @param value The new value for this property. 182 * @return This object. 183 */ 184 public Builder interceptor(Class<? extends BeanInterceptor<?>> value) { 185 interceptor = value; 186 return this; 187 } 188 189 /** 190 * Sets the {@link Bean#interfaceClass()} property on this annotation. 191 * 192 * @param value The new value for this property. 193 * @return This object. 194 */ 195 public Builder interfaceClass(Class<?> value) { 196 interfaceClass = value; 197 return this; 198 } 199 200 /** 201 * Sets the {@link Bean#p()} property on this annotation. 202 * 203 * @param value The new value for this property. 204 * @return This object. 205 */ 206 public Builder p(String value) { 207 p = value; 208 return this; 209 } 210 211 /** 212 * Sets the {@link Bean#properties()} property on this annotation. 213 * 214 * @param value The new value for this property. 215 * @return This object. 216 */ 217 public Builder properties(String value) { 218 properties = value; 219 return this; 220 } 221 222 /** 223 * Sets the {@link Bean#propertyNamer()} property on this annotation. 224 * 225 * @param value The new value for this property. 226 * @return This object. 227 */ 228 public Builder propertyNamer(Class<? extends PropertyNamer> value) { 229 propertyNamer = value; 230 return this; 231 } 232 233 /** 234 * Sets the {@link Bean#readOnlyProperties()} property on this annotation. 235 * 236 * @param value The new value for this property. 237 * @return This object. 238 */ 239 public Builder readOnlyProperties(String value) { 240 readOnlyProperties = value; 241 return this; 242 } 243 244 /** 245 * Sets the {@link Bean#ro()} property on this annotation. 246 * 247 * @param value The new value for this property. 248 * @return This object. 249 */ 250 public Builder ro(String value) { 251 ro = value; 252 return this; 253 } 254 255 /** 256 * Sets the {@link Bean#sort()} property on this annotation. 257 * 258 * @param value The new value for this property. 259 * @return This object. 260 */ 261 public Builder sort(boolean value) { 262 sort = value; 263 return this; 264 } 265 266 /** 267 * Sets the {@link Bean#stopClass()} property on this annotation. 268 * 269 * @param value The new value for this property. 270 * @return This object. 271 */ 272 public Builder stopClass(Class<?> value) { 273 stopClass = value; 274 return this; 275 } 276 277 /** 278 * Sets the {@link Bean#typeName()} property on this annotation. 279 * 280 * @param value The new value for this property. 281 * @return This object. 282 */ 283 public Builder typeName(String value) { 284 typeName = value; 285 return this; 286 } 287 288 /** 289 * Sets the {@link Bean#typePropertyName()} property on this annotation. 290 * 291 * @param value The new value for this property. 292 * @return This object. 293 */ 294 public Builder typePropertyName(String value) { 295 typePropertyName = value; 296 return this; 297 } 298 299 /** 300 * Sets the{@link Bean#wo()} property on this annotation. 301 * 302 * @param value The new value for this property. 303 * @return This object. 304 */ 305 public Builder wo(String value) { 306 wo = value; 307 return this; 308 } 309 310 /** 311 * Sets the{@link Bean#writeOnlyProperties()} property on this annotation. 312 * 313 * @param value The new value for this property. 314 * @return This object. 315 */ 316 public Builder writeOnlyProperties(String value) { 317 writeOnlyProperties = value; 318 return this; 319 } 320 321 /** 322 * Sets the {@link Bean#xp()} property on this annotation. 323 * 324 * @param value The new value for this property. 325 * @return This object. 326 */ 327 public Builder xp(String value) { 328 xp = value; 329 return this; 330 } 331 332 @Override /* Overridden from AppliedAnnotationObject.Builder */ 333 public Builder on(String...value) { 334 super.on(value); 335 return this; 336 } 337 338 @Override /* Overridden from AppliedAnnotationObject.BuilderT */ 339 public Builder on(Class<?>...value) { 340 super.on(value); 341 return this; 342 } 343 344 @Override /* Overridden from AppliedOnClassAnnotationObject.Builder */ 345 public Builder onClass(Class<?>...value) { 346 super.onClass(value); 347 return this; 348 } 349 350 @Override /* Overridden from AppliedAnnotationObject.BuilderT */ 351 public Builder on(ClassInfo...value) { 352 super.on(value); 353 return this; 354 } 355 356 @Override /* Overridden from AppliedAnnotationObject.BuilderT */ 357 public Builder onClass(ClassInfo...value) { 358 super.onClass(value); 359 return this; 360 } 361 362 } 363 364 private static class Object extends AppliedOnClassAnnotationObject implements Bean { 365 366 private final String[] description; 367 private final boolean findFluentSetters, sort; 368 private final Class<? extends BeanInterceptor<?>> interceptor; 369 private final Class<? extends PropertyNamer> propertyNamer; 370 private final Class<?> implClass, interfaceClass, stopClass; 371 private final Class<?>[] dictionary; 372 private final String example, excludeProperties, p, properties, readOnlyProperties, ro, typeName, typePropertyName, wo, writeOnlyProperties, xp; 373 374 Object(BeanAnnotation.Builder b) { 375 super(b); 376 description = copyOf(b.description); 377 dictionary = copyOf(b.dictionary); 378 example = b.example; 379 excludeProperties = b.excludeProperties; 380 findFluentSetters = b.findFluentSetters; 381 implClass = b.implClass; 382 interceptor = b.interceptor; 383 interfaceClass = b.interfaceClass; 384 p = b.p; 385 properties = b.properties; 386 propertyNamer = b.propertyNamer; 387 readOnlyProperties = b.readOnlyProperties; 388 ro = b.ro; 389 sort = b.sort; 390 stopClass = b.stopClass; 391 typeName = b.typeName; 392 typePropertyName = b.typePropertyName; 393 wo = b.wo; 394 writeOnlyProperties = b.writeOnlyProperties; 395 xp = b.xp; 396 } 397 398 @Override /* Overridden from Bean */ 399 public Class<?>[] dictionary() { 400 return dictionary; 401 } 402 403 @Override /* Overridden from Bean */ 404 public String example() { 405 return example; 406 } 407 408 @Override /* Overridden from Bean */ 409 public String excludeProperties() { 410 return excludeProperties; 411 } 412 413 @Override /* Overridden from Bean */ 414 public boolean findFluentSetters() { 415 return findFluentSetters; 416 } 417 418 @Override /* Overridden from Bean */ 419 public Class<?> implClass() { 420 return implClass; 421 } 422 423 @Override /* Overridden from Bean */ 424 public Class<? extends BeanInterceptor<?>> interceptor() { 425 return interceptor; 426 } 427 428 @Override /* Overridden from Bean */ 429 public Class<?> interfaceClass() { 430 return interfaceClass; 431 } 432 433 @Override /* Overridden from Bean */ 434 public String p() { 435 return p; 436 } 437 438 @Override /* Overridden from Bean */ 439 public String properties() { 440 return properties; 441 } 442 443 @Override /* Overridden from Bean */ 444 public Class<? extends PropertyNamer> propertyNamer() { 445 return propertyNamer; 446 } 447 448 @Override /* Overridden from Bean */ 449 public String readOnlyProperties() { 450 return readOnlyProperties; 451 } 452 453 @Override /* Overridden from Bean */ 454 public String ro() { 455 return ro; 456 } 457 458 @Override /* Overridden from Bean */ 459 public boolean sort() { 460 return sort; 461 } 462 463 @Override /* Overridden from Bean */ 464 public Class<?> stopClass() { 465 return stopClass; 466 } 467 468 @Override /* Overridden from Bean */ 469 public String typeName() { 470 return typeName; 471 } 472 473 @Override /* Overridden from Bean */ 474 public String typePropertyName() { 475 return typePropertyName; 476 } 477 478 @Override /* Overridden from Bean */ 479 public String wo() { 480 return wo; 481 } 482 483 @Override /* Overridden from Bean */ 484 public String writeOnlyProperties() { 485 return writeOnlyProperties; 486 } 487 488 @Override /* Overridden from Bean */ 489 public String xp() { 490 return xp; 491 } 492 493 @Override /* Overridden from Bean */ 494 public String[] description() { 495 return description; 496 } 497 } 498 499 /** Default value */ 500 public static final Bean DEFAULT = create().build(); 501 502 /** 503 * Creates a copy of the specified annotation. 504 * 505 * @param a The annotation to copy. 506 * @param r The var resolver for resolving any variables. 507 * @return A copy of the specified annotation. 508 */ 509 public static Bean copy(Bean a, VarResolverSession r) { 510 // @formatter:off 511 return 512 create() 513 .dictionary(a.dictionary()) 514 .example(r.resolve(a.example())) 515 .excludeProperties(r.resolve(a.excludeProperties())) 516 .findFluentSetters(a.findFluentSetters()) 517 .implClass(a.implClass()) 518 .interceptor(a.interceptor()) 519 .interfaceClass(a.interfaceClass()) 520 .on(r.resolve(a.on())) 521 .onClass(a.onClass()) 522 .p(r.resolve(a.p())) 523 .properties(r.resolve(a.properties())) 524 .propertyNamer(a.propertyNamer()) 525 .readOnlyProperties(r.resolve(a.readOnlyProperties())) 526 .ro(r.resolve(a.ro())) 527 .sort(a.sort()) 528 .stopClass(a.stopClass()) 529 .typeName(r.resolve(a.typeName())) 530 .typePropertyName(r.resolve(a.typePropertyName())) 531 .wo(r.resolve(a.wo())) 532 .writeOnlyProperties(r.resolve(a.writeOnlyProperties())) 533 .xp(r.resolve(a.xp())) 534 .build(); 535 // @formatter:on 536 } 537 538 /** 539 * Instantiates a new builder for this class. 540 * 541 * @return A new builder object. 542 */ 543 public static Builder create() { 544 return new Builder(); 545 } 546 547 /** 548 * Instantiates a new builder for this class. 549 * 550 * @param on The targets this annotation applies to. 551 * @return A new builder object. 552 */ 553 public static Builder create(Class<?>...on) { 554 return create().on(on); 555 } 556 557 /** 558 * Instantiates a new builder for this class. 559 * 560 * @param on The targets this annotation applies to. 561 * @return A new builder object. 562 */ 563 public static Builder create(String...on) { 564 return create().on(on); 565 } 566}