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