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

@Bean Annotation

<p>
	The {@link oaj.annotation.Bean @Bean} annotation is used to tailor how beans are 
	interpreted by the framework.
</p>
<p> 
	Bean property inclusion and ordering on a bean class can be done using the 
	{@link oaj.annotation.Bean#properties() @Bean(properties)} annotation.
</p>
<p class='bpcode w800'>
	<jc>// Address class with only street/city/state properties (in that order).</jc>
	<jc>// All other properties are ignored.</jc>
	<ja>@Bean</ja>(bpi=<js>"street,city,state"</js>)
	<jk>public class</jk> Address { ... }
</p>
<p> 
	Bean properties can be excluded using the {@link oaj.annotation.Bean#bpx() @Bean(bpx)}
	annotation.
</p>
<p class='bpcode w800'>
	<jc>// Address class with only street/city/state properties (in that order).</jc>
	<jc>// All other properties are ignored.</jc>
	<ja>@Bean</ja>(bpx=<js>"city,state"</js>})
	<jk>public class</jk> Address { ... }
</p>
<p>
	Bean properties can be sorted alphabetically using {@link oaj.annotation.Bean#sort() @Bean(sort)}
</p>
<p class='bpcode w800'>
	<jc>// Address class with only street/city/state properties (in that order).</jc>
	<jc>// All other properties are ignored.</jc>
	<ja>@Bean</ja>(sort=<jk>true</jk>)
	<jk>public class</jk> MyBean { ... }
</p>
<p>
	The {@link oaj.annotation.Bean#propertyNamer() @Bean(propertyNamer)} annotation
	is used to provide customized naming of properties.
</p>
<p>
	Property namers are used to transform bean property names from standard form to some other form.
	For example, the {@link oaj.PropertyNamerDLC} will convert property names to 
	dashed-lowercase, and these will be used as attribute names in JSON and element names in XML.
</p>
<p class='bpcode w800'>
	<jc>// Define a class with dashed-lowercase property names.</jc>
	<ja>@Bean</ja>(propertyNamer=PropertyNamerDashedLC.<jk>class</jk>)
	<jk>public class</jk> MyBean { ... }
</p>
<p>
	The {@link oaj.annotation.Bean#interfaceClass @Bean(interfaceClass)} annotation is used
	to limit properties on beans to specific interface classes.
	When specified, only the list of properties defined on the interface class will be used during 
	serialization.
	Additional properties on subclasses will be ignored.
</p>
<p class='bpcode w800'>
	<jc>// Parent class</jc>
	<ja>@Bean</ja>(interfaceClass=A.<jk>class</jk>)
	<jk>public abstract class</jk> A {
		<jk>public</jk> String <jf>f0</jf> = <js>"f0"</js>;
	}
	
	<jc>// Child class</jc>
	<jk>public class</jk> A1 <jk>extends</jk> A {
		<jk>public</jk> String <jf>f1</jf> = <js>"f1"</js>;
	}

	JsonSerializer s = SimpleJsonSerializer.<jsf>DEFAULT</jsf>;
	
	A1 a1 = <jk>new</jk> A1();
	String r = s.serialize(a1);
	<jsm>assertEquals</jsm>(<js>"{f0:'f0'}"</js>, r);  <jc>// Note f1 is not serialized.</jc> 
</p>
<p>
	Note that this annotation can be used on the parent class so that it filters to all child classes.
	Or can be set individually on the child classes.
</p>
<p>
	The {@link oaj.annotation.Bean#stopClass @Bean(stopClass)} annotation is another
	way to limit which properties are serialized (except from the opposite direction).
	It's identical in purpose to the stop class specified by {@link java.beans.Introspector#getBeanInfo(Class, Class)}.
	Any properties in the stop class or in its base classes will be ignored during analysis.
</p>
<p>
	For example, in the following class hierarchy, instances of <c>C3</c> will include property 
	<c>p3</c>, but not <c>p1</c> or <c>p2</c>.
</p>
<p class='bpcode w800'>
	<jk>public class</jk> C1 {
		<jk>public int</jk> getP1();
	}

	<jk>public class</jk> C2 <jk>extends</jk> C1 {
		<jk>public int</jk> getP2();
	}

	<ja>@Bean</ja>(stopClass=C2.<jk>class</jk>)
	<jk>public class</jk> C3 <jk>extends</jk> C2 {
		<jk>public int</jk> getP3();
	}
</p>
<p>
	The {@link oaj.annotation.Bean#propertyFilter() @Bean(propertyFilter)} annotation
	and {@link oaj.transform.PropertyFilter} class can be used to perform interception
	and inline handling of bean getter and setter calls.
</p>
<p class='bpcode w800'>
	<jc>// Register filter on bean class.</jc>
	<ja>@Bean</ja>(propertyFilter=AddressPropertyFilter.<jk>class</jk>)
	<jk>public class</jk> Address {
		<jk>public</jk> String getTaxInfo() {...}
		<jk>public void</jk> setTaxInfo(String s) {...}
	}
				
	<jc>// Property filter that strips out sensitive information in our bean.</jc>
	<jk>public class</jk> AddressPropertyFilter <jk>extends</jk> PropertyFilter {
		
		<ja>@Override</ja> <jc>/* PropertyFilter */</jc>
		<jk>public</jk> Object readProperty(Object bean, String name, Object value) {
			<jk>if</jk> (<js>"taxInfo"</js>.equals(name))
				<jk>return</jk> <js>"redacted"</js>;
			<jk>return</jk> value;
		}

		<ja>@Override</ja> <jc>/* PropertyFilter */</jc>
		<jk>public</jk> Object writeProperty(Object bean, String name, Object value) {
			AddressBook a = (Address)bean;
			<jk>if</jk> (<js>"taxInfo"</js>.equals(name) &amp;&amp; <js>"redacted"</js>.equals(value))
				<jk>return</jk> TaxInfoUtils.<jsm>lookUpByName</jsm>(a.getStreet(), a.getCity(), a.getState());
			<jk>return</jk> value;
		}
	}	
</p>
