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.lang.annotation.*;
019
020import org.apache.juneau.*;
021
022/**
023 * Used tailor how bean properties get interpreted by the framework.
024 *
025 * <p>
026 * This annotation is applied to public fields and public getter/setter methods of beans.
027 *
028 * <ul class='seealso'>
029 *    <li class='link'>{@doc BeanpAnnotation}
030 * </ul>
031 *
032 * <div class='warn'>
033 *    <b>Deprecated</b> - {@link Beanp}.
034 * </div>
035 */
036@Documented
037@Target({FIELD,METHOD,PARAMETER})
038@Retention(RUNTIME)
039@Inherited
040@Deprecated
041public @interface BeanProperty {
042
043   /**
044    * Identifies the name of the property.
045    *
046    * <p>
047    * Normally, this is automatically inferred from the field name or getter method name of the property.
048    * However, this property can be used to assign a different property name from the automatically inferred value.
049    *
050    * <p>
051    * If the {@link BeanContext#BEAN_beanFieldVisibility} setting on the bean context excludes this field (e.g. the
052    * visibility is set to PUBLIC, but the field is PROTECTED), this annotation can be used to force the field to be
053    * identified as a property.
054    *
055    * <h5 class='topic'>Dynamic beans</h5>
056    * <p>
057    * The bean property named <js>"*"</js> is the designated "dynamic property" which allows for "extra" bean
058    * properties not otherwise defined.
059    * This is similar in concept to the Jackson <ja>@JsonGetterAll</ja> and <ja>@JsonSetterAll</ja> annotations.
060    * The primary purpose is for backwards compatibility in parsing newer streams with addition information into older
061    * beans.
062    *
063    * <p>
064    * The following examples show how to define dynamic bean properties.
065    * <p class='bcode w800'>
066    *    <jc>// Option #1 - A simple public Map field.
067    *    // The field name can be anything.</jc>
068    *    <jk>public class</jk> BeanWithDynaField {
069    *
070    *       <ja>@BeanProperty</ja>(name=<js>"*"</js>)
071    *       <jk>public</jk> Map&lt;String,Object&gt; extraStuff = <jk>new</jk> LinkedHashMap&lt;String,Object&gt;();
072    *    }
073    *
074    *    <jc>// Option #2 - Getters and setters.
075    *    // Method names can be anything.
076    *    // Getter must return a Map with String keys.
077    *    // Setter must take in two arguments.</jc>
078    *    <jk>public class</jk> BeanWithDynaMethods {
079    *
080    *       <ja>@BeanProperty</ja>(name=<js>"*"</js>)
081    *       <jk>public</jk> Map&lt;String,Object&gt; getMyExtraStuff() {
082    *          ...
083    *       }
084    *
085    *       <ja>@BeanProperty</ja>(name=<js>"*"</js>)
086    *       <jk>public void</jk> setAnExtraField(String name, Object value) {
087    *          ...
088    *       }
089    *    }
090    *
091    *    <jc>// Option #3 - Getter only.
092    *    // Properties will be added through the getter.</jc>
093    *    <jk>public class</jk> BeanWithDynaGetterOnly {
094    *
095    *       <ja>@BeanProperty</ja>(name=<js>"*"</js>)
096    *       <jk>public</jk> Map&lt;String,Object&gt; getMyExtraStuff() {
097    *          ...
098    *       }
099    *    }
100    *
101    *    <jc>// Option #4 - Getter, setter, and extra-keys method .
102    *    // Define a method that returns a Collection&lt;String&gt; with currently-set property names.</jc>
103    *    <jk>public class</jk> BeanWithDynaExtraKeys {
104    *
105    *       <ja>@BeanProperty</ja>(name=<js>"*"</js>)
106    *       <jk>public</jk> Object get(String name) {
107    *          ...
108    *       }
109    *
110    *       <ja>@BeanProperty</ja>(name=<js>"*"</js>)
111    *       <jk>public void</jk> set(String name, Object value) {
112    *          ...
113    *       }
114    *
115    *       <ja>@BeanProperty</ja>(name=<js>"*"</js>)
116    *       <jk>public</jk> Collection&lt;String&gt; extraKeys() {
117    *          ...
118    *       }
119    *    }
120    * </p>
121    *
122    *<p>
123    * Similar rules apply for value types and swaps.
124    * The property values optionally can be any serializable type or use swaps.
125    * <p class='bcode w800'>
126    *    <jc>// A serializable type other than Object.</jc>
127    *    <jk>public class</jk> BeanWithDynaFieldWithListValues {
128    *
129    *       <ja>@BeanProperty</ja>(name=<js>"*"</js>)
130    *       <jk>public</jk> Map&lt;String,List&lt;String&gt;&gt; getMyExtraStuff() {
131    *          ...
132    *       }
133    *    }
134    *
135    *    <jc>// A swapped value.</jc>
136    *    <jk>public class</jk> BeanWithDynaFieldWithSwappedValues {
137    *
138    *       <ja>@BeanProperty</ja>(name=<js>"*"</js>, swap=TemporalCalendarSwap.IsoLocalDateTime.<jk>class</jk>)
139    *       <jk>public</jk> Map&lt;String,Calendar&gt; getMyExtraStuff() {
140    *          ...
141    *       }
142    *    }
143    * </p>
144    *
145    * <div class='info'>
146    *    Note that if you're not interested in these additional properties, you can also use the
147    *    {@link BeanContext#BEAN_ignoreUnknownBeanProperties} setting to ignore values that don't fit into existing
148    *    properties.
149    * </div>
150    * <div class='info'>
151    *       Note that the {@link Name @Name} annotation can also be used for identifying a property name.
152    * </div>
153    */
154   String name() default "";
155
156   /**
157    * A synonym for {@link #name()}.
158    *
159    * <p>
160    * The following annotations are equivalent:
161    *
162    * <p class='bcode w800'>
163    *    <ja>@BeanProperty</ja>(name=<js>"foo"</js>)
164    *
165    *    <ja>@BeanProperty</ja>(<js>"foo"</js>)
166    * </p>
167    */
168   String value() default "";
169
170   /**
171    * Identifies a specialized class type for the property.
172    *
173    * <p>
174    * Normally this can be inferred through reflection of the field type or getter return type.
175    * However, you'll want to specify this value if you're parsing beans where the bean property class is an interface
176    * or abstract class to identify the bean type to instantiate.
177    * Otherwise, you may cause an {@link InstantiationException} when trying to set these fields.
178    *
179    * <p>
180    * This property must denote a concrete bean class with a no-arg constructor.
181    *
182    * <h5 class='section'>Example:</h5>
183    * <p class='bcode w800'>
184    *    <jk>public class</jk> MyBean {
185    *
186    *       <jc>// Identify concrete map type.</jc>
187    *       <ja>@BeanProperty</ja>(type=HashMap.<jk>class</jk>)
188    *       <jk>public</jk> Map <jf>p1</jf>;
189    *    }
190    * </p>
191    *
192    * <p>
193    * This annotation can also be used on private fields of a property like so:
194    *
195    * <h5 class='section'>Example:</h5>
196    * <p class='bcode w800'>
197    *    <jk>public class</jk> MyBean {
198    *
199    *       <ja>@BeanProperty</ja>(type=HashMap.<jk>class</jk>)
200    *       <jk>private</jk> Map <jf>p1</jf>;
201    *
202    *       <jk>public</jk> Map getP1() {
203    *          <jk>return</jk> <jf>p1</jf>;
204    *       }
205    *    }
206    * </p>
207    */
208   Class<?> type() default Object.class;
209
210   /**
211    * For bean properties of maps and collections, this annotation can be used to identify the class types of the
212    * contents of the bean property object when the generic parameter types are interfaces or abstract classes.
213    *
214    * <h5 class='section'>Example:</h5>
215    * <p class='bcode w800'>
216    *    <jk>public class</jk> MyBean {
217    *
218    *       <jc>// Identify concrete map type with String keys and Integer values.</jc>
219    *       <ja>@BeanProperty</ja>(type=HashMap.<jk>class</jk>, params={String.<jk>class</jk>,Integer.<jk>class</jk>})
220    *       <jk>public</jk> Map <jf>p1</jf>;
221    *    }
222    * </p>
223    *
224    * <p>
225    * This annotation can also be used on private fields of a property like so:
226    *
227    * <h5 class='section'>Example:</h5>
228    * <p class='bcode w800'>
229    *    <jk>public class</jk> MyBean {
230    *
231    *       <ja>@BeanProperty</ja>(type=HashMap.<jk>class</jk>, params={String.<jk>class</jk>,Integer.<jk>class</jk>})
232    *       <jk>private</jk> Map <jf>p1</jf>;
233    *
234    *       <jk>public</jk> Map getP1() {
235    *          <jk>return</jk> <jf>p1</jf>;
236    *       }
237    *    }
238    * </p>
239    */
240   Class<?>[] params() default {};
241
242   /**
243    * Used to limit which child properties are rendered by the serializers.
244    *
245    * <p>
246    * Can be used on any of the following bean property types:
247    * <ul class='spaced-list'>
248    *    <li>Beans - Only render the specified properties of the bean.
249    *    <li>Maps - Only render the specified entries in the map.
250    *    <li>Bean/Map arrays - Same, but applied to each element in the array.
251    *    <li>Bean/Map collections - Same, but applied to each element in the collection.
252    * </ul>
253    *
254    * <h5 class='section'>Example:</h5>
255    * <p class='bcode w800'>
256    *    <jk>public class</jk> MyClass {
257    *
258    *       <jc>// Only render 'f1' when serializing this bean property.</jc>
259    *       <ja>@BeanProperty</ja>(bpi=<js>"f1"</js>)
260    *       <jk>public</jk> MyChildClass x1 = <jk>new</jk> MyChildClass();
261    *    }
262    *
263    *    <jk>public class</jk> MyChildClass {
264    *       <jk>public int</jk> f1 = 1;
265    *       <jk>public int</jk> f2 = 2;
266    *    }
267    *
268    *    <jc>// Renders "{x1:{f1:1}}"</jc>
269    *    String json = JsonSerializer.<jsf>DEFAULT</jsf>.serialize(<jk>new</jk> MyClass());
270    * </p>
271    *
272    * <p>
273    * This annotation can also be used on private fields of a property like so:
274    *
275    * <h5 class='section'>Example:</h5>
276    * <p class='bcode w800'>
277    *    <jk>public class</jk> MyBean {
278    *
279    *       <ja>@BeanProperty</ja>(properties=<js>"f1"</js>)
280    *       <jk>private</jk> MyChildClass <jf>x1</jf>;
281    *
282    *       <jk>public</jk> MyChildClass getX1() {
283    *          <jk>return</jk> <jf>x1</jf>;
284    *       }
285    *    }
286    * </p>
287    */
288   String properties() default "";
289
290   /**
291    * Bean dictionary.
292    *
293    * <p>
294    * The list of classes that make up the bean dictionary this bean property.
295    *
296    * <ul class='seealso'>
297    *    <li class='jf'>{@link BeanContext#BEAN_beanDictionary}
298    * </ul>
299    *
300    * <p>
301    * This annotation can also be used on private fields of a property.
302    */
303   Class<?>[] beanDictionary() default {};
304
305   /**
306    * Specifies a String format for converting the bean property value to a formatted string.
307    *
308    * <p>
309    * Note that this is usually a one-way conversion during serialization.
310    *
311    * <p>
312    * During parsing, we will attempt to convert the value to the original form by using the
313    * {@link BeanSession#convertToType(Object, Class)} but there is no guarantee that this will succeed.
314    *
315    * <h5 class='section'>Example:</h5>
316    * <p class='bcode w800'>
317    *    <ja>@BeanProperty</ja>(format=<js>"$%.2f"</js>)
318    *    <jk>public float</jk> <jf>price</jf>;
319    * </p>
320    *
321    * <p>
322    * This annotation can also be used on private fields of a property like so:
323    *
324    * <h5 class='section'>Example:</h5>
325    * <p class='bcode w800'>
326    *    <jk>public class</jk> MyBean {
327    *
328    *       <ja>@BeanProperty</ja>(format=<js>"$%.2f"</js>)
329    *       <jk>private float</jk> <jf>price</jf>;
330    *
331    *       <jk>public float</jk> gePrice() {
332    *          <jk>return</jk> <jf>price</jf>;
333    *       }
334    *    }
335    * </p>
336    */
337   String format() default "";
338}