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