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   Class<?>[] beanDictionary() default {};
051
052   /**
053    * Specifies a list of properties that should be excluded from {@link BeanMap#entrySet()}.
054    *
055    * <h5 class='section'>Example:</h5>
056    * <p class='bcode w800'>
057    *    <jc>// Exclude the 'city' and 'state' properties from the Address class.</jc>
058    *    <ja>@Bean</ja>(excludeProperties=<js>"city,state"</js>})
059    *    <jk>public class</jk> Address {...}
060    * </p>
061    *
062    * <ul class='seealso'>
063    *    <li class='jf'>{@link BeanContext#BEAN_excludeProperties}
064    * </ul>
065    */
066   String excludeProperties() default "";
067
068   /**
069    * Find fluent setters.
070    *
071    * <p>
072    * When <jk>true</jk>, fluent setters will be detected on beans.
073    *
074    * <p>
075    * Fluent setters
076    *
077    * <h5 class='section'>Example:</h5>
078    * <p class='bcode w800'>
079    *    <ja>@Bean</ja>(fluentSetters=<jk>true</jk>)
080    *    <jk>public class</jk> MyBean {
081    *       <jk>public int</jk> getId() {...}
082    *       <jk>public</jk> MyBean id(<jk>int</jk> id) {...}
083    *    }
084    * </p>
085    *
086    * <p>
087    * Fluent setters must have the following attributes:
088    * <ul>
089    *    <li>Public.
090    *    <li>Not static.
091    *    <li>Take in one parameter.
092    *    <li>Return the bean itself.
093    * </ul>
094    *
095    * <ul class='seealso'>
096    *    <li class='jf'>{@link BeanContext#BEAN_fluentSetters}
097    * </ul>
098    */
099   boolean fluentSetters() default false;
100
101   /**
102    * Identifies a class to be used as the interface class for this and all subclasses.
103    *
104    * <p>
105    * When specified, only the list of properties defined on the interface class will be used during serialization.
106    * Additional properties on subclasses will be ignored.
107    *
108    * <p class='bcode w800'>
109    *    <jc>// Parent class</jc>
110    *    <ja>@Bean</ja>(interfaceClass=A.<jk>class</jk>)
111    *    <jk>public abstract class</jk> A {
112    *       <jk>public</jk> String <jf>f0</jf> = <js>"f0"</js>;
113    *    }
114    *
115    *    <jc>// Sub class</jc>
116    *    <jk>public class</jk> A1 <jk>extends</jk> A {
117    *       <jk>public</jk> String <jf>f1</jf> = <js>"f1"</js>;
118    *    }
119    *
120    *    <jc>// Produces "{f0:'f0'}"</jc>
121    *    String json = SimpleJsonSerializer.<jsf>DEFAULT</jsf>.serialize(<jk>new</jk> A1());
122    * </p>
123    *
124    * <p>
125    * Note that this annotation can be used on the parent class so that it filters to all child classes,
126    * or can be set individually on the child classes.
127    *
128    * <ul class='seealso'>
129    *    <li class='jf'>{@link BeanContext#BEAN_beanFilters}
130    * </ul>
131    */
132   Class<?> interfaceClass() default Object.class;
133
134   /**
135    * The set and order of names of properties associated with a bean class.
136    *
137    * <p>
138    * The order specified is the same order that the entries will be returned by the {@link BeanMap#entrySet()} and
139    * related methods.
140    *
141    * <p>
142    * This value is entirely optional if you simply want to expose all the getters and public fields on
143    * a class as bean properties.
144    * <br>However, it's useful if you want certain getters to be ignored or you want the properties to be
145    * serialized in a particular order.
146    * <br>Note that on IBM JREs, the property order is the same as the order in the source code,
147    * whereas on Oracle JREs, the order is entirely random.
148    *
149    * <h5 class='section'>Example:</h5>
150    * <p class='bcode w800'>
151    *    <jc>// Address class with only street/city/state properties (in that order).</jc>
152    *    <ja>@Bean</ja>(properties=<js>"street,city,state"</js>)
153    *    <jk>public class</jk> Address {...}
154    * </p>
155    *
156    * <ul class='seealso'>
157    *    <li class='jf'>{@link BeanContext#BEAN_includeProperties}
158    * </ul>
159    */
160   String properties() default "";
161
162   /**
163    * Property filter.
164    *
165    * <p>
166    * Property filters can be used to intercept calls to getters and setters and alter their values in transit.
167    *
168    * <ul class='seealso'>
169    *    <li class='jc'>{@link PropertyFilter}
170    * </ul>
171    */
172   Class<? extends PropertyFilter> propertyFilter() default PropertyFilter.class;
173
174   /**
175    * Associates a {@link PropertyNamer} with this bean to tailor the names of the bean properties.
176    *
177    * <p>
178    * Property namers are used to transform bean property names from standard form to some other form.
179    *
180    * <h5 class='section'>Example:</h5>
181    * <p class='bcode w800'>
182    *    <jc>// Define a class with dashed-lowercase property names.</jc>
183    *    <ja>@Bean</ja>(propertyNamer=PropertyNamerDashedLC.<jk>class</jk>)
184    *    <jk>public class</jk> MyBean {...}
185    * </p>
186    *
187    * <ul class='seealso'>
188    *    <li class='jf'>{@link BeanContext#BEAN_propertyNamer}
189    * </ul>
190    */
191   Class<? extends PropertyNamer> propertyNamer() default PropertyNamerDefault.class;
192
193   /**
194    * Sort bean properties in alphabetical order.
195    *
196    * <p>
197    * When <jk>true</jk>, all bean properties will be serialized and access in alphabetical order.
198    * <br>Otherwise, the natural order of the bean properties is used which is dependent on the JVM vendor.
199    *
200    * <h5 class='section'>Example:</h5>
201    * <p class='bcode w800'>
202    *    <jc>// Sort bean properties alphabetically during serialization.</jc>
203    *    <ja>@Bean</ja>(sort=<jk>true</jk>)
204    *    <jk>public class</jk> MyBean {...}
205    * </p>
206    *
207    * <ul class='seealso'>
208    *    <li class='jf'>{@link BeanContext#BEAN_sortProperties}
209    * </ul>
210    */
211   boolean sort() default false;
212
213   /**
214    * Identifies a stop class for the annotated class.
215    *
216    * <p>
217    * Identical in purpose to the stop class specified by {@link Introspector#getBeanInfo(Class, Class)}.
218    * Any properties in the stop class or in its base classes will be ignored during analysis.
219    *
220    * <p>
221    * For example, in the following class hierarchy, instances of <c>C3</c> will include property <c>p3</c>,
222    * but not <c>p1</c> or <c>p2</c>.
223    * <p class='bcode w800'>
224    *    <jk>public class</jk> C1 {
225    *       <jk>public int</jk> getP1();
226    *    }
227    *
228    *    <jk>public class</jk> C2 <jk>extends</jk> C1 {
229    *       <jk>public int</jk> getP2();
230    *    }
231    *
232    *    <ja>@Bean</ja>(stopClass=C2.<jk>class</jk>)
233    *    <jk>public class</jk> C3 <jk>extends</jk> C2 {
234    *       <jk>public int</jk> getP3();
235    *    }
236    * </p>
237    */
238   Class<?> stopClass() default Object.class;
239
240   /**
241    * An identifying name for this class.
242    *
243    * <p>
244    * The name is used to identify the class type during parsing when it cannot be inferred through reflection.
245    * <br>For example, if a bean property is of type <c>Object</c>, then the serializer will add the name to the
246    * output so that the class can be determined during parsing.
247    *
248    * <p>
249    * It is also used to specify element names in XML.
250    *
251    * <h5 class='section'>Example:</h5>
252    * <p class='bcode w800'>
253    *    <jc>// Use _type='mybean' to identify this bean.</jc>
254    *    <ja>@Bean</ja>(typeName=<js>"mybean"</js>)
255    *    <jk>public class</jk> MyBean {...}
256    * </p>
257    *
258    * <ul class='seealso'>
259    *    <li class='jf'>{@link BeanContext#BEAN_beanDictionary}
260    * </ul>
261    */
262   String typeName() default "";
263
264   /**
265    * The property name to use for representing the type name.
266    *
267    * <p>
268    * This can be used to override the name used for the <js>"_type"</js> property used by the {@link #typeName()} setting.
269    *
270    * <p>
271    * The default value if not specified is <js>"_type"</js> .
272    *
273    * <h5 class='section'>Example:</h5>
274    * <p class='bcode w800'>
275    *    <jc>// Use 'type' instead of '_type' for bean names.</jc>
276    *    <ja>@Bean</ja>(typePropertyName=<js>"type"</js>)
277    *    <jk>public class</jk> MyBean {...}
278    * </p>
279    *
280    * <ul class='seealso'>
281    *    <li class='jf'>{@link BeanContext#BEAN_beanTypePropertyName}
282    * </ul>
283    */
284   String typePropertyName() default "";
285}