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}