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 * <h5 class='section'>See Also:</h5> 029 * <ul> 030 * <li class='link'><a class="doclink" href="../../../../overview-summary.html#juneau-marshall.BeanPropertyAnnotation">Overview > juneau-marshall > @BeanProperty Annotation</a> 031 * </ul> 032 */ 033@Documented 034@Target({FIELD,METHOD}) 035@Retention(RUNTIME) 036@Inherited 037public @interface BeanProperty { 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'> 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>@BeanProperty</ja>(name=<js>"*"</js>) 067 * <jk>public</jk> Map<String,Object> extraStuff = <jk>new</jk> LinkedHashMap<String,Object>(); 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>@BeanProperty</ja>(name=<js>"*"</js>) 077 * <jk>public</jk> Map<String,Object> getMyExtraStuff() { 078 * ... 079 * } 080 * 081 * <ja>@BeanProperty</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>@BeanProperty</ja>(name=<js>"*"</js>) 092 * <jk>public</jk> Map<String,Object> getMyExtraStuff() { 093 * ... 094 * } 095 * } 096 * </p> 097 * 098 *<p> 099 * Similar rules apply for value types and swaps. 100 * The property values optionally can be any serializable type or use swaps. 101 * <p class='bcode'> 102 * <jc>// A serializable type other than Object.</jc> 103 * <jk>public class</jk> BeanWithDynaFieldWithListValues { 104 * 105 * <ja>@BeanProperty</ja>(name=<js>"*"</js>) 106 * <jk>public</jk> Map<String,List<String>> getMyExtraStuff() { 107 * ... 108 * } 109 * } 110 * 111 * <jc>// A swapped value.</jc> 112 * <jk>public class</jk> BeanWithDynaFieldWithSwappedValues { 113 * 114 * <ja>@BeanProperty</ja>(name=<js>"*"</js>, swap=CalendarSwap.<jsf>ISO8601DTZ</jsf>.<jk>class</jk>) 115 * <jk>public</jk> Map<String,Calendar> getMyExtraStuff() { 116 * ... 117 * } 118 * } 119 * </p> 120 * 121 * <ul class='doctree'> 122 * <li class='info'> 123 * Note that if you're not interested in these additional properties, you can also use the 124 * {@link BeanContext#BEAN_ignoreUnknownBeanProperties} setting to ignore values that don't fit into existing 125 * properties. 126 * </ul> 127 */ 128 String name() default ""; 129 130 /** 131 * A synonym for {@link #name()}. 132 * 133 * <p> 134 * The following annotations are equivalent: 135 * 136 * <p class='bcode'> 137 * <ja>@BeanProperty</ja>(name=<js>"foo"</js>) 138 * 139 * <ja>@BeanProperty</ja>(<js>"foo"</js>) 140 * </p> 141 */ 142 String value() default ""; 143 144 /** 145 * Identifies a specialized class type for the property. 146 * 147 * <p> 148 * Normally this can be inferred through reflection of the field type or getter return type. 149 * However, you'll want to specify this value if you're parsing beans where the bean property class is an interface 150 * or abstract class to identify the bean type to instantiate. 151 * Otherwise, you may cause an {@link InstantiationException} when trying to set these fields. 152 * 153 * <p> 154 * This property must denote a concrete bean class with a no-arg constructor. 155 * 156 * <h5 class='section'>Example:</h5> 157 * <p class='bcode'> 158 * <jk>public class</jk> MyBean { 159 * 160 * <jc>// Identify concrete map type.</jc> 161 * <ja>@BeanProperty</ja>(type=HashMap.<jk>class</jk>) 162 * <jk>public</jk> Map <jf>p1</jf>; 163 * } 164 * </p> 165 */ 166 Class<?> type() default Object.class; 167 168 /** 169 * For bean properties of maps and collections, this annotation can be used to identify the class types of the 170 * contents of the bean property object when the generic parameter types are interfaces or abstract classes. 171 * 172 * <h5 class='section'>Example:</h5> 173 * <p class='bcode'> 174 * <jk>public class</jk> MyBean { 175 * 176 * <jc>// Identify concrete map type with String keys and Integer values.</jc> 177 * <ja>@BeanProperty</ja>(type=HashMap.<jk>class</jk>, params={String.<jk>class</jk>,Integer.<jk>class</jk>}) 178 * <jk>public</jk> Map <jf>p1</jf>; 179 * } 180 * </p> 181 */ 182 Class<?>[] params() default {}; 183 184 /** 185 * Used to limit which child properties are rendered by the serializers. 186 * 187 * <p> 188 * Can be used on any of the following bean property types: 189 * <ul class='spaced-list'> 190 * <li>Beans - Only render the specified properties of the bean. 191 * <li>Maps - Only render the specified entries in the map. 192 * <li>Bean/Map arrays - Same, but applied to each element in the array. 193 * <li>Bean/Map collections - Same, but applied to each element in the collection. 194 * </ul> 195 * 196 * <h5 class='section'>Example:</h5> 197 * <p class='bcode'> 198 * <jk>public class</jk> MyClass { 199 * 200 * <jc>// Only render 'f1' when serializing this bean property.</jc> 201 * <ja>@BeanProperty</ja>(properties=<js>"f1"</js>) 202 * <jk>public</jk> MyChildClass x1 = <jk>new</jk> MyChildClass(); 203 * } 204 * 205 * <jk>public class</jk> MyChildClass { 206 * <jk>public int</jk> f1 = 1; 207 * <jk>public int</jk> f2 = 2; 208 * } 209 * 210 * <jc>// Renders "{x1:{f1:1}}"</jc> 211 * String json = JsonSerializer.<jsf>DEFAULT</jsf>.serialize(<jk>new</jk> MyClass()); 212 * </p> 213 */ 214 String properties() default ""; 215 216 /** 217 * Bean dictionary. 218 * 219 * <p> 220 * The list of classes that make up the bean dictionary this bean property. 221 * 222 * <h5 class='section'>See Also:</h5> 223 * <ul> 224 * <li class='jf'>{@link BeanContext#BEAN_beanDictionary} 225 * </ul> 226 */ 227 Class<?>[] beanDictionary() default {}; 228 229 /** 230 * Specifies a String format for converting the bean property value to a formatted string. 231 * 232 * <p> 233 * Note that this is usually a one-way conversion during serialization. 234 * 235 * <p> 236 * During parsing, we will attempt to convert the value to the original form by using the 237 * {@link BeanSession#convertToType(Object, Class)} but there is no guarantee that this will succeed. 238 * 239 * <h5 class='section'>Example:</h5> 240 * <p class='bcode'> 241 * <ja>@BeanProperty</ja>(format=<js>"$%.2f"</js>) 242 * <jk>public float</jk> <jf>price</jf>; 243 * </p> 244 */ 245 String format() default ""; 246}