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