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<Class></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<Address> { - * <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<Address> { - * <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<A> { - * <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<A> { - * <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<Class<?>,String> <jsm>createSubTypes</jsm>() { - * HashMap<Class<?>,String> m = new HashMap<Class<?>,String>(); - * 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 {};
