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