You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2016/08/28 21:46:18 UTC

incubator-juneau git commit: Make fields in BeanFilter and PojoSwap final.

Repository: incubator-juneau
Updated Branches:
  refs/heads/master 528bbfdfb -> ecc843021


Make fields in BeanFilter and PojoSwap final.

Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/ecc84302
Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/ecc84302
Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/ecc84302

Branch: refs/heads/master
Commit: ecc843021bd1cadd2c983192c7039d4682c41fcb
Parents: 528bbfd
Author: jamesbognar <ja...@gmail.com>
Authored: Sun Aug 28 17:46:14 2016 -0400
Committer: jamesbognar <ja...@gmail.com>
Committed: Sun Aug 28 17:46:14 2016 -0400

----------------------------------------------------------------------
 .../java/org/apache/juneau/BeanContext.java     |  18 +-
 .../main/java/org/apache/juneau/BeanMap.java    |  14 +-
 .../java/org/apache/juneau/BeanMapEntry.java    |   4 +-
 .../main/java/org/apache/juneau/BeanMeta.java   |  46 +--
 .../org/apache/juneau/BeanPropertyMeta.java     |  28 +-
 .../main/java/org/apache/juneau/ClassMeta.java  |  20 +-
 .../main/java/org/apache/juneau/ObjectMap.java  |  12 +-
 .../apache/juneau/annotation/BeanProperty.java  |   4 +-
 .../java/org/apache/juneau/annotation/Pojo.java |   2 +-
 .../org/apache/juneau/dto/cognos/Column.java    |  10 +-
 .../org/apache/juneau/dto/cognos/DataSet.java   |   4 +-
 .../org/apache/juneau/internal/StringUtils.java |  20 +
 .../juneau/serializer/SerializerSession.java    |   2 +-
 .../juneau/transform/AnnotationBeanFilter.java  |  71 ++--
 .../org/apache/juneau/transform/BeanFilter.java | 377 +++++++------------
 .../juneau/transform/InterfaceBeanFilter.java   |   3 +-
 .../org/apache/juneau/transform/PojoSwap.java   |  28 +-
 .../juneau/a/rttests/RoundTripBeanMapsTest.java |   8 +-
 .../apache/juneau/utils/StringUtilsTest.java    |   2 +-
 19 files changed, 300 insertions(+), 373 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanContext.java b/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
index 113e1f8..8b260bc 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
@@ -423,12 +423,12 @@ public class BeanContext extends Context {
 	public static final String BEAN_pojoSwaps = "BeanContext.pojoSwaps.list";
 
 	/**
-	 * Add to the list of transform classes.
+	 * Add to the list of POJO swap classes.
 	 */
 	public static final String BEAN_pojoSwaps_add = "BeanContext.pojoSwaps.list.add";
 
 	/**
-	 * Remove from the list of transform classes.
+	 * Remove from the list of POJO swap classes.
 	 */
 	public static final String BEAN_pojoSwaps_remove = "BeanContext.pojoSwaps.list.remove";
 
@@ -942,7 +942,7 @@ public class BeanContext extends Context {
 	public <T> ClassMeta<T> getClassMeta(Class<T> c) {
 
 		// If this is an array, then we want it wrapped in an uncached ClassMeta object.
-		// Note that if it has a pojo transform, we still want to cache it so that
+		// Note that if it has a pojo swap, we still want to cache it so that
 		// we can cache something like byte[] with ByteArrayBase64Swap.
 		if (c.isArray() && findPojoSwap(c) == null)
 			return new ClassMeta(c, this);
@@ -1414,9 +1414,9 @@ public class BeanContext extends Context {
 	 * Returns the {@link PojoSwap} associated with the specified class, or <jk>null</jk> if there is no
 	 * pojo swap associated with the class.
 	 *
-	 * @param <T> The class associated with the transform.
-	 * @param c The class associated with the transform.
-	 * @return The transform associated with the class, or null if there is no association.
+	 * @param <T> The class associated with the swap.
+	 * @param c The class associated with the swap.
+	 * @return The swap associated with the class, or null if there is no association.
 	 */
 	protected <T> PojoSwap findPojoSwap(Class<T> c) {
 		// Note:  On first
@@ -1444,9 +1444,9 @@ public class BeanContext extends Context {
 	 * Returns the {@link BeanFilter} associated with the specified class, or <jk>null</jk> if there is no
 	 * bean filter associated with the class.
 	 *
-	 * @param <T> The class associated with the transform.
-	 * @param c The class associated with the transform.
-	 * @return The transform associated with the class, or null if there is no association.
+	 * @param <T> The class associated with the bean filter.
+	 * @param c The class associated with the bean filter.
+	 * @return The bean filter associated with the class, or null if there is no association.
 	 */
 	protected <T> BeanFilter findBeanFilter(Class<T> c) {
 		if (c != null)

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanMap.java b/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
index fac7b92..5a23ad8 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
@@ -181,7 +181,7 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T
 	 * If there is a {@link PojoSwap} associated with this bean property or bean property type class, then
 	 * 	you must pass in a transformed value.
 	 * For example, if the bean property type class is a {@link Date} and the bean property has the
-	 * 	{@link org.apache.juneau.transforms.DateSwap.ISO8601DT} transform associated with it through the
+	 * 	{@link org.apache.juneau.transforms.DateSwap.ISO8601DT} swap associated with it through the
 	 * 	{@link BeanProperty#swap() @BeanProperty.swap()} annotation, the value being passed in must be
 	 * 	a String containing an ISO8601 date-time string value.
 	 *
@@ -192,7 +192,7 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T
 	 * 	<jc>// Construct a bean with a 'birthDate' Date field</jc>
 	 * 	Person p = <jk>new</jk> Person();
 	 *
-	 * 	<jc>// Create a bean context and add the ISO8601 date-time transform</jc>
+	 * 	<jc>// Create a bean context and add the ISO8601 date-time swap</jc>
 	 * 	BeanContext beanContext = <jk>new</jk> BeanContext().addPojoSwaps(DateSwap.ISO8601DT.<jk>class</jk>);
 	 *
 	 * 	<jc>// Wrap our bean in a bean map</jc>
@@ -235,8 +235,8 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T
 
 			throw new BeanRuntimeException(meta.c, "Bean property ''{0}'' not found.", property);
 		}
-		if (meta.transform != null)
-			if (meta.transform.writeProperty(this.bean, property, value))
+		if (meta.beanFilter != null)
+			if (meta.beanFilter.writeProperty(this.bean, property, value))
 				return null;
 		return p.set(this, value);
 	}
@@ -267,7 +267,7 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T
 	 * If there is a {@link PojoSwap} associated with this bean property or bean property type class, then
 	 * 	this method will return the transformed value.
 	 * For example, if the bean property type class is a {@link Date} and the bean property has the
-	 * 	{@link org.apache.juneau.transforms.DateSwap.ISO8601DT} transform associated with it through the
+	 * 	{@link org.apache.juneau.transforms.DateSwap.ISO8601DT} swap associated with it through the
 	 * 	{@link BeanProperty#swap() @BeanProperty.swap()} annotation, this method will return a String
 	 * 	containing an ISO8601 date-time string value.
 	 *
@@ -304,8 +304,8 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T
 		BeanPropertyMeta p = meta.properties.get(property);
 		if (p == null)
 			return null;
-		if (meta.transform != null && property != null)
-			return meta.transform.readProperty(this.bean, property.toString(), p.get(this));
+		if (meta.beanFilter != null && property != null)
+			return meta.beanFilter.readProperty(this.bean, property.toString(), p.get(this));
 		return p.get(this);
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/main/java/org/apache/juneau/BeanMapEntry.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanMapEntry.java b/juneau-core/src/main/java/org/apache/juneau/BeanMapEntry.java
index 6eba4ef..099f99e 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanMapEntry.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanMapEntry.java
@@ -68,7 +68,7 @@ public class BeanMapEntry implements Map.Entry<String,Object> {
 	 * If there is a {@link PojoSwap} associated with this bean property or bean property type class, then
 	 * 	this method will return the transformed value.
 	 * For example, if the bean property type class is a {@link Date} and the bean property has the
-	 * 	{@link org.apache.juneau.transforms.DateSwap.ISO8601DT} transform associated with it through the
+	 * 	{@link org.apache.juneau.transforms.DateSwap.ISO8601DT} swap associated with it through the
 	 * 	{@link BeanProperty#swap() @BeanProperty.swap()} annotation, this method will return a String
 	 * 	containing an ISO8601 date-time string value.
 	 */
@@ -87,7 +87,7 @@ public class BeanMapEntry implements Map.Entry<String,Object> {
 	 * If there is a {@link PojoSwap} associated with this bean property or bean property type class, then
 	 * 	you must pass in a transformed value.
 	 * For example, if the bean property type class is a {@link Date} and the bean property has the
-	 * 	{@link org.apache.juneau.transforms.DateSwap.ISO8601DT} transform associated with it through the
+	 * 	{@link org.apache.juneau.transforms.DateSwap.ISO8601DT} swap associated with it through the
 	 * 	{@link BeanProperty#swap() @BeanProperty.swap()} annotation, the value being passed in must be
 	 * 	a String containing an ISO8601 date-time string value.
 	 *

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java b/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
index 78f72a3..1453dbb 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
@@ -80,7 +80,7 @@ public class BeanMeta<T> {
 	protected BeanContext ctx;
 
 	/** Optional bean filter associated with the target class. */
-	protected BeanFilter<? extends T> transform;
+	protected BeanFilter<? extends T> beanFilter;
 
 	/** Type variables implemented by this bean. */
 	protected Map<Class<?>,Class<?>[]> typeVarImpls;
@@ -106,12 +106,12 @@ public class BeanMeta<T> {
 	 *
 	 * @param classMeta The target class.
 	 * @param ctx The bean context that created this object.
-	 * @param transform Optional bean filter associated with the target class.  Can be <jk>null</jk>.
+	 * @param beanFilter Optional bean filter associated with the target class.  Can be <jk>null</jk>.
 	 */
-	protected BeanMeta(final ClassMeta<T> classMeta, BeanContext ctx, org.apache.juneau.transform.BeanFilter<? extends T> transform) {
+	protected BeanMeta(final ClassMeta<T> classMeta, BeanContext ctx, BeanFilter<? extends T> beanFilter) {
 		this.classMeta = classMeta;
 		this.ctx = ctx;
-		this.transform = transform;
+		this.beanFilter = beanFilter;
 		this.classProperty = new BeanPropertyMeta(this, "_class", ctx.string());
 		this.c = classMeta.getInnerClass();
 	}
@@ -145,9 +145,9 @@ public class BeanMeta<T> {
 
 			// If @Bean.interfaceClass is specified on the parent class, then we want
 			// to use the properties defined on that class, not the subclass.
-			Class<?> c2 = (transform != null && transform.getInterfaceClass() != null ? transform.getInterfaceClass() : c);
+			Class<?> c2 = (beanFilter != null && beanFilter.getInterfaceClass() != null ? beanFilter.getInterfaceClass() : c);
 
-			Class<?> stopClass = (transform != null ? transform.getStopClass() : Object.class);
+			Class<?> stopClass = (beanFilter != null ? beanFilter.getStopClass() : Object.class);
 			if (stopClass == null)
 				stopClass = Object.class;
 
@@ -164,7 +164,7 @@ public class BeanMeta<T> {
 				return "Class is annotated with @BeanIgnore";
 
 			// Make sure it's serializable.
-			if (transform == null && ctx.beansRequireSerializable && ! isParentClass(Serializable.class, c))
+			if (beanFilter == null && ctx.beansRequireSerializable && ! isParentClass(Serializable.class, c))
 				return "Class is not serializable";
 
 			// Look for @BeanConstructor constructor.
@@ -188,7 +188,7 @@ public class BeanMeta<T> {
 			if (constructor == null)
 				constructor = (Constructor<T>)ClassMeta.findNoArgConstructor(c, conVis);
 
-			if (constructor == null && transform == null && ctx.beansRequireDefaultConstructor)
+			if (constructor == null && beanFilter == null && ctx.beansRequireDefaultConstructor)
 				return "Class does not have the required no-arg constructor";
 
 			if (! setAccessible(constructor))
@@ -197,15 +197,15 @@ public class BeanMeta<T> {
 			// Explicitly defined property names in @Bean annotation.
 			Set<String> fixedBeanProps = new LinkedHashSet<String>();
 
-			if (transform != null) {
+			if (beanFilter != null) {
 
 				// Get the 'properties' attribute if specified.
-				if (transform.getProperties() != null)
-					for (String p : transform.getProperties())
+				if (beanFilter.getProperties() != null)
+					for (String p : beanFilter.getProperties())
 						fixedBeanProps.add(p);
 
-				if (transform.getPropertyNamer() != null)
-					propertyNamer = transform.getPropertyNamer().newInstance();
+				if (beanFilter.getPropertyNamer() != null)
+					propertyNamer = beanFilter.getPropertyNamer();
 			}
 
 			if (propertyNamer == null)
@@ -307,27 +307,27 @@ public class BeanMeta<T> {
 			}
 
 			// Make sure at least one property was found.
-			if (transform == null && ctx.beansRequireSomeProperties && normalProps.size() == 0)
+			if (beanFilter == null && ctx.beansRequireSomeProperties && normalProps.size() == 0)
 				return "No properties detected on bean class";
 
-			boolean sortProperties = (ctx.sortProperties || (transform != null && transform.isSortProperties())) && fixedBeanProps.isEmpty();
+			boolean sortProperties = (ctx.sortProperties || (beanFilter != null && beanFilter.isSortProperties())) && fixedBeanProps.isEmpty();
 
 			properties = sortProperties ? new TreeMap<String,BeanPropertyMeta>() : new LinkedHashMap<String,BeanPropertyMeta>();
 
-			if (transform != null && transform.getSubTypeProperty() != null) {
-				String subTypeProperty = transform.getSubTypeProperty();
-				this.subTypeIdProperty = new SubTypePropertyMeta(subTypeProperty, transform.getSubTypes(), normalProps.remove(subTypeProperty));
+			if (beanFilter != null && beanFilter.getSubTypeProperty() != null) {
+				String subTypeProperty = beanFilter.getSubTypeProperty();
+				this.subTypeIdProperty = new SubTypePropertyMeta(subTypeProperty, beanFilter.getSubTypes(), normalProps.remove(subTypeProperty));
 				properties.put(subTypeProperty, this.subTypeIdProperty);
 			}
 
 			properties.putAll(normalProps);
 
-			// If a transform is defined, look for inclusion and exclusion lists.
-			if (transform != null) {
+			// If a beanFilter is defined, look for inclusion and exclusion lists.
+			if (beanFilter != null) {
 
 				// Eliminated excluded properties if BeanFilter.excludeKeys is specified.
-				String[] includeKeys = transform.getProperties();
-				String[] excludeKeys = transform.getExcludeProperties();
+				String[] includeKeys = beanFilter.getProperties();
+				String[] excludeKeys = beanFilter.getExcludeProperties();
 				if (excludeKeys != null) {
 					for (String k : excludeKeys)
 						properties.remove(k);
@@ -741,7 +741,7 @@ public class BeanMeta<T> {
 
 		@Override /* BeanPropertyMeta */
 		public Object get(BeanMap<?> m) throws BeanRuntimeException {
-			String subTypeId = transform.getSubTypes().get(c);
+			String subTypeId = beanFilter.getSubTypes().get(c);
 			if (subTypeId == null)
 				throw new BeanRuntimeException(c, "Unmapped sub type class");
 			return subTypeId;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java b/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java
index f35ce12..b9d18b9 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java
@@ -55,7 +55,7 @@ public class BeanPropertyMeta {
 		rawTypeMeta,                           // The real class type of the bean property.
 		typeMeta;                              // The transformed class type of the bean property.
 	private String[] properties;
-	private PojoSwap transform;      // PojoSwap defined only via @BeanProperty annotation.
+	private PojoSwap swap;                     // PojoSwap defined only via @BeanProperty annotation.
 
 	private MetadataMap extMeta = new MetadataMap();  // Extended metadata
 
@@ -138,7 +138,7 @@ public class BeanPropertyMeta {
 	 */
 	public ClassMeta<?> getClassMeta() {
 		if (typeMeta == null)
-			typeMeta = (transform != null ? transform.getSwapClassMeta(beanMeta.ctx) : rawTypeMeta == null ? beanMeta.ctx.object() : rawTypeMeta.getSerializedClassMeta());
+			typeMeta = (swap != null ? swap.getSwapClassMeta(beanMeta.ctx) : rawTypeMeta == null ? beanMeta.ctx.object() : rawTypeMeta.getSerializedClassMeta());
 		return typeMeta;
 	}
 
@@ -249,7 +249,7 @@ public class BeanPropertyMeta {
 			rawTypeMeta = f.getClassMeta(p, field.getGenericType(), typeVarImpls);
 			isUri |= (rawTypeMeta.isUri() || field.isAnnotationPresent(org.apache.juneau.annotation.URI.class));
 			if (p != null) {
-				transform = getPropertyPojoSwap(p);
+				swap = getPropertyPojoSwap(p);
 				if (p.properties().length != 0)
 					properties = p.properties();
 				isBeanUri |= p.beanUri();
@@ -262,8 +262,8 @@ public class BeanPropertyMeta {
 				rawTypeMeta = f.getClassMeta(p, getter.getGenericReturnType(), typeVarImpls);
 			isUri |= (rawTypeMeta.isUri() || getter.isAnnotationPresent(org.apache.juneau.annotation.URI.class));
 			if (p != null) {
-				if (transform == null)
-					transform = getPropertyPojoSwap(p);
+				if (swap == null)
+					swap = getPropertyPojoSwap(p);
 				if (properties != null && p.properties().length != 0)
 					properties = p.properties();
 				isBeanUri |= p.beanUri();
@@ -276,8 +276,8 @@ public class BeanPropertyMeta {
 				rawTypeMeta = f.getClassMeta(p, setter.getGenericParameterTypes()[0], typeVarImpls);
 			isUri |= (rawTypeMeta.isUri() || setter.isAnnotationPresent(org.apache.juneau.annotation.URI.class));
 			if (p != null) {
-			if (transform == null)
-				transform = getPropertyPojoSwap(p);
+			if (swap == null)
+				swap = getPropertyPojoSwap(p);
 				if (properties != null && p.properties().length != 0)
 					properties = p.properties();
 				isBeanUri |= p.beanUri();
@@ -549,8 +549,8 @@ public class BeanPropertyMeta {
 				}
 
 			} else {
-				if (transform != null && value != null && isParentClass(transform.getSwapClass(), value.getClass())) {
-						value = transform.unswap(value, rawTypeMeta, beanMeta.ctx);
+				if (swap != null && value != null && isParentClass(swap.getSwapClass(), value.getClass())) {
+						value = swap.unswap(value, rawTypeMeta, beanMeta.ctx);
 				} else {
 						value = beanMeta.ctx.convertToType(value, rawTypeMeta);
 					}
@@ -720,9 +720,9 @@ public class BeanPropertyMeta {
 	}
 
 	private Object transform(Object o) throws SerializeException {
-		// First use transform defined via @BeanProperty.
-		if (transform != null)
-			return transform.swap(o, beanMeta.ctx);
+		// First use swap defined via @BeanProperty.
+		if (swap != null)
+			return swap.swap(o, beanMeta.ctx);
 		if (o == null)
 			return null;
 		// Otherwise, look it up via bean context.
@@ -737,8 +737,8 @@ public class BeanPropertyMeta {
 	}
 
 	private Object unswap(Object o) throws ParseException {
-		if (transform != null)
-			return transform.unswap(o, rawTypeMeta, beanMeta.ctx);
+		if (swap != null)
+			return swap.unswap(o, rawTypeMeta, beanMeta.ctx);
 		if (o == null)
 			return null;
 		if (rawTypeMeta.hasChildPojoSwaps()) {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java b/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java
index c2aa67f..6da687c 100644
--- a/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java
@@ -55,14 +55,14 @@ public final class ClassMeta<T> implements Type {
 		MAP, COLLECTION, CLASS, NUMBER, DECIMAL, BOOLEAN, CHAR, DATE, ARRAY, ENUM, BEAN, UNKNOWN, OTHER, CHARSEQ, STR, OBJ, URI, BEANMAP, READER, INPUTSTREAM
 	}
 
-	final BeanContext beanContext;                      // The bean context that created this object.
+	final BeanContext beanContext;                    // The bean context that created this object.
 	ClassCategory classCategory = UNKNOWN;            // The class category.
 	final Class<T> innerClass;                        // The class being wrapped.
 	ClassMeta<?>
-		serializedClassMeta,                             // The transformed class type (in class has transform associated with it.
-		elementType = null,                            // If ARRAY or COLLECTION, the element class type.
-		keyType = null,                                // If MAP, the key class type.
-		valueType = null;                              // If MAP, the value class type.
+		serializedClassMeta,                          // The transformed class type (if class has swap associated with it).
+		elementType = null,                           // If ARRAY or COLLECTION, the element class type.
+		keyType = null,                               // If MAP, the key class type.
+		valueType = null;                             // If MAP, the value class type.
 	InvocationHandler invocationHandler;              // The invocation handler for this class (if it has one).
 	volatile BeanMeta<T> beanMeta;                    // The bean meta for this bean class (if it's a bean).
 	Method fromStringMethod;                          // The static valueOf(String) or fromString(String) method (if it has one).
@@ -75,17 +75,17 @@ public final class ClassMeta<T> implements Type {
 	Method namePropertyMethod;                        // The method to set the name on an object (if it has one).
 	Method parentPropertyMethod;                      // The method to set the parent on an object (if it has one).
 	String notABeanReason;                            // If this isn't a bean, the reason why.
-	PojoSwap<T,?> pojoSwap;                       // The object transform associated with this bean (if it has one).
+	PojoSwap<T,?> pojoSwap;                           // The object POJO swap associated with this bean (if it has one).
 	BeanFilter<? extends T> beanFilter;               // The bean filter associated with this bean (if it has one).
 	boolean
-		isDelegate,                                    // True if this class extends Delegate.
-		isAbstract,                                    // True if this class is abstract.
-		isMemberClass;                                 // True if this is a non-static member class.
+		isDelegate,                                   // True if this class extends Delegate.
+		isAbstract,                                   // True if this class is abstract.
+		isMemberClass;                                // True if this is a non-static member class.
 
 	private MetadataMap extMeta = new MetadataMap();  // Extended metadata
 
 	private Throwable initException;                   // Any exceptions thrown in the init() method.
-	private boolean hasChildPojoSwaps;               // True if this class or any subclass of this class has a PojoSwap associated with it.
+	private boolean hasChildPojoSwaps;                 // True if this class or any subclass of this class has a PojoSwap associated with it.
 	private Object primitiveDefault;                   // Default value for primitive type classes.
 	private Map<String,Method> remoteableMethods,      // Methods annotated with @Remoteable.  Contains all public methods if class is annotated with @Remotable.
 		publicMethods;                                 // All public methods, including static methods.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java b/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java
index 7237cf5..93dad9d 100644
--- a/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java
+++ b/juneau-core/src/main/java/org/apache/juneau/ObjectMap.java
@@ -347,21 +347,21 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	}
 
 	/**
-	 * Same as {@link Map#get(Object) get()}, but converts the raw value to the specified class type using the specified transform.
+	 * Same as {@link Map#get(Object) get()}, but converts the raw value to the specified class type using the specified beanFilter.
 	 *
 	 * @param <T> The transformed class type.
-	 * @param transform The transform class used to convert the raw type to a transformed type.
+	 * @param pojoSwap The swap class used to convert the raw type to a transformed type.
 	 * @param key The key.
 	 * @return The value, or <jk>null</jk> if the entry doesn't exist.
-	 * @throws ParseException Thrown by the transform if a problem occurred trying to parse the value.
+	 * @throws ParseException Thrown by the POJO swap if a problem occurred trying to parse the value.
 	 */
 	@SuppressWarnings({ "rawtypes", "unchecked" })
-	public <T> T get(PojoSwap<T,?> transform, String key) throws ParseException {
+	public <T> T get(PojoSwap<T,?> pojoSwap, String key) throws ParseException {
 		Object o = super.get(key);
 		if (o == null)
 			return null;
-		PojoSwap f = transform;
-		return (T)f.unswap(o, null, beanContext);
+		PojoSwap swap = pojoSwap;
+		return (T)swap.unswap(o, null, beanContext);
 	}
 
 	/**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java b/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java
index 3b91992..7363290 100644
--- a/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java
+++ b/juneau-core/src/main/java/org/apache/juneau/annotation/BeanProperty.java
@@ -35,7 +35,7 @@ import org.apache.juneau.xml.annotation.*;
  * 	<li>Identify a specific subclass for a property with a general class type.
  * 	<li>Identify class types of elements in properties of type <code>Collection</code> or <code>Map</code>.
  * 	<li>Hide properties during serialization.
- * 	<li>Associate transforms with bean property values, such as a transform to convert a <code>Calendar</code> field to a string.
+ * 	<li>Associate transforms with bean property values, such as a POJO swap to convert a <code>Calendar</code> field to a string.
  * 	<li>Override the list of properties during serialization on child elements of a property of type <code>Collection</code> or <code>Map</code>.
  * 	<li>Identify a property as the URL for a bean.
  * 	<li>Identify a property as the ID for a bean.
@@ -127,7 +127,7 @@ public @interface BeanProperty {
 	 * 	<jk>public class</jk> MyClass {
 	 *
 	 * 		<jc>// During serialization, convert to ISO8601 date-time string.</jc>
-	 * 		<ja>@BeanProperty</ja>(transform=CalendarSwap.ISO8601DT.<jk>class</jk>)
+	 * 		<ja>@BeanProperty</ja>(pojoSwap=CalendarSwap.ISO8601DT.<jk>class</jk>)
 	 * 		<jk>public</jk> Calendar getTime();
 	 * 	}
 	 * 		</p>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/main/java/org/apache/juneau/annotation/Pojo.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/annotation/Pojo.java b/juneau-core/src/main/java/org/apache/juneau/annotation/Pojo.java
index af001f5..f200622 100644
--- a/juneau-core/src/main/java/org/apache/juneau/annotation/Pojo.java
+++ b/juneau-core/src/main/java/org/apache/juneau/annotation/Pojo.java
@@ -51,7 +51,7 @@ public @interface Pojo {
 	 * 		<jk>public</jk> String <jf>f1</jf>;
 	 * 	}
 	 *
-	 * 	<jc>// Our transform to force the bean to be serialized as a String</jc>
+	 * 	<jc>// Our POJO swap to force the bean to be serialized as a String</jc>
 	 * 	<jk>public class</jk> BSwap <jk>extends</jk> PojoSwap&lt;B,String&gt; {
 	 * 		<jk>public</jk> String swap(B o) <jk>throws</jk> SerializeException {
 	 * 			<jk>return</jk> o.f1;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/main/java/org/apache/juneau/dto/cognos/Column.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/cognos/Column.java b/juneau-core/src/main/java/org/apache/juneau/dto/cognos/Column.java
index 3607451..98f0420 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/cognos/Column.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/cognos/Column.java
@@ -33,7 +33,7 @@ public class Column {
 
 	private String name, type;
 	private Integer length;
-	PojoSwap transform;
+	PojoSwap pojoSwap;
 
 	/** Bean constructor. */
 	public Column() {}
@@ -66,7 +66,7 @@ public class Column {
 	 * <p>
 	 * 	Typically used to define columns that don't exist on the underlying beans being serialized.
 	 * <p>
-	 * 	For example, the <code>AddressBookResource</code> sample defined the following transform
+	 * 	For example, the <code>AddressBookResource</code> sample defined the following POJO swap
 	 * 		to define an additional <js>"numAddresses"</js> column even though no such property exists
 	 * 		on the serialized beans.
 	 * <p class='bcode'>
@@ -81,11 +81,11 @@ public class Column {
 	 * 		);
 	 * </p>
 	 *
-	 * @param transform The transform to associate with the column.
+	 * @param pojoSwap The POJO swap to associate with the column.
 	 * @return This object (for method chaining).
 	 */
-	public Column addPojoSwap(PojoSwap transform) {
-		this.transform = transform;
+	public Column addPojoSwap(PojoSwap pojoSwap) {
+		this.pojoSwap = pojoSwap;
 		return this;
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/main/java/org/apache/juneau/dto/cognos/DataSet.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/cognos/DataSet.java b/juneau-core/src/main/java/org/apache/juneau/dto/cognos/DataSet.java
index 3228495..def8fcd 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/cognos/DataSet.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/cognos/DataSet.java
@@ -111,8 +111,8 @@ public class DataSet {
 						m = beanContext.forBean(o2);
 					for (Column col : columns) {
 						Object v;
-						if (col.transform != null)
-							v = col.transform.swap(o2, beanContext);
+						if (col.pojoSwap != null)
+							v = col.pojoSwap.swap(o2, beanContext);
 						else
 							v = m.get(col.getName());
 						r.add(v == null ? null : v.toString());

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java b/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java
index 6ed4d55..05d3c0b 100644
--- a/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java
+++ b/juneau-core/src/main/java/org/apache/juneau/internal/StringUtils.java
@@ -495,6 +495,26 @@ public final class StringUtils {
 	}
 
 	/**
+	 * Same as {@link #split(String, char)} except splits all strings in the input and returns a single result.
+	 *
+	 * @param s The string to split.  Can be <jk>null</jk>.
+	 * @param c The character to split on.
+	 * @return The tokens.
+	 */
+	public static String[] split(String[] s, char c) {
+		if (s == null)
+			return null;
+		List<String> l = new LinkedList<String>();
+		for (String ss : s) {
+			if (ss == null || ss.indexOf(c) == -1)
+				l.add(ss);
+			else
+				l.addAll(Arrays.asList(split(ss, c)));
+		}
+		return l.toArray(new String[l.size()]);
+	}
+
+	/**
 	 * Returns <jk>true</jk> if specified string is <jk>null</jk> or empty.
 	 *
 	 * @param s The string to check.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
index 0d9a917..3ea28e3 100644
--- a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
@@ -526,7 +526,7 @@ public class SerializerSession extends Session {
 	}
 
 	/**
-	 * Generalize the specified object if a transform is associated with it.
+	 * Generalize the specified object if a POJO swap is associated with it.
 	 *
 	 * @param o The object to generalize.
 	 * @param type The type of object.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilter.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilter.java b/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilter.java
index bf502b7..dd8cb4d 100644
--- a/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilter.java
+++ b/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilter.java
@@ -14,6 +14,7 @@ package org.apache.juneau.transform;
 
 import java.util.*;
 
+import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 
 /**
@@ -22,7 +23,7 @@ import org.apache.juneau.annotation.*;
  * <b>*** Internal class - Not intended for external use ***</b>
  *
  * @author James Bognar (james.bognar@salesforce.com)
- * @param <T> The class type that this transform applies to.
+ * @param <T> The class type that this bean filter applies to.
  */
 public final class AnnotationBeanFilter<T> extends BeanFilter<T> {
 
@@ -33,37 +34,63 @@ public final class AnnotationBeanFilter<T> extends BeanFilter<T> {
 	 * @param annotations The {@link Bean @Bean} annotations found on the class and all parent classes in child-to-parent order.
 	 */
 	public AnnotationBeanFilter(Class<T> annotatedClass, List<Bean> annotations) {
-		super(annotatedClass);
+		this(new Builder<T>(annotatedClass, annotations));
+	}
+
+	private AnnotationBeanFilter(Builder<T> b) {
+		super(b.beanClass, b.properties, b.excludeProperties, b.interfaceClass, b.stopClass, b.sortProperties, b.propertyNamer);
+
+		// Temp
+		setSubTypeProperty(b.subTypeProperty);
+		setSubTypes(b.subTypes);
+	}
+
+	private static class Builder<T> {
+		Class<T> beanClass;
+		String[] properties;
+		String[] excludeProperties;
+		Class<?> interfaceClass;
+		Class<?> stopClass;
+		boolean sortProperties;
+		PropertyNamer propertyNamer;
+		String subTypeProperty;
+		LinkedHashMap<Class<?>,String> subTypes = new LinkedHashMap<Class<?>,String>();
 
-		ListIterator<Bean> li = annotations.listIterator(annotations.size());
-		while (li.hasPrevious()) {
-			Bean b = li.previous();
+		private Builder(Class<T> annotatedClass, List<Bean> annotations) {
+			this.beanClass = annotatedClass;
+			ListIterator<Bean> li = annotations.listIterator(annotations.size());
+			while (li.hasPrevious()) {
+				Bean b = li.previous();
 
-			if (b.properties().length > 0 && getProperties() == null)
-				setProperties(b.properties());
+				if (b.properties().length > 0 && properties == null)
+					properties = b.properties();
 
-			if (b.sort())
-				setSortProperties(true);
+				if (b.sort())
+					sortProperties = true;
 
-			if (b.excludeProperties().length > 0)
-				setExcludeProperties(b.excludeProperties());
+				if (b.excludeProperties().length > 0 && excludeProperties == null)
+					excludeProperties = b.excludeProperties();
 
-			setPropertyNamer(b.propertyNamer());
+				if (b.propertyNamer() != PropertyNamerDefault.class)
+					try {
+						propertyNamer = b.propertyNamer().newInstance();
+					} catch (Exception e) {
+						throw new RuntimeException(e);
+					}
 
-			if (b.interfaceClass() != Object.class)
-				setInterfaceClass(b.interfaceClass());
+				if (b.interfaceClass() != Object.class && interfaceClass == null)
+					interfaceClass = b.interfaceClass();
 
-			if (b.stopClass() != Object.class)
-				setStopClass(b.stopClass());
+				if (b.stopClass() != Object.class)
+					stopClass = b.stopClass();
 
-			if (! b.subTypeProperty().isEmpty()) {
-				setSubTypeProperty(b.subTypeProperty());
 
-				LinkedHashMap<Class<?>,String> subTypes = new LinkedHashMap<Class<?>,String>();
-				for (BeanSubType bst : b.subTypes())
-					subTypes.put(bst.type(), bst.id());
+				if (! b.subTypeProperty().isEmpty()) {
+					subTypeProperty = b.subTypeProperty();
 
-				setSubTypes(subTypes);
+					for (BeanSubType bst : b.subTypes())
+						subTypes.put(bst.type(), bst.id());
+				}
 			}
 		}
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilter.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilter.java b/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilter.java
index 80d8fd7..92c6199 100644
--- a/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilter.java
+++ b/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilter.java
@@ -34,8 +34,8 @@ import org.apache.juneau.internal.*;
  *
  * <h6 class='topic'>Example</h6>
  * <p class='bcode'>
- * 	<jc>// Create our serializer with a bean filter.</jc> 
- * 	WriterSerializer s = <jk>new</jk> JsonSerializer().addBeanFilters(AddressFilter.<jk>class</jk>); 
+ * 	<jc>// Create our serializer with a bean filter.</jc>
+ * 	WriterSerializer s = <jk>new</jk> JsonSerializer().addBeanFilters(AddressFilter.<jk>class</jk>);
  *
  * 	Address a = <jk>new</jk> Address();
  * 	String json = s.serialize(a); <jc>// Serializes only street, city, state.</jc>
@@ -66,66 +66,143 @@ import org.apache.juneau.internal.*;
  */
 public abstract class BeanFilter<T> {
 
-	private Class<T> beanClass;
-	private String[] properties, excludeProperties;
+	private final Class<T> beanClass;
+	private final String[] properties, excludeProperties;
 	private LinkedHashMap<Class<?>, String> subTypes;
 	private String subTypeAttr;
-	private Class<? extends PropertyNamer> propertyNamer;
-	private Class<?> interfaceClass, stopClass;
-	private boolean sortProperties;
+	private final PropertyNamer propertyNamer;
+	private final Class<?> interfaceClass, stopClass;
+	private final boolean sortProperties;
 
 	/**
-	 * Constructor that determines the for-class value using reflection.
+	 * Constructor.
+	 *
+	 * @param beanClass
+	 * 	The bean class that this filter applies to.
+	 * 	If <jk>null</jk>, then the value is inferred through reflection.
+	 * @param properties
+	 * 	Specifies the set and order of names of properties associated with a bean class.
+	 * 	The order specified is the same order that the entries will be returned by the {@link BeanMap#entrySet()} and related methods.
+	 * 	Entries in the list can also contain comma-delimited lists that will be split.
+	 * @param excludeProperties
+	 * 	Specifies a list of properties to ignore on a bean.
+	 * @param interfaceClass
+	 * 	Identifies a class to be used as the interface class for this and all subclasses.
+	 * 	<p>
+	 * 	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 class='bcode'>
+	 * 	<jc>// Parent class</jc>
+	 * 	<jk>public abstract class</jk> A {
+	 * 		<jk>public</jk> String <jf>f0</jf> = <js>"f0"</js>;
+	 * 	}
+	 *
+	 * 	<jc>// Sub class</jc>
+	 * 	<jk>public class</jk> A1 <jk>extends</jk> A {
+	 * 		<jk>public</jk> String <jf>f1</jf> = <js>"f1"</js>;
+	 * 	}
+	 *
+	 * 	<jc>// Filter class</jc>
+	 * 	<jk>public class</jk> AFilter <jk>extends</jk> BeanFilter&lt;A&gt; {
+	 * 		<jk>public</jk> AFilter() {
+	 * 			setInterfaceClass(A.<jk>class</jk>);
+	 * 		}
+	 * 	}
+	 *
+	 * 	JsonSerializer s = new JsonSerializer().addBeanFilters(AFilter.<jk>class</jk>);
+	 * 	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 filter can be used on the parent class so that it filters to all child classes,
+	 * 		or can be set individually on the child classes.
+	 * @param stopClass
+	 * 	Identifies a stop class for this class and all subclasses.
+	 * 	<p>
+	 * 	Identical in purpose to the stop class specified by {@link Introspector#getBeanInfo(Class, Class)}.
+	 * 	Any properties in the stop class or in its base classes will be ignored during analysis.
+	 * 	<p>
+	 * 	For example, in the following class hierarchy, instances of <code>C3</code> will include property <code>p3</code>, but
+	 * 		not <code>p1</code> or <code>p2</code>.
+	 * 	<p class='bcode'>
+	 * 	<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>
+	 * @param sortProperties
+	 * 	Sort properties in alphabetical order.
+	 * @param propertyNamer
+	 * 	The property namer to use to name bean properties.
 	 */
 	@SuppressWarnings("unchecked")
-	public BeanFilter() {
-		super();
+	public BeanFilter(Class<T> beanClass, String[] properties, String[] excludeProperties, Class<?> interfaceClass, Class<?> stopClass, boolean sortProperties, PropertyNamer propertyNamer) {
 
-		Class<?> c = this.getClass().getSuperclass();
-		Type t = this.getClass().getGenericSuperclass();
-		while (c != BeanFilter.class) {
-			t = c.getGenericSuperclass();
-			c = c.getSuperclass();
-		}
+		if (beanClass == null) {
+			Class<?> c = this.getClass().getSuperclass();
+			Type t = this.getClass().getGenericSuperclass();
+			while (c != BeanFilter.class) {
+				t = c.getGenericSuperclass();
+				c = c.getSuperclass();
+			}
 
-		// Attempt to determine the T and G classes using reflection.
-		if (t instanceof ParameterizedType) {
-			ParameterizedType pt = (ParameterizedType)t;
-			Type[] pta = pt.getActualTypeArguments();
-			if (pta.length > 0) {
-				Type nType = pta[0];
-				if (nType instanceof Class)
-					this.beanClass = (Class<T>)nType;
+			// Attempt to determine the T and G classes using reflection.
+			if (t instanceof ParameterizedType) {
+				ParameterizedType pt = (ParameterizedType)t;
+				Type[] pta = pt.getActualTypeArguments();
+				if (pta.length > 0) {
+					Type nType = pta[0];
+					if (nType instanceof Class)
+						beanClass = (Class<T>)nType;
 
-				else
-					throw new RuntimeException("Unsupported parameter type: " + nType);
+					else
+						throw new RuntimeException("Unsupported parameter type: " + nType);
+				}
 			}
 		}
+
+		this.beanClass = beanClass;
+		this.properties = StringUtils.split(properties, ',');
+		this.excludeProperties = StringUtils.split(excludeProperties, ',');
+		this.interfaceClass = interfaceClass;
+		this.stopClass = stopClass;
+		this.sortProperties = sortProperties;
+		this.propertyNamer = propertyNamer;
 	}
 
 	/**
-	 * Constructor that specifies the for-class explicitly.
-	 * <p>
-	 * This constructor only needs to be called when the class type cannot be inferred through reflection.
+	 * Convenience constructor for defining interface bean filters.
 	 *
-	 * <dl>
-	 * 	<dt>Example:</dt>
-	 * 	<dd>
-	 * 		<p class='bcode'>
-	 * 	<jk>public class</jk> SomeArbitraryFilter <jk>extends</jk> BeanFilter&lt?&gt; {
-	 * 		<jk>public</jk> SomeArbitraryFiter(Class&lt?&gt; forClass) {
-	 * 			<jk>super</jk>(forClass);
-	 * 			...
-	 * 		}
-	 * 	}
-	 * 		</p>
-	 * 	</dd>
-	 * </dl>
+	 * @param interfaceClass The interface class.
+	 */
+	@SuppressWarnings("unchecked")
+	public BeanFilter(Class<?> interfaceClass) {
+		this((Class<T>)interfaceClass, null, null, interfaceClass, null, false, null);
+	}
+
+	/**
+	 * Convenience constructor for defining a bean filter that simply specifies the properties and order of properties for a bean.
 	 *
-	 * @param beanClass The class that this bean filter applies to.
+	 * @param properties
 	 */
-	public BeanFilter(Class<T> beanClass) {
-		this.beanClass = beanClass;
+	public BeanFilter(String...properties) {
+		this(null, properties, null, null, null, false, null);
+	}
+
+	/**
+	 * Dummy constructor.
+	 */
+	public BeanFilter() {
+		this((Class<T>)null);
 	}
 
 	/**
@@ -138,8 +215,6 @@ public abstract class BeanFilter<T> {
 
 	/**
 	 * Returns the set and order of names of properties associated with a bean class.
-	 *
-	 * @see #setProperties(String...)
 	 * @return The name of the properties associated with a bean class, or <jk>null</jk> if all bean properties should be used.
 	 */
 	public String[] getProperties() {
@@ -147,57 +222,11 @@ public abstract class BeanFilter<T> {
 	}
 
 	/**
-	 * Specifies the set and order of names of properties associated with a bean class.
-	 * <p>
-	 * 	The order specified is the same order that the entries will be returned by the {@link BeanMap#entrySet()} and related methods.
-	 * <p>
-	 * 	This method is an alternative to using the {@link Bean#properties()} annotation on a class.
-	 *
-	 * <dl>
-	 * 	<dt>Example:</dt>
-	 * 	<dd>
-	 * 		<p class='bcode'>
-	 * 	<jc>// Create our serializer with a bean filter.</jc>
-	 * 	WriterSerializer s = <jk>new</jk> JsonSerializer().addBeanFilters(AddressFilter.<jk>class</jk>);
-	 *
-	 * 	Address a = <jk>new</jk> Address();
-	 * 	String json = s.serialize(a); <jc>// Serializes only street, city, state.</jc>
-	 *
-	 * 	<jc>// Filter class</jc>
-	 * 	<jk>public class</jk> AddressFilter <jk>extends</jk> BeanFilter&lt;Address&gt; {
-	 * 		<jk>public</jk> AddressFilter() {
-	 * 			setProperties(<js>"street"</js>,<js>"city"</js>,<js>"state"</js>);
-	 * 		}
-	 * 	}
-	 * 		</p>
-	 * 	</dd>
-	 * </dl>
-	 *
-	 * @param properties The name of the properties associated with a bean class.
-	 * @return This object (for method chaining).
-	 */
-	public BeanFilter<T> setProperties(String...properties) {
-		this.properties = properties;
-		return this;
-	}
-
-	/**
-	 * Same as {@link #setProperties(String[])} but pass in a comma-delimited list of values.
-	 *
-	 * @param properties A comma-delimited list of properties.
-	 * @return This object (for method chaining).
-	 */
-	public BeanFilter<T> setProperties(String properties) {
-		return setProperties(StringUtils.split(properties, ','));
-	}
-
-	/**
 	 * Returns <jk>true</jk> if the properties defined on this bean class should be ordered alphabetically.
 	 * <p>
 	 * 	This method is only used when the {@link #getProperties()} method returns <jk>null</jk>.
 	 * 	Otherwise, the ordering of the properties in the returned value is used.
 	 *
-	 * @see #setSortProperties(boolean)
 	 * @return <jk>true</jk> if bean properties should be sorted.
 	 */
 	public boolean isSortProperties() {
@@ -205,24 +234,8 @@ public abstract class BeanFilter<T> {
 	}
 
 	/**
-	 * Specifies whether the properties on this bean should be ordered alphabetically.
-	 * <p>
-	 * 	This method is ignored if the {@link #getProperties()} method does not return <jk>null</jk>.
-	 * <p>
-	 * 	This method is an alternative to using the {@link Bean#sort()} annotation on a class.
-	 *
-	 * @param sortProperties The new value for the sort properties property.
-	 * @return This object (for method chaining).
-	 */
-	public BeanFilter<T> setSortProperties(boolean sortProperties) {
-		this.sortProperties = sortProperties;
-		return this;
-	}
-
-	/**
 	 * Returns the list of properties to ignore on a bean.
 	 *
-	 * @see #setExcludeProperties(String...)
 	 * @return The name of the properties to ignore on a bean, or <jk>null</jk> to not ignore any properties.
 	 */
 	public String[] getExcludeProperties() {
@@ -230,76 +243,15 @@ public abstract class BeanFilter<T> {
 	}
 
 	/**
-	 * Specifies a list of properties to ignore on a bean.
-	 * <p>
-	 * 	This method is an alternative to using the {@link Bean#excludeProperties()} annotation on a class.
-	 *
-	 * <dl>
-	 * 	<dt>Example:</dt>
-	 * 	<dd>
-	 * 		<p class='bcode'>
-	 * 	<jc>// Create our serializer with a bean filter.</jc>
-	 * 	WriterSerializer s = <jk>new</jk> JsonSerializer().addBeanFilters(NoCityOrStateFilter.<jk>class</jk>);
-	 *
-	 * 	Address a = <jk>new</jk> Address();
-	 * 	String json = s.serialize(a); <jc>// Excludes city and state.</jc>
-	 *
-	 * 	<jc>// Filter class</jc>
-	 * 	<jk>public class</jk> NoCityOrStateFilter <jk>extends</jk> BeanFilter&lt;Address&gt; {
-	 * 		<jk>public</jk> AddressFilter() {
-	 * 			setExcludeProperties(<js>"city"</js>,<js>"state"</js>);
-	 * 		}
-	 * 	}
-	 * 		</p>
-	 * 	</dd>
-	 * </dl>
-	 *
-	 * @param excludeProperties The name of the properties to ignore on a bean class.
-	 * @return This object (for method chaining).
-	 */
-	public BeanFilter<T> setExcludeProperties(String...excludeProperties) {
-		this.excludeProperties = excludeProperties;
-		return this;
-	}
-
-	/**
-	 * Same as {@link #setExcludeProperties(String[])} but pass in a comma-delimited list of values.
-	 *
-	 * @param excludeProperties A comma-delimited list of properties to eclipse.
-	 * @return This object (for method chaining).
-	 */
-	public BeanFilter<T> setExcludeProperties(String excludeProperties) {
-		return setExcludeProperties(StringUtils.split(excludeProperties, ','));
-	}
-
-	/**
 	 * Returns the {@link PropertyNamer} associated with the bean to tailor the names of bean properties.
 	 *
-	 * @see #setPropertyNamer(Class)
 	 * @return The property namer class, or <jk>null</jk> if no property namer is associated with this bean property.
 	 */
-	public Class<? extends PropertyNamer> getPropertyNamer() {
+	public PropertyNamer getPropertyNamer() {
 		return propertyNamer;
 	}
 
 	/**
-	 * Associates a {@link PropertyNamer} with this bean to tailor the names of the bean properties.
-	 * <p>
-	 * 	Property namers are used to transform bean property names from standard form to some other form.
-	 * 	For example, the {@link PropertyNamerDashedLC} will convert property names to dashed-lowercase, and
-	 * 		these will be used as attribute names in JSON, and element names in XML.
-	 * <p>
-	 * 	This method is an alternative to using the {@link Bean#propertyNamer()} annotation on a class.
-	 *
-	 * @param propertyNamer The property namer class.
-	 * @return This object (for method chaining).
-	 */
-	public BeanFilter<T> setPropertyNamer(Class<? extends PropertyNamer> propertyNamer) {
-		this.propertyNamer = propertyNamer;
-		return this;
-	}
-
-	/**
 	 * Returns the name of the sub type property associated with the bean class.
 	 *
 	 * @see #setSubTypeProperty(String)
@@ -362,6 +314,7 @@ public abstract class BeanFilter<T> {
 	 * @param subTypeAttr The name of the attribute representing the subtype.
 	 * @return This object (for method chaining).
 	 */
+	@Deprecated
 	public BeanFilter<T> setSubTypeProperty(String subTypeAttr) {
 		this.subTypeAttr = subTypeAttr;
 		return this;
@@ -373,6 +326,7 @@ public abstract class BeanFilter<T> {
 	 * @see #setSubTypeProperty(String)
 	 * @return The set of sub types associated with this bean class, or <jk>null</jk> if bean has no subtypes defined.
 	 */
+	@Deprecated
 	public LinkedHashMap<Class<?>, String> getSubTypes() {
 		return subTypes;
 	}
@@ -384,6 +338,7 @@ public abstract class BeanFilter<T> {
 	 * @param subTypes the map of subtype classes to subtype identifier strings.
 	 * @return This object (for method chaining).
 	 */
+	@Deprecated
 	public BeanFilter<T> setSubTypes(LinkedHashMap<Class<?>, String> subTypes) {
 		this.subTypes = subTypes;
 		return this;
@@ -397,6 +352,7 @@ public abstract class BeanFilter<T> {
 	 * @param id The subtype identifier string for the specified subtype class.
 	 * @return This object (for method chaining).
 	 */
+	@Deprecated
 	public BeanFilter<T> addSubType(Class<?> c, String id) {
 		if (subTypes == null)
 			subTypes = new LinkedHashMap<Class<?>, String>();
@@ -407,7 +363,6 @@ public abstract class BeanFilter<T> {
 	/**
 	 * Returns the interface class associated with this class.
 	 *
-	 * @see #setInterfaceClass(Class)
 	 * @return The interface class associated with this class, or <jk>null</jk> if no interface class is associated.
 	 */
 	public Class<?> getInterfaceClass() {
@@ -415,53 +370,8 @@ public abstract class BeanFilter<T> {
 	}
 
 	/**
-	 * Identifies a class to be used as the interface class for this and all subclasses.
-	 * <p>
-	 * 	Functionally equivalent to using the {@link Bean#interfaceClass()} annotation.
-	 * <p>
-	 * 	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 class='bcode'>
-	 * 	<jc>// Parent class</jc>
-	 * 	<jk>public abstract class</jk> A {
-	 * 		<jk>public</jk> String <jf>f0</jf> = <js>"f0"</js>;
-	 * 	}
-	 *
-	 * 	<jc>// Sub class</jc>
-	 * 	<jk>public class</jk> A1 <jk>extends</jk> A {
-	 * 		<jk>public</jk> String <jf>f1</jf> = <js>"f1"</js>;
-	 * 	}
-	 *
-	 * 	<jc>// Filter class</jc>
-	 * 	<jk>public class</jk> AFilter <jk>extends</jk> BeanFilter&lt;A&gt; {
-	 * 		<jk>public</jk> AFilter() {
-	 * 			setInterfaceClass(A.<jk>class</jk>);
-	 * 		}
-	 * 	}
-	 *
-	 * 	JsonSerializer s = new JsonSerializer().addBeanFilters(AFilter.<jk>class</jk>);
-	 * 	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 filter 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>
-	 * 	This method is an alternative to using the {@link Bean#interfaceClass()}} annotation.
-	 *
-	 * @param interfaceClass The interface class.
-	 * @return This object (for method chaining).
-	 */
-	public BeanFilter<T> setInterfaceClass(Class<?> interfaceClass) {
-		this.interfaceClass = interfaceClass;
-		return this;
-	}
-
-	/**
 	 * Returns the stop class associated with this class.
 	 *
-	 * @see #setStopClass(Class)
 	 * @return The stop class associated with this class, or <jk>null</jk> if no stop class is associated.
 	 */
 	public Class<?> getStopClass() {
@@ -469,39 +379,6 @@ public abstract class BeanFilter<T> {
 	}
 
 	/**
-	 * Identifies a stop class for this class and all subclasses.
-	 * <p>
-	 * 	Functionally equivalent to using the {@link Bean#stopClass()} annotation.
-	 * <p>
-	 * 	Identical in purpose to the stop class specified by {@link Introspector#getBeanInfo(Class, Class)}.
-	 * 	Any properties in the stop class or in its baseclasses will be ignored during analysis.
-	 * <p>
-	 * 	For example, in the following class hierarchy, instances of <code>C3</code> will include property <code>p3</code>, but
-	 * 		not <code>p1</code> or <code>p2</code>.
-	 * <p class='bcode'>
-	 * 	<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>
-	 *
-	 * @param stopClass The stop class.
-	 * @return This object (for method chaining).
-	 */
-	public BeanFilter<T> setStopClass(Class<?> stopClass) {
-		this.stopClass = stopClass;
-		return this;
-	}
-
-	/**
 	 * Subclasses can override this property to convert property values to some other
 	 * 	object just before serialization.
 	 *

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilter.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilter.java b/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilter.java
index 908d959..e042efc 100644
--- a/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilter.java
+++ b/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilter.java
@@ -23,7 +23,7 @@ import org.apache.juneau.*;
  * 		and are equivalent to adding a <code><ja>@Bean</ja>(interfaceClass=Foo.<jk>class</jk>)</code> annotation on the <code>Foo</code> class.
  *
  * @author James Bognar (james.bognar@salesforce.com)
- * @param <T> The class type that this transform applies to.
+ * @param <T> The class type that this bean filter applies to.
  */
 public class InterfaceBeanFilter<T> extends BeanFilter<T> {
 
@@ -34,6 +34,5 @@ public class InterfaceBeanFilter<T> extends BeanFilter<T> {
 	 */
 	public InterfaceBeanFilter(Class<T> interfaceClass) {
 		super(interfaceClass);
-		setInterfaceClass(interfaceClass);
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/main/java/org/apache/juneau/transform/PojoSwap.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/transform/PojoSwap.java b/juneau-core/src/main/java/org/apache/juneau/transform/PojoSwap.java
index 6e846dc..d289ce4 100644
--- a/juneau-core/src/main/java/org/apache/juneau/transform/PojoSwap.java
+++ b/juneau-core/src/main/java/org/apache/juneau/transform/PojoSwap.java
@@ -91,16 +91,17 @@ import org.apache.juneau.serializer.*;
  */
 public abstract class PojoSwap<T,S> {
 
-	Class<T> normalClass;
-	Class<S> swapClass;
-	ClassMeta<S> swapClassMeta;
+	private final Class<T> normalClass;
+	private final Class<S> swapClass;
+	private ClassMeta<S> swapClassMeta;
 
 	/**
 	 * Constructor.
 	 */
 	@SuppressWarnings("unchecked")
 	protected PojoSwap() {
-		super();
+
+		Class<?> t_normalClass = null, t_swapClass = null;
 
 		Class<?> c = this.getClass().getSuperclass();
 		Type t = this.getClass().getGenericSuperclass();
@@ -116,28 +117,31 @@ public abstract class PojoSwap<T,S> {
 			if (pta.length == 2) {
 				Type nType = pta[0];
 				if (nType instanceof Class) {
-					this.normalClass = (Class<T>)nType;
+					t_normalClass = (Class<T>)nType;
 
 				// <byte[],x> ends up containing a GenericArrayType, so it has to
 				// be handled as a special case.
 				} else if (nType instanceof GenericArrayType) {
 					Class<?> cmpntType = (Class<?>)((GenericArrayType)nType).getGenericComponentType();
-					this.normalClass = (Class<T>)Array.newInstance(cmpntType, 0).getClass();
+					t_normalClass = Array.newInstance(cmpntType, 0).getClass();
 
 				// <Class<?>,x> ends up containing a ParameterizedType, so just use the raw type.
 				} else if (nType instanceof ParameterizedType) {
-					this.normalClass = (Class<T>)((ParameterizedType)nType).getRawType();
+					t_normalClass = (Class<T>)((ParameterizedType)nType).getRawType();
 
 				} else
 					throw new RuntimeException("Unsupported parameter type: " + nType);
 				if (pta[1] instanceof Class)
-					this.swapClass = (Class<S>)pta[1];
+					t_swapClass = (Class<S>)pta[1];
 				else if (pta[1] instanceof ParameterizedType)
-					this.swapClass = (Class<S>)((ParameterizedType)pta[1]).getRawType();
+					t_swapClass = (Class<S>)((ParameterizedType)pta[1]).getRawType();
 				else
 					throw new RuntimeException("Unexpected transformed class type: " + pta[1].getClass().getName());
 			}
 		}
+
+		this.normalClass = (Class<T>)t_normalClass;
+		this.swapClass = (Class<S>)t_swapClass;
 	}
 
 	/**
@@ -170,7 +174,7 @@ public abstract class PojoSwap<T,S> {
 	 * @throws SerializeException If a problem occurred trying to convert the output.
 	 */
 	public S swap(T o) throws SerializeException {
-		throw new SerializeException("Generalize method not implemented on transform ''{0}''", this.getClass().getName());
+		throw new SerializeException("Swap method not implemented on PojoSwap ''{0}''", this.getClass().getName());
 	}
 
 	/**
@@ -195,11 +199,11 @@ public abstract class PojoSwap<T,S> {
 	 * @throws ParseException If this method is not implemented.
 	 */
 	public T unswap(S f) throws ParseException {
-		throw new ParseException("Narrow method not implemented on transform ''{0}''", this.getClass().getName());
+		throw new ParseException("Unswap method not implemented on PojoSwap ''{0}''", this.getClass().getName());
 	}
 
 	/**
-	 *	Same as {@link #unswap(Object)}, but override this method if you need access to the real class type or the bean context that created this swap. 
+	 *	Same as {@link #unswap(Object)}, but override this method if you need access to the real class type or the bean context that created this swap.
 	 *
 	 * @param f The transformed object.
 	 * @param hint If possible, the parser will try to tell you the object type being created.  For example,

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java b/juneau-core/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
index 972054f..143c677 100755
--- a/juneau-core/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
+++ b/juneau-core/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
@@ -523,7 +523,7 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 	}
 	public static class D2Filter extends BeanFilter<D2> {
 		public D2Filter() {
-			setProperties("f3","f2");
+			super("f3","f2");
 		}
 	}
 
@@ -585,7 +585,7 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 	}
 	public static class E2Filter extends BeanFilter<E2> {
 		public E2Filter() {
-			setExcludeProperties("f2");
+			super(null, null, new String[]{"f2"}, null, null, false, null);
 		}
 	}
 
@@ -677,12 +677,12 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 	}
 	public static class FB1Filter extends BeanFilter<FB1> {
 		public FB1Filter() {
-			setInterfaceClass(FB1.class);
+			super(FB1.class);
 		}
 	}
 	public static class FB2Filter extends BeanFilter<FB2> {
 		public FB2Filter() {
-			setInterfaceClass(FB1.class);
+			super(FB1.class);
 		}
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/ecc84302/juneau-core/src/test/java/org/apache/juneau/utils/StringUtilsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/test/java/org/apache/juneau/utils/StringUtilsTest.java b/juneau-core/src/test/java/org/apache/juneau/utils/StringUtilsTest.java
index e66a047..0fb5c75 100755
--- a/juneau-core/src/test/java/org/apache/juneau/utils/StringUtilsTest.java
+++ b/juneau-core/src/test/java/org/apache/juneau/utils/StringUtilsTest.java
@@ -462,7 +462,7 @@ public class StringUtilsTest {
 	public void testSplit() throws Exception {
 		String[] r;
 
-		assertNull(split(null, ','));
+		assertNull(split((String)null, ','));
 		assertObjectEquals("[]", split("", ','));
 		assertObjectEquals("['1']", split("1", ','));
 		assertObjectEquals("['1','2']", split("1,2", ','));