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

BeanFilter Class

<p>
	The {@link oaj.transform.BeanFilter} class is the programmatic equivalent to the
	{@link oaj.annotation.Bean @Bean} annotation.
</p>
<p>
	In practice, it's usually simpler to use the {@link oaj.annotation.Bean @Bean} and 
	{@link oaj.annotation.Beanp @Beanp} annotations on your bean classes.
	However, bean filters make it possible to accomplish the same when you can't add annotations
	to existing code.
</p>
<p>
	Bean filters are defined through {@link oaj.transform.BeanFilterBuilder BeanFilterBuilders}.
</p>
<p>
	In the previous examples, we defined this bean annotation:
</p>
<p class='bpcode w800'>
	<ja>@Bean</ja>(bpi=<js>"street,city,state"</js>)
	<jk>public class</jk> Address { ... }
</p>
<p>
	The programmatic equivalent would be:
</p>				
<p class='bpcode w800'>
	<jk>public class</jk> AddressFilter <jk>extends</jk> BeanFilterBuilder&lt;Address&gt; {
		
		<jc>// Must provide a no-arg constructor!</jc>
		<jk>public</jk> AddressFilter() {
			bpi(<js>"street,city,state"</js>);  <jc>// The properties we want exposed.</jc>
		}
	}	
</p>		
<p>
	Bean filters are added to serializers and parsers using the following:
</p>
<ul class='javatree'>
	<li class='jf'>{@link oaj.BeanContext#BEAN_beanFilters}
	<li class='jm'>{@link oaj.BeanContextBuilder#beanFilters(Object...)}
</ul>
<p>
	For example:
</p>
<p class='bpcode w800'>			
	<jc>// Create a new JSON serializer and associate a bean filter with it.</jc>
	WriterSerializer s = JsonSerializer
		.<jsm>create</jsm>()
		.beanFilters(AddressFilter.<jk>class</jk>)
		.build();
</p>
<p>
	Note that if you use the annotation, you do NOT need to set anything on the serializers/parsers.
	The annotations will be detected and bean filters will automatically be created for them.
</p>
<p>
	The {@link oaj.BeanContextBuilder#beanFilters(Object...)} method also allows you to pass in interfaces.
	Any class that's not a subclass of {@link oaj.transform.BeanFilterBuilder} get interpreted 
	as bean interface classes.
	These cause bean implementations of those interfaces to only expose the properties defined on the 
	interface.
</p>
<p class='bpcode w800'>
	<jc>// An interface with the 3 properties we want serialized.</jc>
	<jk>public interface</jk> AddressInterface {
		<jk>public</jk> String getStreet();
		<jk>public</jk> String getCity();
		<jk>public</jk> String getState();
	}
	
	<jc>// Our bean implementation.</jc>
	<jk>public class</jk> Address <jk>implements</jk> AddressInterface {
		<jk>public</jk> String getStreet() {...};
		<jk>public</jk> String getCity() {...};
		<jk>public</jk> String getState() {...};
		<jk>public</jk> String getCountry() {...};
	}
	
	<jc>// Create a new JSON serializer that only exposes street,city,state on Address bean.</jc>
	<jc>// The 'country' field will be ignored.</jc>
	WriterSerializer s = JsonSerializer
		.<jsm>create</jsm>()
		.beanFilters(AddressInterface.<jk>class</jk>)
		.build();
</p>			
