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