Repository: incubator-juneau
Updated Branches:
  refs/heads/master f479285a7 -> cebe92113


Create BeanFilterBuilder class.

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

Branch: refs/heads/master
Commit: cebe92113e2c660b01d012fb5ee7712546b434b2
Parents: f479285
Author: jamesbognar <[email protected]>
Authored: Sat Sep 10 12:08:26 2016 -0400
Committer: jamesbognar <[email protected]>
Committed: Sat Sep 10 12:08:26 2016 -0400

----------------------------------------------------------------------
 .../java/org/apache/juneau/BeanContext.java     |  22 +-
 .../java/org/apache/juneau/BeanDictionary.java  |   6 +-
 .../apache/juneau/BeanDictionaryBuilder.java    |   6 +-
 .../main/java/org/apache/juneau/BeanMeta.java   |   8 +-
 .../main/java/org/apache/juneau/ClassMeta.java  |   9 +-
 .../juneau/transform/AnnotationBeanFilter.java  | 103 -------
 .../transform/AnnotationBeanFilterBuilder.java  |  79 +++++
 .../org/apache/juneau/transform/BeanFilter.java | 235 +--------------
 .../juneau/transform/BeanFilterBuilder.java     | 287 ++++++++++++++++++-
 .../juneau/transform/InterfaceBeanFilter.java   |  37 ---
 .../transform/InterfaceBeanFilterBuilder.java   |  37 +++
 .../java/org/apache/juneau/BeanConfigTest.java  |  18 +-
 .../juneau/a/rttests/RoundTripBeanMapsTest.java |  39 ++-
 .../juneau/server/annotation/RestResource.java  |   4 +-
 .../juneau/server/jaxrs/JuneauProvider.java     |   4 +-
 15 files changed, 484 insertions(+), 410 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/cebe9211/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 d00f029..0834363 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
@@ -393,10 +393,18 @@ public class BeanContext extends Context {
        /**
         * List of bean filters registered on the bean context 
(<code>List&lt;Class&gt;</code>).
         * <p>
+        * This is a programmatic equivalent to the {@link Bean @Bean} 
annotation.
+        * It's useful when you want to use the Bean annotation functionality, 
but you don't have the ability
+        *      to alter the bean classes.
+        * <p>
         * There are two category of classes that can be passed in through this 
method:
         * <ul class='spaced-list'>
-        *      <li>Subclasses of {@link BeanFilter}.
-        *      <li>Bean interface classes.  A shortcut for defining a {@link 
InterfaceBeanFilter}.
+        *      <li>Subclasses of {@link BeanFilterBuilder}.  
+        *              These must have a public no-arg constructor.
+        *      <li>Bean interface classes.  
+        *              A shortcut for defining a {@link 
InterfaceBeanFilterBuilder}.
+        *              Any subclasses of an interface class will only have 
properties defined on the interface.
+        *              All other bean properties will be ignored.
         * </ul>
         */
        public static final String BEAN_beanFilters = 
"BeanContext.beanFilters.list";
@@ -550,7 +558,7 @@ public class BeanContext extends Context {
 
        final Class<?>[] notBeanClasses;
        final String[] notBeanPackageNames, notBeanPackagePrefixes;
-       final BeanFilter<?>[] beanFilters;
+       final BeanFilter[] beanFilters;
        final PojoSwap<?,?>[] pojoSwaps;
        final BeanDictionary beanDictionary;
        final Map<Class<?>,Class<?>> implClasses;
@@ -620,13 +628,15 @@ public class BeanContext extends Context {
                notBeanPackageNames = l1.toArray(new String[l1.size()]);
                notBeanPackagePrefixes = l2.toArray(new String[l2.size()]);
 
-               LinkedList<BeanFilter<?>> lbf = new LinkedList<BeanFilter<?>>();
+               LinkedList<BeanFilter> lbf = new LinkedList<BeanFilter>();
                try {
                        for (Class<?> c : pm.get(BEAN_beanFilters, 
Class[].class, new Class[0])) {
                                if (isParentClass(BeanFilter.class, c))
-                                       lbf.add((BeanFilter<?>)c.newInstance());
+                                       lbf.add((BeanFilter)c.newInstance());
+                               else if (isParentClass(BeanFilterBuilder.class, 
c))
+                                       
lbf.add(((BeanFilterBuilder)c.newInstance()).build());
                                else
-                                       lbf.add(new InterfaceBeanFilter(c));
+                                       lbf.add(new 
InterfaceBeanFilterBuilder(c).build());
                        }
                } catch (Exception e) {
                        throw new RuntimeException(e);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/cebe9211/juneau-core/src/main/java/org/apache/juneau/BeanDictionary.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanDictionary.java 
b/juneau-core/src/main/java/org/apache/juneau/BeanDictionary.java
index d5dddc0..22dff49 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanDictionary.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanDictionary.java
@@ -38,11 +38,11 @@ public class BeanDictionary {
        private final BeanContext beanContext;
        private final String beanTypePropertyName;
 
-       BeanDictionary(BeanContext beanContext, Map<String,Class<?>> map) {
-               this.beanContext = beanContext;
+       BeanDictionary(BeanDictionaryBuilder builder) {
+               this.beanContext = builder.beanContext;
                this.beanTypePropertyName = 
beanContext.getBeanTypePropertyName();
                Map<String,ClassMeta<?>> m1 = new 
HashMap<String,ClassMeta<?>>();
-               for (Map.Entry<String,Class<?>> e : map.entrySet()) {
+               for (Map.Entry<String,Class<?>> e : builder.map.entrySet()) {
                        ClassMeta<?> cm = 
beanContext.getClassMeta(e.getValue());
                        if (! cm.isBean())
                                throw new BeanRuntimeException("Invalid class 
type passed to dictionary.  ''{0}'' is not a bean.", cm);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/cebe9211/juneau-core/src/main/java/org/apache/juneau/BeanDictionaryBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/BeanDictionaryBuilder.java 
b/juneau-core/src/main/java/org/apache/juneau/BeanDictionaryBuilder.java
index 5900b53..7abb9a3 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanDictionaryBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanDictionaryBuilder.java
@@ -27,8 +27,8 @@ import org.apache.juneau.internal.*;
  */
 public class BeanDictionaryBuilder {
 
-       private Map<String,Class<?>> map = new HashMap<String,Class<?>>();
-       private BeanContext beanContext;
+       Map<String,Class<?>> map = new HashMap<String,Class<?>>();
+       BeanContext beanContext;
 
        /**
         * Add the specified classes to this type dictionary.
@@ -70,6 +70,6 @@ public class BeanDictionaryBuilder {
        }
 
        BeanDictionary build() {
-               return new BeanDictionary(beanContext, map);
+               return new BeanDictionary(this);
        }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/cebe9211/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 d68402d..6cdf591 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
@@ -79,7 +79,7 @@ public class BeanMeta<T> {
        protected final BeanContext ctx;
 
        /** Optional bean filter associated with the target class. */
-       protected final BeanFilter<? extends T> beanFilter;
+       protected final BeanFilter beanFilter;
 
        /** Type variables implemented by this bean. */
        protected final Map<Class<?>,Class<?>[]> typeVarImpls;
@@ -106,7 +106,7 @@ public class BeanMeta<T> {
         * @param beanFilter Optional bean filter associated with the target 
class.  Can be <jk>null</jk>.
         * @param pNames Explicit list of property names and order of 
properties.  If <jk>null</jk>, determine automatically.
         */
-       protected BeanMeta(final ClassMeta<T> classMeta, BeanContext ctx, 
BeanFilter<? extends T> beanFilter, String[] pNames) {
+       protected BeanMeta(final ClassMeta<T> classMeta, BeanContext ctx, 
BeanFilter beanFilter, String[] pNames) {
                this.classMeta = classMeta;
                this.ctx = ctx;
                this.c = classMeta.getInnerClass();
@@ -131,7 +131,7 @@ public class BeanMeta<T> {
        private static final class Builder<T> {
                ClassMeta<T> classMeta;
                BeanContext ctx;
-               BeanFilter<? extends T> beanFilter;
+               BeanFilter beanFilter;
                String[] pNames;
                Map<String,BeanPropertyMeta> properties;
                Map<Method,String> getterProps = new HashMap<Method,String>();
@@ -143,7 +143,7 @@ public class BeanMeta<T> {
                BeanPropertyMeta subTypeIdProperty;
                PropertyNamer propertyNamer;
 
-               private Builder(ClassMeta<T> classMeta, BeanContext ctx, 
BeanFilter<? extends T> beanFilter, String[] pNames) {
+               private Builder(ClassMeta<T> classMeta, BeanContext ctx, 
BeanFilter beanFilter, String[] pNames) {
                        this.classMeta = classMeta;
                        this.ctx = ctx;
                        this.beanFilter = beanFilter;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/cebe9211/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 06dac33..9ae3788 100644
--- a/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java
@@ -76,7 +76,7 @@ public final class ClassMeta<T> implements Type {
        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 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).
+       BeanFilter 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.
@@ -437,17 +437,16 @@ public final class ClassMeta<T> implements Type {
                return hasChildPojoSwaps;
        }
 
-       @SuppressWarnings("unchecked")
-       private BeanFilter<? extends T> findBeanFilter(BeanContext context) {
+       private BeanFilter findBeanFilter(BeanContext context) {
                try {
                        if (context == null)
                                return null;
-                       BeanFilter<? extends T> f = 
context.findBeanFilter(innerClass);
+                       BeanFilter f = context.findBeanFilter(innerClass);
                        if (f != null)
                                return f;
                        List<Bean> ba = 
ReflectionUtils.findAnnotations(Bean.class, innerClass);
                        if (! ba.isEmpty())
-                               f = new AnnotationBeanFilter<T>(innerClass, ba);
+                               f = new AnnotationBeanFilterBuilder(innerClass, 
ba).build();
                        return f;
                } catch (Exception e) {
                        throw new RuntimeException(e);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/cebe9211/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
deleted file mode 100644
index ae8d649..0000000
--- 
a/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilter.java
+++ /dev/null
@@ -1,103 +0,0 @@
-// 
***************************************************************************************************************************
-// * 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.                                              *
-// 
***************************************************************************************************************************
-package org.apache.juneau.transform;
-
-import java.util.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.annotation.*;
-
-/**
- * Bean filter constructed from a {@link Bean @Bean} annotation found on a 
class.
- * <p>
- * <b>*** Internal class - Not intended for external use ***</b>
- *
- * @author James Bognar ([email protected])
- * @param <T> The class type that this bean filter applies to.
- */
-public final class AnnotationBeanFilter<T> extends BeanFilter<T> {
-
-       /**
-        * Constructor.
-        *
-        * @param annotatedClass The class found to have a {@link Bean @Bean} 
annotation.
-        * @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) {
-               this(new Builder<T>(annotatedClass, annotations));
-       }
-
-       private AnnotationBeanFilter(Builder<T> b) {
-               super(b.beanClass, b.typeName, b.properties, 
b.excludeProperties, b.interfaceClass, b.stopClass, b.sortProperties, 
b.propertyNamer, b.subTypeProperty, b.subTypes);
-       }
-
-       private static class Builder<T> {
-               Class<T> beanClass;
-               String typeName;
-               String[] properties;
-               String[] excludeProperties;
-               Class<?> interfaceClass;
-               Class<?> stopClass;
-               boolean sortProperties;
-               PropertyNamer propertyNamer;
-               String subTypeProperty;
-               LinkedHashMap<Class<?>,String> subTypes = new 
LinkedHashMap<Class<?>,String>();
-
-               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 && properties == 
null)
-                                       properties = b.properties();
-
-                               if (! b.typeName().isEmpty())
-                                       typeName = b.typeName();
-
-                               if (b.sort())
-                                       sortProperties = true;
-
-                               if (b.excludeProperties().length > 0 && 
excludeProperties == null)
-                                       excludeProperties = 
b.excludeProperties();
-
-                               if (b.propertyNamer() != 
PropertyNamerDefault.class)
-                                       try {
-                                               propertyNamer = 
b.propertyNamer().newInstance();
-                                       } catch (Exception e) {
-                                               throw new RuntimeException(e);
-                                       }
-
-                               if (b.interfaceClass() != Object.class && 
interfaceClass == null)
-                                       interfaceClass = b.interfaceClass();
-
-                               if (b.stopClass() != Object.class)
-                                       stopClass = b.stopClass();
-
-                               if (b.subTypes().length > 0) {
-                                       subTypeProperty = b.subTypeProperty();
-
-                                       for (Class<?> bst : b.subTypes()) {
-                                               Bean b2 = 
bst.getAnnotation(Bean.class);
-                                               String name = null;
-                                               if (! b2.typeName().isEmpty())
-                                                       name = b2.typeName();
-                                               else
-                                                       name = bst.getName();
-                                               subTypes.put(bst, name);
-                                       }
-                               }
-                       }
-               }
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/cebe9211/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java
 
b/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java
new file mode 100644
index 0000000..ef4afa0
--- /dev/null
+++ 
b/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java
@@ -0,0 +1,79 @@
+// 
***************************************************************************************************************************
+// * 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.                                              *
+// 
***************************************************************************************************************************
+package org.apache.juneau.transform;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+
+/**
+ * Bean filter builder initialized from the contents of a {@link Bean @Bean} 
annotation found on a class.
+ * <p>
+ * <b>*** Internal class - Not intended for external use ***</b>
+ *
+ * @author James Bognar ([email protected])
+ */
+public final class AnnotationBeanFilterBuilder extends BeanFilterBuilder {
+
+       /**
+        * Constructor.
+        *
+        * @param annotatedClass The class found to have a {@link Bean @Bean} 
annotation.
+        * @param annotations The {@link Bean @Bean} annotations found on the 
class and all parent classes in child-to-parent order.
+        * @throws Exception Thrown from property namer constructor.
+        */
+       public AnnotationBeanFilterBuilder(Class<?> annotatedClass, List<Bean> 
annotations) throws Exception {
+               super(annotatedClass);
+
+               ListIterator<Bean> li = 
annotations.listIterator(annotations.size());
+               while (li.hasPrevious()) {
+                       Bean b = li.previous();
+
+                       if (b.properties().length > 0)
+                               setProperties(b.properties());
+
+                       if (! b.typeName().isEmpty())
+                               setTypeName(b.typeName());
+
+                       if (b.sort())
+                               setSortProperties(true);
+
+                       if (b.excludeProperties().length > 0)
+                               setExcludeProperties(b.excludeProperties());
+
+                       if (b.propertyNamer() != PropertyNamerDefault.class)
+                               setPropertyNamer(b.propertyNamer());
+
+                       if (b.interfaceClass() != Object.class)
+                               setInterfaceClass(b.interfaceClass());
+
+                       if (b.stopClass() != Object.class)
+                               setStopClass(b.stopClass());
+
+                       if (b.subTypes().length > 0) {
+                               setSubTypeProperty(b.subTypeProperty());
+
+                               for (Class<?> bst : b.subTypes()) {
+                                       Bean b2 = bst.getAnnotation(Bean.class);
+                                       String name = null;
+                                       if (! b2.typeName().isEmpty())
+                                               name = b2.typeName();
+                                       else
+                                               name = bst.getSimpleName();
+                                       addSubType(name, bst);
+                               }
+                       }
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/cebe9211/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 60c3ad9..290dae1 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
@@ -12,8 +12,6 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.transform;
 
-import java.beans.*;
-import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.*;
@@ -29,44 +27,11 @@ import org.apache.juneau.internal.*;
  *     Thus, it can be used to perform the same function as the 
<code>@Bean</code> annotation when you don't have
  *             the ability to annotate those classes (e.g. you don't have 
access to the source code).
  *
- * <p>
- *     When defining bean filters, you can either call the setters in the 
contructor, or override getters.
- *
- * <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>);
- *
- *     Address a = <jk>new</jk> Address();
- *     String json = s.serialize(a); <jc>// Serializes only street, city, 
state.</jc>
- *
- *     <jc>// Filter class defined via setters</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>);
- *             }
- *     }
- *
- *     <jc>// Filter class defined by overriding getters</jc>
- *     <jk>public class</jk> AddressFilter <jk>extends</jk> 
BeanFilter&lt;Address&gt; {
- *             <jk>public</jk> String[] getProperties() {
- *                     <jk>return new</jk> 
String[]{<js>"street"</js>,<js>"city"</js>,<js>"state"</js>};
- *             }
- *     }
- * </p>
- * <p>
- *     The examples in this class use the setters approach.
- *
- * <h6 class='topic'>Additional information</h6>
- *     See {@link org.apache.juneau.transform} for more information.
- *
- *
  * @author James Bognar ([email protected])
- * @param <T> The class type that this filter applies to.
  */
-public abstract class BeanFilter<T> {
+public class BeanFilter {
 
-       private final Class<T> beanClass;
+       private final Class<?> beanClass;
        private final String[] properties, excludeProperties;
        private final Map<Class<?>, String> subTypes;
        private final String subTypeAttr;
@@ -77,197 +42,25 @@ public abstract class BeanFilter<T> {
 
        /**
         * Constructor.
-        *
-        * @param beanClass
-        *      The bean class that this filter applies to.
-        *      If <jk>null</jk>, then the value is inferred through reflection.
-        * @param typeName
-        *      The dictionary name associated with this bean.
-        * @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.
-        * @param subTypeProperty
-        *      Defines a virtual property on a superclass that identifies bean 
subtype classes.
-        *      <p>
-        *      In the following example, the abstract class has two subclasses 
that are differentiated
-        *              by a property called <code>subType</code>
-        *
-        *      <p class='bcode'>
-        *      <jc>// Abstract superclass</jc>
-        *      <jk>public abstract class</jk> A {
-        *              <jk>public</jk> String <jf>f0</jf> = <js>"f0"</js>;
-        *      }
-        *
-        *      <jc>// Subclass 1</jc>
-        *      <jk>public class</jk> A1 <jk>extends</jk> A {
-        *              <jk>public</jk> String <jf>f1</jf>;
-        *      }
-        *
-        *      <jc>// Subclass 2</jc>
-        *      <jk>public class</jk> A2 <jk>extends</jk> A {
-        *              <jk>public</jk> String <jf>f2</jf>;
-        *      }
-        *
-        *      <jc>// Filter for defining subtypes</jc>
-        *      <jk>public class</jk> AFilter <jk>extends</jk> 
BeanFilter&lt;A&gt; {
-        *              <jk>public</jk> AFilter() {
-        *                      <jk>super</jk>(A.<jk>class</jk>, <jk>null</jk>, 
<jk>null</jk>, <jk>null</jk>, <jk>null</jk>, <jk>false</jk>, <jk>null</jk>, 
<jk>null</jk>, <js>"subType"</js>, <jsm>createSubTypes</jsm>())
-        *              }
-        *              <jk>private static</jk> 
Map&lt;Class&lt;?&gt;,String&gt; <jsm>createSubTypes</jsm>() {
-        *                      HashMap&lt;Class&lt;?&gt;,String&gt; m = new 
HashMap&lt;Class&lt;?&gt;,String&gt;();
-        *                      m.put(A1.<jk>class</jk>,<js>"A1"</js>);
-        *                      m.put(A2.<jk>class</jk>,<js>"A2"</js>);
-        *                      <jk>return</jk> m;
-        *              }
-        *      }
-        *      </p>
-        *      <p>
-        *      The following shows what happens when serializing a subclassed 
object to JSON:
-        *      <p class='bcode'>
-        *      JsonSerializer s = <jk>new</jk> 
JsonSerializer().addBeanFilters(AFilter.<jk>class</jk>);
-        *      A1 a1 = <jk>new</jk> A1();
-        *      a1.<jf>f1</jf> = <js>"f1"</js>;
-        *      String r = s.serialize(a1);
-        *      
<jsm>assertEquals</jsm>(<js>"{subType:'A1',f1:'f1',f0:'f0'}"</js>, r);
-        *              </p>
-        *      <p>
-        *      The following shows what happens when parsing back into the 
original object.
-        *      <p class='bcode'>
-        *      JsonParser p = <jk>new</jk> 
JsonParser().addBeanFilters(AFilter.<jk>class</jk>);
-        *      A a = p.parse(r, A.<jk>class</jk>);
-        *      <jsm>assertTrue</jsm>(a <jk>instanceof</jk> A1);
-        *      </p>
-        * @param subTypes
-        */
-       @SuppressWarnings("unchecked")
-       public BeanFilter(Class<T> beanClass, String typeName, String[] 
properties, String[] excludeProperties, Class<?> interfaceClass, Class<?> 
stopClass, boolean sortProperties, PropertyNamer propertyNamer, String 
subTypeProperty, Map<Class<?>,String> subTypes) {
-
-               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)
-                                               beanClass = (Class<T>)nType;
-
-                                       else
-                                               throw new 
RuntimeException("Unsupported parameter type: " + nType);
-                               }
-                       }
-               }
-
-               this.beanClass = beanClass;
-               this.typeName = typeName;
-               this.properties = StringUtils.split(properties, ',');
-               this.excludeProperties = StringUtils.split(excludeProperties, 
',');
-               this.interfaceClass = interfaceClass;
-               this.stopClass = stopClass;
-               this.sortProperties = sortProperties;
-               this.propertyNamer = propertyNamer;
-               this.subTypeAttr = subTypeProperty;
-               this.subTypes = subTypes == null ? null : 
Collections.unmodifiableMap(subTypes);
-       }
-
-       /**
-        * Convenience constructor for defining interface bean filters.
-        *
-        * @param interfaceClass The interface class.
-        */
-       @SuppressWarnings("unchecked")
-       public BeanFilter(Class<?> interfaceClass) {
-               this((Class<T>)interfaceClass, null, null, null, 
interfaceClass, null, false, null, null, null);
-       }
-
-       /**
-        * Convenience constructor for defining a bean filter that simply 
specifies the properties and order of properties for a bean.
-        *
-        * @param properties
-        */
-       public BeanFilter(String...properties) {
-               this(null, null, properties, null, null, null, false, null, 
null, null);
-       }
-
-       /**
-        * Dummy constructor.
         */
-       public BeanFilter() {
-               this((Class<T>)null);
+       BeanFilter(BeanFilterBuilder builder) {
+               this.beanClass = builder.beanClass;
+               this.typeName = builder.typeName;
+               this.properties = StringUtils.split(builder.properties, ',');
+               this.excludeProperties = 
StringUtils.split(builder.excludeProperties, ',');
+               this.interfaceClass = builder.interfaceClass;
+               this.stopClass = builder.stopClass;
+               this.sortProperties = builder.sortProperties;
+               this.propertyNamer = builder.propertyNamer;
+               this.subTypeAttr = builder.subTypeProperty;
+               this.subTypes = builder.subTypes == null ? null : 
Collections.unmodifiableMap(builder.subTypes);
        }
 
        /**
         * Returns the bean class that this filter applies to.
         * @return The bean class that this filter applies to.
         */
-       public Class<T> getBeanClass() {
+       public Class<?> getBeanClass() {
                return beanClass;
        }
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/cebe9211/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java 
b/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java
index 6d96758..522ab6a 100644
--- 
a/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java
+++ 
b/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java
@@ -12,6 +12,291 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.transform;
 
-public class BeanFilterBuilder {
+import java.beans.*;
+import java.util.*;
 
+import org.apache.juneau.*;
+
+/**
+ * Builder class for {@link BeanFilter} objects.
+ * <p>
+ *     Bean filter builders must have a public no-arg constructor.
+ *     Builder settings should be set in the constructor using the provided 
setters on this class.
+ *
+ * <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>);
+ *
+ *     Address a = <jk>new</jk> Address();
+ *     String json = s.serialize(a); <jc>// Serializes only street, city, 
state.</jc>
+ *
+ *     <jc>// Filter class defined via setters</jc>
+ *     <jk>public class</jk> AddressFilter <jk>extends</jk> BeanFilterBuilder {
+ *             <jk>public</jk> AddressFilter() {
+ *                     super(Address.<jk>class</jk>);
+ *                     
setProperties(<js>"street"</js>,<js>"city"</js>,<js>"state"</js>);
+ *             }
+ *     }
+ * </p>
+ *
+ * <h6 class='topic'>Additional information</h6>
+ *     See {@link org.apache.juneau.transform} for more information.
+ *
+ * @author james.bognar
+ */
+public abstract class BeanFilterBuilder {
+
+       Class<?> beanClass;
+       String typeName;
+       String[] properties, excludeProperties;
+       Class<?> interfaceClass, stopClass;
+       boolean sortProperties;
+       PropertyNamer propertyNamer;
+       String subTypeProperty;
+       Map<Class<?>,String> subTypes;
+
+       /**
+        * Constructor.
+        *
+        * @param beanClass The bean class that this filter applies to.
+        */
+       public BeanFilterBuilder(Class<?> beanClass) {
+               this.beanClass = beanClass;
+       }
+
+       /**
+        * Specifies the type name for this bean.
+        *
+        * @param typeName The dictionary name associated with this bean.
+        * @return This object (for method chaining).
+        */
+       public BeanFilterBuilder setTypeName(String typeName) {
+               this.typeName = typeName;
+               return this;
+       }
+
+       /**
+        * Specifies the set and order of names of properties associated with 
the 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 properties The properties associated with the bean class.
+        * @return This object (for method chaining).
+        */
+       public BeanFilterBuilder setProperties(String...properties) {
+               this.properties = properties;
+               return this;
+       }
+
+       /**
+        * Specifies the list of properties to ignore on a bean.
+        *
+        * @param excludeProperties The list of properties to ignore on a bean.
+        * @return This object (for method chaining).
+        */
+       public BeanFilterBuilder 
setExcludeProperties(String...excludeProperties) {
+               this.excludeProperties = excludeProperties;
+               return this;
+       }
+
+       /**
+        * 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> 
BeanFilterBuilder {
+        *              <jk>public</jk> AFilter() {
+        *                      super(A.<jk>class</jk>);
+        *                      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 interfaceClass The interface class to use for this bean class.
+        * @return This object (for method chaining).
+        */
+       public BeanFilterBuilder setInterfaceClass(Class<?> interfaceClass) {
+               this.interfaceClass = interfaceClass;
+               return this;
+       }
+
+       /**
+        * 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 stopClass
+        * @return This object (for method chaining).
+        */
+       public BeanFilterBuilder setStopClass(Class<?> stopClass) {
+               this.stopClass = stopClass;
+               return this;
+       }
+
+       /**
+        * Sort properties in alphabetical order.
+        *
+        * @param sortProperties
+        * @return This object (for method chaining).
+        */
+       public BeanFilterBuilder setSortProperties(boolean sortProperties) {
+               this.sortProperties = sortProperties;
+               return this;
+       }
+
+       /**
+        * The property namer to use to name bean properties.
+        *
+        * @param propertyNamer The property namer instance.
+        * @return This object (for method chaining).
+        */
+       public BeanFilterBuilder setPropertyNamer(PropertyNamer propertyNamer) {
+               this.propertyNamer = propertyNamer;
+               return this;
+       }
+
+       /**
+        * The property namer to use to name bean properties.
+        *
+        * @param c The property namer class.  Must have a public no-arg 
constructor.
+        * @return This object (for method chaining).
+        * @throws Exception Thrown from constructor method.
+        */
+       public BeanFilterBuilder setPropertyNamer(Class<? extends 
PropertyNamer> c) throws Exception {
+               this.propertyNamer = c.newInstance();
+               return this;
+       }
+
+       /**
+        * Defines a virtual property on a superclass that identifies bean 
subtype classes.
+        * <p>
+        * In the following example, the abstract class has two subclasses that 
are differentiated
+        *      by a property called <code>subType</code>
+        *
+        * <p class='bcode'>
+        *      <jc>// Abstract superclass</jc>
+        *      <jk>public abstract class</jk> A {
+        *              <jk>public</jk> String <jf>f0</jf> = <js>"f0"</js>;
+        *      }
+        *
+        *      <jc>// Subclass 1</jc>
+        *      <jk>public class</jk> A1 <jk>extends</jk> A {
+        *              <jk>public</jk> String <jf>f1</jf>;
+        *      }
+        *
+        *      <jc>// Subclass 2</jc>
+        *      <jk>public class</jk> A2 <jk>extends</jk> A {
+        *              <jk>public</jk> String <jf>f2</jf>;
+        *      }
+        *
+        *      <jc>// Filter for defining subtypes</jc>
+        *      <jk>public class</jk> AFilter <jk>extends</jk> 
BeanFilterBuilder {
+        *              <jk>public</jk> AFilter() {
+        *                      super(A.<jk>class</jk>);
+        *                      setSubTypeProperty(<js>"subType"</js>);
+        *                              addSubType("A1", A1.<jk>class</jk>);
+        *                              addSubType("A2", A2.<jk>class</jk>);
+        *              }
+        *      }
+        * </p>
+        * <p>
+        * The following shows what happens when serializing a subclassed 
object to JSON:
+        * <p class='bcode'>
+        *      JsonSerializer s = <jk>new</jk> 
JsonSerializer().addBeanFilters(AFilter.<jk>class</jk>);
+        *      A1 a1 = <jk>new</jk> A1();
+        *      a1.<jf>f1</jf> = <js>"f1"</js>;
+        *      String r = s.serialize(a1);
+        *      
<jsm>assertEquals</jsm>(<js>"{subType:'A1',f1:'f1',f0:'f0'}"</js>, r);
+        *      </p>
+        * <p>
+        * The following shows what happens when parsing back into the original 
object.
+        * <p class='bcode'>
+        *      JsonParser p = <jk>new</jk> 
JsonParser().addBeanFilters(AFilter.<jk>class</jk>);
+        *      A a = p.parse(r, A.<jk>class</jk>);
+        *      <jsm>assertTrue</jsm>(a <jk>instanceof</jk> A1);
+        * </p>
+        *
+        * @param subTypeProperty The name of the subtype property for this 
bean.
+        *      Default is <js>"_subtype"</js>.
+        * @return This object (for method chaining).
+        */
+       public BeanFilterBuilder setSubTypeProperty(String subTypeProperty) {
+               this.subTypeProperty = subTypeProperty;
+               return this;
+       }
+
+       /**
+        * Specifies the subtype mappings for this bean class.
+        * See {@link #setSubTypeProperty(String)}.
+        *
+        * @param subTypes The mappings of subtype classes to subtype names.
+        * @return This object (for method chaining).
+        */
+       public BeanFilterBuilder setSubTypes(Map<Class<?>,String> subTypes) {
+               this.subTypes = subTypes;
+               return this;
+       }
+
+       /**
+        * Adds an entry to the subtype mappings for this bean class.
+        * See {@link #setSubTypeProperty(String)}.
+        *
+        * @param name The subtype name.
+        * @param c The subtype class.
+        * @return This object (for method chaining).
+        */
+       public BeanFilterBuilder addSubType(String name, Class<?> c) {
+               if (subTypes == null)
+                       subTypes = new LinkedHashMap<Class<?>,String>();
+               subTypes.put(c, name);
+               return this;
+       }
+
+       /**
+        * Creates a {@link BeanFilter} with settings in this builder class.
+        *
+        * @return A new {@link BeanFilter} instance.
+        */
+       public BeanFilter build() {
+               return new BeanFilter(this);
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/cebe9211/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
deleted file mode 100644
index 6201139..0000000
--- 
a/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilter.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// 
***************************************************************************************************************************
-// * 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.                                              *
-// 
***************************************************************************************************************************
-package org.apache.juneau.transform;
-
-import org.apache.juneau.*;
-
-/**
- * Simple bean filter that simply identifies a class to be used as an interface
- *     class for all child classes.
- * <p>
- *     These objects are created when you pass in non-<code>BeanFilter</code> 
classes to {@link ContextFactory#addToProperty(String,Object)},
- *             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 ([email protected])
- * @param <T> The class type that this bean filter applies to.
- */
-public class InterfaceBeanFilter<T> extends BeanFilter<T> {
-
-       /**
-        * Constructor.
-        *
-        * @param interfaceClass The class to use as an interface on all child 
classes.
-        */
-       public InterfaceBeanFilter(Class<T> interfaceClass) {
-               super(interfaceClass);
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/cebe9211/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java
----------------------------------------------------------------------
diff --git 
a/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java
 
b/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java
new file mode 100644
index 0000000..d40c358
--- /dev/null
+++ 
b/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java
@@ -0,0 +1,37 @@
+// 
***************************************************************************************************************************
+// * 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.                                              *
+// 
***************************************************************************************************************************
+package org.apache.juneau.transform;
+
+import org.apache.juneau.*;
+
+/**
+ * Simple bean filter that simply identifies a class to be used as an interface
+ *     class for all child classes.
+ * <p>
+ *     These objects are created when you pass in 
non-<code>BeanFilterBuilder</code> classes to {@link 
ContextFactory#addToProperty(String,Object)},
+ *             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 ([email protected])
+ */
+public class InterfaceBeanFilterBuilder extends BeanFilterBuilder {
+
+       /**
+        * Constructor.
+        *
+        * @param interfaceClass The class to use as an interface on all child 
classes.
+        */
+       public InterfaceBeanFilterBuilder(Class<?> interfaceClass) {
+               super(interfaceClass);
+               setInterfaceClass(interfaceClass);
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/cebe9211/juneau-core/src/test/java/org/apache/juneau/BeanConfigTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/test/java/org/apache/juneau/BeanConfigTest.java 
b/juneau-core/src/test/java/org/apache/juneau/BeanConfigTest.java
index b671cc9..797cbd7 100755
--- a/juneau-core/src/test/java/org/apache/juneau/BeanConfigTest.java
+++ b/juneau-core/src/test/java/org/apache/juneau/BeanConfigTest.java
@@ -754,9 +754,21 @@ public class BeanConfigTest {
        public static class DummyPojoSwapA extends PojoSwap<A,ObjectMap> {}
        public static class DummyPojoSwapB extends PojoSwap<B,ObjectMap> {}
        public static class DummyPojoSwapC extends PojoSwap<C,ObjectMap> {}
-       public static class DummyBeanFilterA extends BeanFilter<A> {}
-       public static class DummyBeanFilterB extends BeanFilter<B> {}
-       public static class DummyBeanFilterC extends BeanFilter<C> {}
+       public static class DummyBeanFilterA extends BeanFilterBuilder {
+               public DummyBeanFilterA() {
+                       super(A.class);
+               }
+       }
+       public static class DummyBeanFilterB extends BeanFilterBuilder {
+               public DummyBeanFilterB() {
+                       super(B.class);
+               }
+       }
+       public static class DummyBeanFilterC extends BeanFilterBuilder {
+               public DummyBeanFilterC() {
+                       super(C.class);
+               }
+       }
        public static class C {}
 
        private void assertSameCache(Parser p1, Parser p2) {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/cebe9211/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 3934921..a369db9 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
@@ -355,17 +355,13 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
                }
        }
 
-       public static class CFilter extends BeanFilter<C> {
+       public static class CFilter extends BeanFilterBuilder {
                public CFilter() {
-                       super(C.class, null, null, null, null, null, false, 
null, "subType", createSubTypes());
-               }
-
-               private static Map<Class<?>,String> createSubTypes() {
-                       HashMap<Class<?>,String> m = new 
HashMap<Class<?>,String>();
-                       m.put(C1.class,"C1");
-                       m.put(C2.class,"C2");
-                       m.put(C3.class,"C3");
-                       return m;
+                       super(C.class);
+                       setSubTypeProperty("subType");
+                       addSubType("C1", C1.class);
+                       addSubType("C2", C2.class);
+                       addSubType("C3", C3.class);
                }
        }
 
@@ -456,11 +452,12 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
                public String f2;
        }
 
-       public static class CAFilter extends BeanFilter<CA> {
+       public static class CAFilter extends BeanFilterBuilder {
                public CAFilter() {
-                       super(CA.class, null, null, null, null, null, false, 
null, "subType",
-                               new 
HashMap<Class<?>,String>(){{put(CA1.class,"CA1");put(CA2.class,"CA2");}}
-                       );
+                       super(CA.class);
+                       setSubTypeProperty("subType");
+                       addSubType("CA1", CA1.class);
+                       addSubType("CA2", CA2.class);
                }
        }
 
@@ -524,9 +521,10 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
                        return this;
                }
        }
-       public static class D2Filter extends BeanFilter<D2> {
+       public static class D2Filter extends BeanFilterBuilder {
                public D2Filter() {
-                       super("f3","f2");
+                       super(D2.class);
+                       setProperties("f3,f2");
                }
        }
 
@@ -586,9 +584,10 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
                        return this;
                }
        }
-       public static class E2Filter extends BeanFilter<E2> {
+       public static class E2Filter extends BeanFilterBuilder {
                public E2Filter() {
-                       super(null, null, null, new String[]{"f2"}, null, null, 
false, null, null, null);
+                       super(E2.class);
+                       setExcludeProperties("f2");
                }
        }
 
@@ -678,12 +677,12 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
                        return this;
                }
        }
-       public static class FB1Filter extends BeanFilter<FB1> {
+       public static class FB1Filter extends InterfaceBeanFilterBuilder {
                public FB1Filter() {
                        super(FB1.class);
                }
        }
-       public static class FB2Filter extends BeanFilter<FB2> {
+       public static class FB2Filter extends InterfaceBeanFilterBuilder {
                public FB2Filter() {
                        super(FB1.class);
                }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/cebe9211/juneau-server/src/main/java/org/apache/juneau/server/annotation/RestResource.java
----------------------------------------------------------------------
diff --git 
a/juneau-server/src/main/java/org/apache/juneau/server/annotation/RestResource.java
 
b/juneau-server/src/main/java/org/apache/juneau/server/annotation/RestResource.java
index b245b85..0279d9b 100755
--- 
a/juneau-server/src/main/java/org/apache/juneau/server/annotation/RestResource.java
+++ 
b/juneau-server/src/main/java/org/apache/juneau/server/annotation/RestResource.java
@@ -98,8 +98,8 @@ public @interface RestResource {
         *      <li>{@link RestServlet#getParsers()}
         * </ul>
         * <p>
-        * If the specified class is an instance of {@link BeanFilter}, then 
that filter is added.
-        * Any other classes are wrapped in a {@link InterfaceBeanFilter} to 
indicate that subclasses should
+        * If the specified class is an instance of {@link BeanFilterBuilder}, 
then a filter built from that builder is added.
+        * Any other classes are wrapped in a {@link 
InterfaceBeanFilterBuilder} to indicate that subclasses should
         *      be treated as the specified class type.
         */
        Class<?>[] beanFilters() default {};

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/cebe9211/juneau-server/src/main/java/org/apache/juneau/server/jaxrs/JuneauProvider.java
----------------------------------------------------------------------
diff --git 
a/juneau-server/src/main/java/org/apache/juneau/server/jaxrs/JuneauProvider.java
 
b/juneau-server/src/main/java/org/apache/juneau/server/jaxrs/JuneauProvider.java
index e2f0924..3e48886 100755
--- 
a/juneau-server/src/main/java/org/apache/juneau/server/jaxrs/JuneauProvider.java
+++ 
b/juneau-server/src/main/java/org/apache/juneau/server/jaxrs/JuneauProvider.java
@@ -47,8 +47,8 @@ public @interface JuneauProvider {
         * <p>
         *      These filters are applied to all serializers and parsers being 
used by the provider.
         * <p>
-        *      If the specified class is an instance of {@link BeanFilter}, 
then that filter is added.
-        *      Any other classes are wrapped in a {@link InterfaceBeanFilter} 
to indicate that subclasses should
+        *      If the specified class is an instance of {@link 
BeanFilterBuilder}, then a filter built from that builder is added.
+        *      Any other classes are wrapped in a {@link 
InterfaceBeanFilterBuilder} to indicate that subclasses should
         *              be treated as the specified class type.
         */
        Class<?>[] beanFilters() default {};

Reply via email to