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