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<String,Object> extraStuff = <jk>new</jk> LinkedHashMap<String,Object>(); 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<String,Object> 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<String,Object> getMyExtraStuff() { 095 * ... 096 * } 097 * } 098 * 099 * <jc>// Option #4 - Getter, setter, and extra-keys method . 100 * // Define a method that returns a Collection<String> 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<String> 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<String,List<String>> 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<String,Calendar> 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}