| <!-- |
| /*************************************************************************************************************************** |
| * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations under the License. |
| ***************************************************************************************************************************/ |
| --> |
| |
| {updated} @Beanp Annotation |
| |
| <p> |
| The {@link oaj.annotation.Beanp @Beanp} annotation is used to tailor how |
| individual bean properties are interpreted by the framework. |
| </p> |
| <p> |
| The {@link oaj.annotation.Beanp#name() @Beanp(name)} annotation |
| is used to override the name of the bean property. |
| </p> |
| <p class='bpcode w800'> |
| <jk>public class</jk> MyBean { |
| <ja>@Beanp</ja>(name=<js>"Bar"</js>) |
| <jk>public</jk> String getFoo() {...} |
| } |
| </p> |
| <p> |
| The {@link oaj.annotation.Name @Name} annotation is a shortcut for specifying a bean property name: |
| </p> |
| <p class='bpcode w800'> |
| <jk>public class</jk> MyBean { |
| <ja>@Name</ja>(<js>"Bar"</js>) |
| <jk>public</jk> String getFoo() {...} |
| } |
| </p> |
| <p> |
| If the {@link oaj.BeanContext#BEAN_beanFieldVisibility} setting on the bean context excludes this field |
| (e.g. the visibility is set to the default of PUBLIC, but the field is PROTECTED), this annotation |
| can be used to force the field to be identified as a property. |
| </p> |
| <p class='bpcode w800'> |
| <jk>public class</jk> MyBean { |
| <ja>@Beanp</ja> |
| <jk>protected</jk> String getFoo() {...} |
| } |
| </p> |
| <p> |
| The bean property named <js>"*"</js> is the designated "dynamic property" which allows for "extra" bean |
| properties not otherwise defined. |
| This is similar in concept to the Jackson <ja>@JsonGetterAll</ja> and <ja>@JsonSetterAll</ja> |
| annotations, but generalized for all supported marshall languages. |
| The primary purpose is for backwards compatibility in parsing newer streams with addition |
| information into older beans. |
| </p> |
| <p> |
| The following shows various ways of using dynamic bean properties. |
| </p> |
| <p class='bpcode w800'> |
| <jc>// Option #1 - A simple public Map field.</jc> |
| <jc>// The field name can be anything.</jc> |
| <jk>public class</jk> BeanWithDynaField { |
| |
| <ja>@Beanp</ja>(name=<js>"*"</js>) |
| <jk>public</jk> Map<String,Object> extraStuff = <jk>new</jk> LinkedHashMap<String,Object>(); |
| } |
| |
| <jc>// Option #2 - Getters and setters.</jc> |
| <jc>// Method names can be anything.</jc> |
| <jc>// Getter must return a Map with String keys.</jc> |
| <jc>// Setter must take in two arguments, a String and Object.</jc> |
| <jk>public class</jk> BeanWithDynaMethods { |
| |
| <ja>@Beanp</ja>(name=<js>"*"</js>) |
| <jk>public</jk> Map<String,Object> getMyExtraStuff() { |
| ... |
| } |
| |
| <ja>@Beanp</ja>(name=<js>"*"</js>) |
| <jk>public void</jk> setAnExtraField(String name, Object value) { |
| ... |
| } |
| } |
| |
| <jc>// Option #3 - Getter only.</jc> |
| <jc>// Properties will be added through the getter.</jc> |
| <jk>public class</jk> BeanWithDynaGetterOnly { |
| |
| <ja>@Beanp</ja>(name=<js>"*"</js>) |
| <jk>public</jk> Map<String,Object> getMyExtraStuff() { |
| ... |
| } |
| } |
| </p> |
| <p> |
| Similar rules apply for value types and swaps. |
| The property values optionally can be any serializable type or use swaps. |
| </p> |
| <p class='bpcode w800'> |
| <jc>// A serializable type other than Object.</jc> |
| <jk>public class</jk> BeanWithDynaFieldWithListValues { |
| |
| <ja>@Beanp</ja>(name=<js>"*"</js>) |
| <jk>public</jk> Map<String,List<String>> getMyExtraStuff() { |
| ... |
| } |
| } |
| |
| <jc>// A swapped value.</jc> |
| <jk>public class</jk> BeanWithDynaFieldWithSwappedValues { |
| |
| <ja>@Beanp</ja>(name=<js>"*"</js>, swap=TemporalCalendarSwap.IsoOffsetDateTime.<jk>class</jk>) |
| <jk>public</jk> Map<String,Calendar> getMyExtraStuff() { |
| ... |
| } |
| } |
| </p> |
| <div class='info'> |
| Note that if you're not interested in these additional properties, you can also use the |
| {@link oaj.BeanContext#BEAN_ignoreUnknownBeanProperties} setting to ignore values |
| that don't fit into existing properties. |
| </div> |
| <p> |
| The {@link oaj.annotation.Beanp#value() @Beanp(value)} annotation |
| is a synonym for {@link oaj.annotation.Beanp#name() @Beanp(name)}. |
| Use it in cases where you're only specifying a name so that you can shorten your annotation. |
| </p> |
| <p> |
| The following annotations are equivalent: |
| </p> |
| <p class='bpcode w800'> |
| <ja>@Beanp</ja>(name=<js>"foo"</js>) |
| |
| <ja>@Beanp</ja>(<js>"foo"</js>) |
| </p> |
| <p> |
| The {@link oaj.annotation.Beanp#type() @Beanp(type)} annotation |
| is used to identify a specialized class type for a generalized property. |
| Normally the type is inferred through reflection of the field type or getter return type. |
| However, you'll want to specify this value if you're parsing beans where the bean property class |
| is an interface or abstract class to identify the bean type to instantiate. |
| Otherwise, you may cause an {@link java.lang.InstantiationException} when trying to set these fields. |
| </p> |
| <p> |
| This property must denote a concrete class with a no-arg constructor. |
| </p> |
| <p class='bpcode w800'> |
| <jk>public class</jk> MyBean { |
| |
| <jc>// Identify concrete type as a HashMap.</jc> |
| <ja>@Beanp</ja>(type=HashMap.<jk>class</jk>) |
| <jk>public</jk> Map <jf>p1</jf>; |
| } |
| </p> |
| <p> |
| The {@link oaj.annotation.BeanProperty#params() @Beanp(params)} annotation |
| is for bean properties of type map or collection. |
| It's used to identify the class types of the contents of the bean property object when |
| the general parameter types are interfaces or abstract classes. |
| </p> |
| <p class='bpcode w800'> |
| <jk>public class</jk> MyBean { |
| |
| <jc>// This is a HashMap<String,Integer>.</jc> |
| <ja>@Beanp</ja>(type=HashMap.<jk>class</jk>, params={String.<jk>class</jk>,Integer.<jk>class</jk>}) |
| <jk>public</jk> Map <jf>p1</jf>; |
| } |
| </p> |
| <p> |
| The {@link oaj.annotation.Beanp#bpi() @Beanp(bpi)} |
| annotation is used to limit which child properties are rendered by the serializers. |
| It can be used on any of the following bean property types: |
| </p> |
| <ul class='spaced-list'> |
| <li>Beans - Only render the specified properties of the bean. |
| <li>Maps - Only render the specified entries in the map. |
| <li>Bean/Map arrays - Same, but applied to each element in the array. |
| <li>Bean/Map collections - Same, but applied to each element in the collection. |
| </ul> |
| <p class='bpcode w800'> |
| <jk>public class</jk> MyClass { |
| |
| <jc>// Only render 'f1' when serializing this bean property.</jc> |
| <ja>@Beanp</ja>(bpi={<js>"f1"</js>}) |
| <jk>public</jk> MyChildClass x1 = <jk>new</jk> MyChildClass(); |
| } |
| |
| <jk>public class</jk> MyChildClass { |
| <jk>public int</jk> f1 = 1; |
| <jk>public int</jk> f2 = 2; |
| } |
| |
| <jc>// Renders "{x1:{f1:1}}"</jc> |
| String json = JsonSerializer.<jsf>DEFAULT</jsf>.serialize(<jk>new</jk> MyClass()); |
| </p> |
| <p> |
| The {@link oaj.annotation.Beanp#format() @Beanp(format)} |
| annotation specifies a String format for converting a bean property value to a formatted string. |
| </p> |
| <p class='bpcode w800'> |
| <jc>// Serialize a float as a string with 2 decimal places.</jc> |
| <ja>@Beanp</ja>(format=<js>"$%.2f"</js>) |
| <jk>public float</jk> <jf>price</jf>; |
| </p> |