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.transform.*;
024
025/**
026 * Used to tailor how beans get interpreted by the framework.
027 *
028 * <p>
029 * This annotation can be applied to classes and interfaces.
030 *
031 * <ul class='seealso'>
032 *    <li class='link'>{@doc BeanAnnotation}
033 * </ul>
034 */
035@Documented
036@Target(TYPE)
037@Retention(RUNTIME)
038@Inherited
039public @interface Bean {
040
041   /**
042    * Bean dictionary.
043    *
044    * <p>
045    * The list of classes that make up the bean dictionary for all properties in this class and all subclasses.
046    *
047    * <ul class='seealso'>
048    *    <li class='jf'>{@link BeanContext#BEAN_beanDictionary}
049    * </ul>
050    *
051    * <div class='warn'>
052    *    <b>Deprecated</b> - {@link #dictionary()}.
053    * </div>
054    */
055   @Deprecated
056   Class<?>[] beanDictionary() default {};
057
058   /**
059    * Bean property includes.
060    *
061    * <p>
062    * The set and order of names of properties associated with a bean class.
063    *
064    * <p>
065    * The order specified is the same order that the entries will be returned by the {@link BeanMap#entrySet()} and
066    * related methods.
067    *
068    * <p>
069    * This value is entirely optional if you simply want to expose all the getters and public fields on
070    * a class as bean properties.
071    * <br>However, it's useful if you want certain getters to be ignored or you want the properties to be
072    * serialized in a particular order.
073    * <br>Note that on IBM JREs, the property order is the same as the order in the source code,
074    * whereas on Oracle JREs, the order is entirely random.
075    *
076    * <h5 class='section'>Example:</h5>
077    * <p class='bcode w800'>
078    *    <jc>// Address class with only street/city/state properties (in that order).</jc>
079    *    <ja>@Bean</ja>(bpi=<js>"street,city,state"</js>)
080    *    <jk>public class</jk> Address {...}
081    * </p>
082    *
083    * <ul class='seealso'>
084    *    <li class='jm'>{@link BeanContextBuilder#bpi(Class, String)}
085    *    <li class='jm'>{@link BeanContextBuilder#bpi(String, String)}
086    *    <li class='jm'>{@link BeanContextBuilder#bpi(Map)}
087    * </ul>
088    */
089   String bpi() default "";
090
091   /**
092    * Bean property excludes.
093    *
094    * <p>
095    * Specifies a list of properties that should be excluded from {@link BeanMap#entrySet()}.
096    *
097    * <h5 class='section'>Example:</h5>
098    * <p class='bcode w800'>
099    *    <jc>// Exclude the 'city' and 'state' properties from the Address class.</jc>
100    *    <ja>@Bean</ja>(bpx=<js>"city,state"</js>})
101    *    <jk>public class</jk> Address {...}
102    * </p>
103    *
104    * <ul class='seealso'>
105    *    <li class='jm'>{@link BeanContextBuilder#bpx(Class, String)}
106    *    <li class='jm'>{@link BeanContextBuilder#bpx(String, String)}
107    *    <li class='jm'>{@link BeanContextBuilder#bpx(Map)}
108    * </ul>
109    */
110   String bpx() default "";
111
112   /**
113    * Read-only bean properties.
114    *
115    * <p>
116    * Specifies one or more properties on a bean that are read-only despite having valid getters.
117    * Serializers will serialize such properties as usual, but parsers will silently ignore them.
118    *
119    * <h5 class='section'>Example:</h5>
120    * <p class='bcode w800'>
121    *    <jc>// Exclude the 'city' and 'state' properties from being parsed, but not serialized.</jc>
122    *    <ja>@Bean</ja>(bpro=<js>"city,state"</js>})
123    *    <jk>public class</jk> Address {...}
124    * </p>
125    *
126    * <ul class='seealso'>
127    *    <li class='jm'>{@link BeanContextBuilder#bpro(Class, String)}
128    *    <li class='jm'>{@link BeanContextBuilder#bpro(String, String)}
129    *    <li class='jm'>{@link BeanContextBuilder#bpro(Map)}
130    * </ul>
131    */
132   String bpro() default "";
133
134   /**
135    * Write-only bean properties.
136    *
137    * <p>
138    * Specifies one or more properties on a bean that are write-only despite having valid setters.
139    * Parsers will parse such properties as usual, but serializers will silently ignore them.
140    *
141    * <h5 class='section'>Example:</h5>
142    * <p class='bcode w800'>
143    *    <jc>// Exclude the 'city' and 'state' properties from being serialized, but not parsed.</jc>
144    *    <ja>@Bean</ja>(bpro=<js>"city,state"</js>})
145    *    <jk>public class</jk> Address {...}
146    * </p>
147    *
148    * <ul class='seealso'>
149    *    <li class='jm'>{@link BeanContextBuilder#bpwo(Class, String)}
150    *    <li class='jm'>{@link BeanContextBuilder#bpwo(String, String)}
151    *    <li class='jm'>{@link BeanContextBuilder#bpwo(Map)}
152    * </ul>
153    */
154   String bpwo() default "";
155
156   /**
157    * Bean dictionary.
158    *
159    * <p>
160    * The list of classes that make up the bean dictionary for all properties in this class and all subclasses.
161    *
162    * <ul class='seealso'>
163    *    <li class='jf'>{@link BeanContext#BEAN_beanDictionary}
164    * </ul>
165    */
166   Class<?>[] dictionary() default {};
167
168   /**
169    * Specifies a list of properties that should be excluded from {@link BeanMap#entrySet()}.
170    *
171    * <div class='warn'>
172    *    <b>Deprecated</b> - {@link #bpx()}.
173    * </div>
174    */
175   @Deprecated String excludeProperties() default "";
176
177   /**
178    * Find fluent setters.
179    *
180    * <p>
181    * When <jk>true</jk>, fluent setters will be detected on beans.
182    *
183    * <p>
184    * Fluent setters
185    *
186    * <h5 class='section'>Example:</h5>
187    * <p class='bcode w800'>
188    *    <ja>@Bean</ja>(fluentSetters=<jk>true</jk>)
189    *    <jk>public class</jk> MyBean {
190    *       <jk>public int</jk> getId() {...}
191    *       <jk>public</jk> MyBean id(<jk>int</jk> id) {...}
192    *    }
193    * </p>
194    *
195    * <p>
196    * Fluent setters must have the following attributes:
197    * <ul>
198    *    <li>Public.
199    *    <li>Not static.
200    *    <li>Take in one parameter.
201    *    <li>Return the bean itself.
202    * </ul>
203    *
204    * <ul class='seealso'>
205    *    <li class='jf'>{@link BeanContext#BEAN_fluentSetters}
206    * </ul>
207    */
208   boolean fluentSetters() default false;
209
210   /**
211    * Identifies a class to be used as the interface class for this and all subclasses.
212    *
213    * <p>
214    * When specified, only the list of properties defined on the interface class will be used during serialization.
215    * Additional properties on subclasses will be ignored.
216    *
217    * <p class='bcode w800'>
218    *    <jc>// Parent class</jc>
219    *    <ja>@Bean</ja>(interfaceClass=A.<jk>class</jk>)
220    *    <jk>public abstract class</jk> A {
221    *       <jk>public</jk> String <jf>f0</jf> = <js>"f0"</js>;
222    *    }
223    *
224    *    <jc>// Sub class</jc>
225    *    <jk>public class</jk> A1 <jk>extends</jk> A {
226    *       <jk>public</jk> String <jf>f1</jf> = <js>"f1"</js>;
227    *    }
228    *
229    *    <jc>// Produces "{f0:'f0'}"</jc>
230    *    String json = SimpleJsonSerializer.<jsf>DEFAULT</jsf>.serialize(<jk>new</jk> A1());
231    * </p>
232    *
233    * <p>
234    * Note that this annotation can be used on the parent class so that it filters to all child classes,
235    * or can be set individually on the child classes.
236    */
237   Class<?> interfaceClass() default Object.class;
238
239   /**
240    * Bean property interceptor.
241    *
242    * <p>
243    * Bean interceptors can be used to intercept calls to getters and setters and alter their values in transit.
244    *
245    * <ul class='seealso'>
246    *    <li class='jc'>{@link BeanInterceptor}
247    * </ul>
248    */
249   Class<? extends BeanInterceptor<?>> interceptor() default BeanInterceptor.Default.class;
250
251   /**
252    * Dynamically apply this annotation to the specified classes.
253    *
254    * <p>
255    * Used in conjunction with the {@link BeanConfig#applyBean()}.
256    * It is ignored when the annotation is applied directly to classes.
257    *
258    * <p>
259    * The following example shows the equivalent methods for applying the {@link Bean @Bean} annotation to REST methods:
260    * <p class='bpcode w800'>
261    *    <jc>// Class with explicit annotation.</jc>
262    *    <ja>@Bean</ja>(bpi=<js>"street,city,state"</js>)
263    *    <jk>public class</jk> A {...}
264    *
265    *    <jc>// Class with annotation applied via @BeanConfig</jc>
266    *    <jk>public class</jk> B {...}
267    *
268    *    <jc>// Java REST method with @BeanConfig annotation.</jc>
269    *    <ja>@RestMethod</ja>(...)
270    *    <ja>@BeanConfig</ja>(
271    *       applyBean={
272    *          <ja>@Bean</ja>(on=<js>"B"</js>, bpi=<js>"street,city,state"</js>)
273    *       }
274    *    )
275    *    <jk>public void</jk> doFoo() {...}
276    * </p>
277    *
278    * <h5 class='section'>Valid patterns:</h5>
279    * <ul class='spaced-list'>
280    *  <li>Classes:
281    *       <ul>
282    *          <li>Fully qualified:
283    *             <ul>
284    *                <li><js>"com.foo.MyClass"</js>
285    *             </ul>
286    *          <li>Fully qualified inner class:
287    *             <ul>
288    *                <li><js>"com.foo.MyClass$Inner1$Inner2"</js>
289    *             </ul>
290    *          <li>Simple:
291    *             <ul>
292    *                <li><js>"MyClass"</js>
293    *             </ul>
294    *          <li>Simple inner:
295    *             <ul>
296    *                <li><js>"MyClass$Inner1$Inner2"</js>
297    *                <li><js>"Inner1$Inner2"</js>
298    *                <li><js>"Inner2"</js>
299    *             </ul>
300    *       </ul>
301    *    <li>A comma-delimited list of anything on this list.
302    * </ul>
303    *
304    * <ul class='seealso'>
305    *    <li class='link'>{@doc DynamicallyAppliedAnnotations}
306    * </ul>
307    */
308   String on() default "";
309
310   /**
311    * The set and order of names of properties associated with a bean class.
312    *
313    * <div class='warn'>
314    *    <b>Deprecated</b> - {@link #bpi()}.
315    * </div>
316    */
317   @Deprecated String properties() default "";
318
319   /**
320    * Associates a {@link PropertyNamer} with this bean to tailor the names of the bean properties.
321    *
322    * <p>
323    * Property namers are used to transform bean property names from standard form to some other form.
324    *
325    * <h5 class='section'>Example:</h5>
326    * <p class='bcode w800'>
327    *    <jc>// Define a class with dashed-lowercase property names.</jc>
328    *    <ja>@Bean</ja>(propertyNamer=PropertyNamerDashedLC.<jk>class</jk>)
329    *    <jk>public class</jk> MyBean {...}
330    * </p>
331    *
332    * <ul class='seealso'>
333    *    <li class='jf'>{@link BeanContext#BEAN_propertyNamer}
334    * </ul>
335    */
336   Class<? extends PropertyNamer> propertyNamer() default PropertyNamerDefault.class;
337
338   /**
339    * Sort bean properties in alphabetical order.
340    *
341    * <p>
342    * When <jk>true</jk>, all bean properties will be serialized and access in alphabetical order.
343    * <br>Otherwise, the natural order of the bean properties is used which is dependent on the JVM vendor.
344    *
345    * <h5 class='section'>Example:</h5>
346    * <p class='bcode w800'>
347    *    <jc>// Sort bean properties alphabetically during serialization.</jc>
348    *    <ja>@Bean</ja>(sort=<jk>true</jk>)
349    *    <jk>public class</jk> MyBean {...}
350    * </p>
351    *
352    * <ul class='seealso'>
353    *    <li class='jf'>{@link BeanContext#BEAN_sortProperties}
354    * </ul>
355    */
356   boolean sort() default false;
357
358   /**
359    * Identifies a stop class for the annotated class.
360    *
361    * <p>
362    * Identical in purpose to the stop class specified by {@link Introspector#getBeanInfo(Class, Class)}.
363    * Any properties in the stop class or in its base classes will be ignored during analysis.
364    *
365    * <p>
366    * For example, in the following class hierarchy, instances of <c>C3</c> will include property <c>p3</c>,
367    * but not <c>p1</c> or <c>p2</c>.
368    * <p class='bcode w800'>
369    *    <jk>public class</jk> C1 {
370    *       <jk>public int</jk> getP1();
371    *    }
372    *
373    *    <jk>public class</jk> C2 <jk>extends</jk> C1 {
374    *       <jk>public int</jk> getP2();
375    *    }
376    *
377    *    <ja>@Bean</ja>(stopClass=C2.<jk>class</jk>)
378    *    <jk>public class</jk> C3 <jk>extends</jk> C2 {
379    *       <jk>public int</jk> getP3();
380    *    }
381    * </p>
382    */
383   Class<?> stopClass() default Object.class;
384
385   /**
386    * An identifying name for this class.
387    *
388    * <p>
389    * The name is used to identify the class type during parsing when it cannot be inferred through reflection.
390    * <br>For example, if a bean property is of type <c>Object</c>, then the serializer will add the name to the
391    * output so that the class can be determined during parsing.
392    *
393    * <p>
394    * It is also used to specify element names in XML.
395    *
396    * <h5 class='section'>Example:</h5>
397    * <p class='bcode w800'>
398    *    <jc>// Use _type='mybean' to identify this bean.</jc>
399    *    <ja>@Bean</ja>(typeName=<js>"mybean"</js>)
400    *    <jk>public class</jk> MyBean {...}
401    * </p>
402    *
403    * <ul class='seealso'>
404    *    <li class='jf'>{@link BeanContext#BEAN_beanDictionary}
405    * </ul>
406    */
407   String typeName() default "";
408
409   /**
410    * The property name to use for representing the type name.
411    *
412    * <p>
413    * This can be used to override the name used for the <js>"_type"</js> property used by the {@link #typeName()} setting.
414    *
415    * <p>
416    * The default value if not specified is <js>"_type"</js> .
417    *
418    * <h5 class='section'>Example:</h5>
419    * <p class='bcode w800'>
420    *    <jc>// Use 'type' instead of '_type' for bean names.</jc>
421    *    <ja>@Bean</ja>(typePropertyName=<js>"type"</js>)
422    *    <jk>public class</jk> MyBean {...}
423    * </p>
424    *
425    * <ul class='seealso'>
426    *    <li class='jf'>{@link BeanContext#BEAN_typePropertyName}
427    * </ul>
428    */
429   String typePropertyName() default "";
430}