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.annotation; 014 015import static java.lang.annotation.ElementType.*; 016import static java.lang.annotation.RetentionPolicy.*; 017 018import java.beans.*; 019import java.lang.annotation.*; 020import java.util.*; 021 022import org.apache.juneau.*; 023import org.apache.juneau.swap.*; 024 025/** 026 * Used to tailor how beans get interpreted by the framework. 027 * 028 * <p> 029 * Can be used in the following locations: 030 * <ul> 031 * <li>Bean classes and parent interfaces. 032 * <li><ja>@Rest</ja>-annotated classes and <ja>@RestOp</ja>-annotated methods when an {@link #on()} value is specified. 033 * </ul> 034 * 035 * <h5 class='section'>See Also:</h5><ul> 036 * <li class='link'><a class="doclink" href="../../../../index.html#jm.BeanAnnotation">@Bean Annotation</a> 037 * </ul> 038 */ 039@Documented 040@Target({METHOD,TYPE}) 041@Retention(RUNTIME) 042@Inherited 043@Repeatable(BeanAnnotation.Array.class) 044@ContextApply(BeanAnnotation.Applier.class) 045public @interface Bean { 046 047 /** 048 * Bean dictionary. 049 * 050 * <p> 051 * The list of classes that make up the bean dictionary for all properties in this class and all subclasses. 052 * 053 * <h5 class='section'>See Also:</h5><ul> 054 * <li class='ja'>{@link Beanp#dictionary()} 055 * <li class='ja'>{@link BeanConfig#dictionary()} 056 * <li class='ja'>{@link BeanConfig#dictionary_replace()} 057 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanDictionary(Class...)} 058 * </ul> 059 * 060 * @return The annotation value. 061 */ 062 Class<?>[] dictionary() default {}; 063 064 /** 065 * POJO example. 066 * 067 * <p> 068 * Specifies an example of the specified class in Simplified JSON format. 069 * 070 * <p> 071 * Examples are used in cases such as POJO examples in Swagger documents. 072 * 073 * <h5 class='section'>Example:</h5> 074 * <p class='bjava'> 075 * <ja>@Bean</ja>(example=<js>"{foo:'bar'}"</js>) 076 * <jk>public class</jk> MyClass {...} 077 * </p> 078 * 079 * <h5 class='section'>Notes:</h5><ul> 080 * <li class='note'> 081 * Setting applies to specified class and all subclasses. 082 * <li class='note'> 083 * Keys are the class of the example. 084 * <br>Values are JSON 5 representation of that class. 085 * <li class='note'> 086 * POJO examples can also be defined on classes via the following: 087 * <ul class='spaced-list'> 088 * <li>A static field annotated with {@link Example @Example}. 089 * <li>A static method annotated with {@link Example @Example} with zero arguments or one {@link BeanSession} argument. 090 * <li>A static method with name <c>example</c> with no arguments or one {@link BeanSession} argument. 091 * </ul> 092 * <li class='note'> 093 * Supports <a class="doclink" href="../../../../index.html#jm.DefaultVarResolver">VarResolver.DEFAULT</a> (e.g. <js>"$C{myConfigVar}"</js>). 094 * </ul> 095 * 096 * <h5 class='section'>See Also:</h5><ul> 097 * <li class='ja'>{@link Example} 098 * </ul> 099 * 100 * @return The annotation value. 101 */ 102 String example() default ""; 103 104 /** 105 * Bean property excludes. 106 * 107 * <p> 108 * Specifies a list of properties that should be excluded from {@link BeanMap#entrySet()}. 109 * 110 * <h5 class='section'>Example:</h5> 111 * <p class='bjava'> 112 * <jc>// Exclude the 'city' and 'state' properties from the Address class.</jc> 113 * <ja>@Bean</ja>(excludeProperties=<js>"city,state"</js>}) 114 * <jk>public class</jk> Address {...} 115 * </p> 116 * 117 * <h5 class='section'>Notes:</h5><ul> 118 * <li class='note'> 119 * {@link #xp()} is a shortened synonym for this value. 120 * </ul> 121 * 122 * <h5 class='section'>See Also:</h5><ul> 123 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanPropertiesExcludes(Class, String)} 124 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanPropertiesExcludes(String, String)} 125 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanPropertiesExcludes(Map)} 126 * </ul> 127 * 128 * @return The annotation value. 129 */ 130 String excludeProperties() default ""; 131 132 /** 133 * Find fluent setters. 134 * 135 * <p> 136 * When <jk>true</jk>, fluent setters will be detected on beans. 137 * 138 * <h5 class='section'>Example:</h5> 139 * <p class='bjava'> 140 * <ja>@Bean</ja>(findFluentSetters=<jk>true</jk>) 141 * <jk>public class</jk> MyBean { 142 * <jk>public int</jk> getId() {...} 143 * <jk>public</jk> MyBean id(<jk>int</jk> <jv>id</jv>) {...} 144 * } 145 * </p> 146 * 147 * <p> 148 * Fluent setters must have the following attributes: 149 * <ul> 150 * <li>Public. 151 * <li>Not static. 152 * <li>Take in one parameter. 153 * <li>Return the bean itself. 154 * </ul> 155 * 156 * <h5 class='section'>See Also:</h5><ul> 157 * <li class='ja'>{@link BeanConfig#findFluentSetters()} 158 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#findFluentSetters()} 159 * </ul> 160 * 161 * @return The annotation value. 162 */ 163 boolean findFluentSetters() default false; 164 165 /** 166 * Implementation class. 167 * 168 * <p> 169 * For interfaces and abstract classes this method can be used to specify an implementation class for the 170 * interface/abstract class so that instances of the implementation class are used when instantiated (e.g. during a 171 * parse). 172 * 173 * <h5 class='section'>Example:</h5> 174 * <p class='bjava'> 175 * <ja>@Bean</ja>(implClass=MyInterfaceImpl.<jk>class</jk>) 176 * <jk>public class</jk> MyInterface {...} 177 * <p> 178 * 179 * @return The annotation value. 180 */ 181 Class<?> implClass() default void.class; 182 183 /** 184 * Bean property interceptor. 185 * 186 * <p> 187 * Bean interceptors can be used to intercept calls to getters and setters and alter their values in transit. 188 * 189 * <h5 class='section'>See Also:</h5><ul> 190 * <li class='jc'>{@link BeanInterceptor} 191 * </ul> 192 * 193 * @return The annotation value. 194 */ 195 Class<? extends BeanInterceptor<?>> interceptor() default BeanInterceptor.Void.class; 196 197 /** 198 * Identifies a class to be used as the interface class for this and all subclasses. 199 * 200 * <p> 201 * When specified, only the list of properties defined on the interface class will be used during serialization. 202 * Additional properties on subclasses will be ignored. 203 * 204 * <p class='bjava'> 205 * <jc>// Parent class</jc> 206 * <ja>@Bean</ja>(interfaceClass=A.<jk>class</jk>) 207 * <jk>public abstract class</jk> A { 208 * <jk>public</jk> String <jf>f0</jf> = <js>"f0"</js>; 209 * } 210 * 211 * <jc>// Sub class</jc> 212 * <jk>public class</jk> A1 <jk>extends</jk> A { 213 * <jk>public</jk> String <jf>f1</jf> = <js>"f1"</js>; 214 * } 215 * 216 * <jc>// Produces "{f0:'f0'}"</jc> 217 * String <jv>json</jv> = Json5Serializer.<jsf>DEFAULT</jsf>.serialize(<jk>new</jk> A1()); 218 * </p> 219 * 220 * <p> 221 * Note that this annotation can be used on the parent class so that it filters to all child classes, 222 * or can be set individually on the child classes. 223 * 224 * @return The annotation value. 225 */ 226 Class<?> interfaceClass() default void.class; 227 228 /** 229 * Dynamically apply this annotation to the specified classes. 230 * 231 * <p> 232 * Used in conjunction with {@link org.apache.juneau.BeanContext.Builder#applyAnnotations(Class...)} to dynamically apply an annotation to an existing class. 233 * It is ignored when the annotation is applied directly to classes. 234 * 235 * <h5 class='section'>Valid patterns:</h5> 236 * <ul class='spaced-list'> 237 * <li>Classes: 238 * <ul> 239 * <li>Fully qualified: 240 * <ul> 241 * <li><js>"com.foo.MyClass"</js> 242 * </ul> 243 * <li>Fully qualified inner class: 244 * <ul> 245 * <li><js>"com.foo.MyClass$Inner1$Inner2"</js> 246 * </ul> 247 * <li>Simple: 248 * <ul> 249 * <li><js>"MyClass"</js> 250 * </ul> 251 * <li>Simple inner: 252 * <ul> 253 * <li><js>"MyClass$Inner1$Inner2"</js> 254 * <li><js>"Inner1$Inner2"</js> 255 * <li><js>"Inner2"</js> 256 * </ul> 257 * </ul> 258 * <li>A comma-delimited list of anything on this list. 259 * </ul> 260 * 261 * <h5 class='section'>See Also:</h5><ul> 262 * <li class='link'><a class="doclink" href="../../../../index.html#jm.DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a> 263 * </ul> 264 * 265 * @return The annotation value. 266 */ 267 String[] on() default {}; 268 269 /** 270 * Dynamically apply this annotation to the specified classes. 271 * 272 * <p> 273 * Identical to {@link #on()} except allows you to specify class objects instead of a strings. 274 * 275 * <h5 class='section'>See Also:</h5><ul> 276 * <li class='link'><a class="doclink" href="../../../../index.html#jm.DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a> 277 * </ul> 278 * 279 * @return The annotation value. 280 */ 281 Class<?>[] onClass() default {}; 282 283 /** 284 * Synonym for {@link #properties()}. 285 * 286 * @return The annotation value. 287 */ 288 String p() default ""; 289 290 /** 291 * Bean property includes. 292 * 293 * <p> 294 * The set and order of names of properties associated with a bean class. 295 * 296 * <p> 297 * The order specified is the same order that the entries will be returned by the {@link BeanMap#entrySet()} and 298 * related methods. 299 * 300 * <p> 301 * This value is entirely optional if you simply want to expose all the getters and public fields on 302 * a class as bean properties. 303 * <br>However, it's useful if you want certain getters to be ignored or you want the properties to be 304 * serialized in a particular order. 305 * <br>Note that on IBM JREs, the property order is the same as the order in the source code, 306 * whereas on Oracle JREs, the order is entirely random. 307 * 308 * <h5 class='section'>Example:</h5> 309 * <p class='bjava'> 310 * <jc>// Address class with only street/city/state properties (in that order).</jc> 311 * <ja>@Bean</ja>(properties=<js>"street,city,state"</js>) 312 * <jk>public class</jk> Address {...} 313 * </p> 314 * 315 * <h5 class='section'>Notes:</h5><ul> 316 * <li class='note'> 317 * {@link #p()} is a shortened synonym for this value. 318 * </ul> 319 * 320 * <h5 class='section'>See Also:</h5><ul> 321 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanProperties(Class, String)} 322 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanProperties(String, String)} 323 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanProperties(Map)} 324 * </ul> 325 * 326 * @return The annotation value. 327 */ 328 String properties() default ""; 329 330 /** 331 * Associates a {@link PropertyNamer} with this bean to tailor the names of the bean properties. 332 * 333 * <p> 334 * Property namers are used to transform bean property names from standard form to some other form. 335 * 336 * <h5 class='section'>Example:</h5> 337 * <p class='bjava'> 338 * <jc>// Define a class with dashed-lowercase property names.</jc> 339 * <ja>@Bean</ja>(propertyNamer=PropertyNamerDashedLC.<jk>class</jk>) 340 * <jk>public class</jk> MyBean {...} 341 * </p> 342 * 343 * <h5 class='section'>See Also:</h5><ul> 344 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#propertyNamer(Class)} 345 * </ul> 346 * 347 * @return The annotation value. 348 */ 349 Class<? extends PropertyNamer> propertyNamer() default PropertyNamer.Void.class; 350 351 /** 352 * Read-only bean properties. 353 * 354 * <p> 355 * Specifies one or more properties on a bean that are read-only despite having valid getters. 356 * Serializers will serialize such properties as usual, but parsers will silently ignore them. 357 * 358 * <h5 class='section'>Example:</h5> 359 * <p class='bjava'> 360 * <jc>// Exclude the 'city' and 'state' properties from being parsed, but not serialized.</jc> 361 * <ja>@Bean</ja>(readOnlyProperties=<js>"city,state"</js>}) 362 * <jk>public class</jk> Address {...} 363 * </p> 364 * 365 * <h5 class='section'>Notes:</h5><ul> 366 * <li class='note'> 367 * {@link #ro()} is a shortened synonym for this value. 368 * </ul> 369 * 370 * <h5 class='section'>See Also:</h5><ul> 371 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanPropertiesReadOnly(Class, String)} 372 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanPropertiesReadOnly(String, String)} 373 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanPropertiesReadOnly(Map)} 374 * </ul> 375 * 376 * @return The annotation value. 377 */ 378 String readOnlyProperties() default ""; 379 380 /** 381 * Synonym for {@link #readOnlyProperties()}. 382 * 383 * @return The annotation value. 384 */ 385 String ro() default ""; 386 387 /** 388 * Sort bean properties in alphabetical order. 389 * 390 * <p> 391 * When <jk>true</jk>, all bean properties will be serialized and access in alphabetical order. 392 * <br>Otherwise, the natural order of the bean properties is used which is dependent on the JVM vendor. 393 * 394 * <h5 class='section'>Example:</h5> 395 * <p class='bjava'> 396 * <jc>// Sort bean properties alphabetically during serialization.</jc> 397 * <ja>@Bean</ja>(sort=<jk>true</jk>) 398 * <jk>public class</jk> MyBean {...} 399 * </p> 400 * 401 * <h5 class='section'>See Also:</h5><ul> 402 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#sortProperties()} 403 * </ul> 404 * 405 * @return The annotation value. 406 */ 407 boolean sort() default false; 408 409 /** 410 * Identifies a stop class for the annotated class. 411 * 412 * <p> 413 * Identical in purpose to the stop class specified by {@link Introspector#getBeanInfo(Class, Class)}. 414 * Any properties in the stop class or in its base classes will be ignored during analysis. 415 * 416 * <p> 417 * For example, in the following class hierarchy, instances of <c>C3</c> will include property <c>p3</c>, 418 * but not <c>p1</c> or <c>p2</c>. 419 * <p class='bjava'> 420 * <jk>public class</jk> C1 { 421 * <jk>public int</jk> getP1(); 422 * } 423 * 424 * <jk>public class</jk> C2 <jk>extends</jk> C1 { 425 * <jk>public int</jk> getP2(); 426 * } 427 * 428 * <ja>@Bean</ja>(stopClass=C2.<jk>class</jk>) 429 * <jk>public class</jk> C3 <jk>extends</jk> C2 { 430 * <jk>public int</jk> getP3(); 431 * } 432 * </p> 433 * 434 * @return The annotation value. 435 */ 436 Class<?> stopClass() default void.class; 437 438 /** 439 * An identifying name for this class. 440 * 441 * <p> 442 * The name is used to identify the class type during parsing when it cannot be inferred through reflection. 443 * <br>For example, if a bean property is of type <c>Object</c>, then the serializer will add the name to the 444 * output so that the class can be determined during parsing. 445 * 446 * <p> 447 * It is also used to specify element names in XML. 448 * 449 * <h5 class='section'>Example:</h5> 450 * <p class='bjava'> 451 * <jc>// Use _type='mybean' to identify this bean.</jc> 452 * <ja>@Bean</ja>(typeName=<js>"mybean"</js>) 453 * <jk>public class</jk> MyBean {...} 454 * </p> 455 * 456 * <h5 class='section'>See Also:</h5><ul> 457 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanDictionary(Class...)} 458 * </ul> 459 * 460 * @return The annotation value. 461 */ 462 String typeName() default ""; 463 464 /** 465 * The property name to use for representing the type name. 466 * 467 * <p> 468 * This can be used to override the name used for the <js>"_type"</js> property used by the {@link #typeName()} setting. 469 * 470 * <p> 471 * The default value if not specified is <js>"_type"</js> . 472 * 473 * <h5 class='section'>Example:</h5> 474 * <p class='bjava'> 475 * <jc>// Use 'type' instead of '_type' for bean names.</jc> 476 * <ja>@Bean</ja>(typePropertyName=<js>"type"</js>) 477 * <jk>public class</jk> MyBean {...} 478 * </p> 479 * 480 * <h5 class='section'>See Also:</h5><ul> 481 * <li class='ja'>{@link BeanConfig#typePropertyName()} 482 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#typePropertyName(String)} 483 * </ul> 484 * 485 * @return The annotation value. 486 */ 487 String typePropertyName() default ""; 488 489 /** 490 * Synonym for {@link #writeOnlyProperties()}. 491 * 492 * @return The annotation value. 493 */ 494 String wo() default ""; 495 496 /** 497 * Write-only bean properties. 498 * 499 * <p> 500 * Specifies one or more properties on a bean that are write-only despite having valid setters. 501 * Parsers will parse such properties as usual, but serializers will silently ignore them. 502 * 503 * <h5 class='section'>Example:</h5> 504 * <p class='bjava'> 505 * <jc>// Exclude the 'city' and 'state' properties from being serialized, but not parsed.</jc> 506 * <ja>@Bean</ja>(writeOnlyProperties=<js>"city,state"</js>}) 507 * <jk>public class</jk> Address {...} 508 * </p> 509 * 510 * <h5 class='section'>Notes:</h5><ul> 511 * <li class='note'> 512 * {@link #wo()} is a shortened synonym for this value. 513 * </ul> 514 * 515 * <h5 class='section'>See Also:</h5><ul> 516 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanPropertiesWriteOnly(Class, String)} 517 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanPropertiesWriteOnly(String, String)} 518 * <li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanPropertiesWriteOnly(Map)} 519 * </ul> 520 * 521 * @return The annotation value. 522 */ 523 String writeOnlyProperties() default ""; 524 525 /** 526 * Synonym for {@link #excludeProperties()}. 527 * 528 * @return The annotation value. 529 */ 530 String xp() default ""; 531}