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