<!--
/***************************************************************************************************************************
 * 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.
 ***************************************************************************************************************************/
 -->

{8.1.0-updated, 8.1.2-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&lt;String,Object&gt; extraStuff = <jk>new</jk> LinkedHashMap&lt;String,Object&gt;();
	}

	<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&lt;String,Object&gt; 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&lt;String,Object&gt; 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&lt;String,List&lt;String&gt;&gt; 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&lt;String,Calendar&gt; 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&lt;String,Integer&gt;.</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#properties() @Beanp(properties)} 
	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>
