Repository: incubator-juneau Updated Branches: refs/heads/master 5818e25b6 -> 58781bee5
Convert BeanPropertyMeta to use Builder and final fields. Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/58781bee Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/58781bee Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/58781bee Branch: refs/heads/master Commit: 58781bee5184086063843e5ce5b438e1d28f157c Parents: 5818e25 Author: JamesBognar <[email protected]> Authored: Thu Feb 9 18:47:52 2017 -0500 Committer: JamesBognar <[email protected]> Committed: Thu Feb 9 18:47:52 2017 -0500 ---------------------------------------------------------------------- .../main/java/org/apache/juneau/BeanMeta.java | 95 ++--- .../org/apache/juneau/BeanPropertyMeta.java | 360 +++++++++++-------- .../apache/juneau/internal/DelegateBeanMap.java | 15 +- 3 files changed, 257 insertions(+), 213 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/58781bee/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 42425ee..40f1346 100644 --- a/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java +++ b/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java @@ -111,17 +111,17 @@ public class BeanMeta<T> { this.notABeanReason = b.init(this); this.beanFilter = beanFilter; - this.dictionaryName = (beanFilter == null ? null : beanFilter.getTypeName()); - this.properties = b.properties; + this.dictionaryName = beanFilter == null ? null : beanFilter.getTypeName(); + this.properties = b.properties == null ? null : Collections.unmodifiableMap(b.properties); this.getterProps = Collections.unmodifiableMap(b.getterProps); this.setterProps = Collections.unmodifiableMap(b.setterProps); - this.typeVarImpls = b.typeVarImpls; + this.typeVarImpls = b.typeVarImpls == null ? null : Collections.unmodifiableMap(b.typeVarImpls); this.constructor = b.constructor; this.constructorArgs = b.constructorArgs; this.extMeta = b.extMeta; - this.subTypeProperty = b.subTypeIdProperty; + this.subTypeProperty = b.subTypeIdProperty == null ? null : b.subTypeIdProperty.build(); this.beanRegistry = b.beanRegistry; - this.typeProperty = new BeanPropertyMeta(this, ctx.getBeanTypePropertyName(), ctx.string(), beanRegistry); + this.typeProperty = new BeanPropertyMeta.Builder(this, ctx.getBeanTypePropertyName(), ctx.string(), beanRegistry).build(); } private static final class Builder<T> { @@ -136,7 +136,7 @@ public class BeanMeta<T> { Constructor<T> constructor; String[] constructorArgs = new String[0]; MetadataMap extMeta = new MetadataMap(); - BeanPropertyMeta subTypeIdProperty; + BeanPropertyMeta.Builder subTypeIdProperty; PropertyNamer propertyNamer; BeanRegistry beanRegistry; @@ -175,7 +175,7 @@ public class BeanMeta<T> { if (stopClass == null) stopClass = Object.class; - Map<String,BeanPropertyMeta> normalProps = new LinkedHashMap<String,BeanPropertyMeta>(); + Map<String,BeanPropertyMeta.Builder> normalProps = new LinkedHashMap<String,BeanPropertyMeta.Builder>(); /// See if this class matches one the patterns in the exclude-class list. if (ctx.isNotABean(c)) @@ -238,7 +238,7 @@ public class BeanMeta<T> { // First populate the properties with those specified in the bean annotation to // ensure that ordering first. for (String name : fixedBeanProps) - normalProps.put(name, new BeanPropertyMeta(beanMeta, name)); + normalProps.put(name, new BeanPropertyMeta.Builder(beanMeta, name)); if (ctx.useJavaBeanIntrospector) { BeanInfo bi = null; @@ -250,7 +250,7 @@ public class BeanMeta<T> { for (PropertyDescriptor pd : bi.getPropertyDescriptors()) { String name = pd.getName(); if (! normalProps.containsKey(name)) - normalProps.put(name, new BeanPropertyMeta(beanMeta, name)); + normalProps.put(name, new BeanPropertyMeta.Builder(beanMeta, name)); normalProps.get(name).setGetter(pd.getReadMethod()).setSetter(pd.getWriteMethod()); } } @@ -261,7 +261,7 @@ public class BeanMeta<T> { String name = findPropertyName(f, fixedBeanProps); if (name != null) { if (! normalProps.containsKey(name)) - normalProps.put(name, new BeanPropertyMeta(beanMeta, name)); + normalProps.put(name, new BeanPropertyMeta.Builder(beanMeta, name)); normalProps.get(name).setField(f); } } @@ -273,8 +273,8 @@ public class BeanMeta<T> { String pn = bm.propertyName; Method m = bm.method; if (! normalProps.containsKey(pn)) - normalProps.put(pn, new BeanPropertyMeta(beanMeta, pn)); - BeanPropertyMeta bpm = normalProps.get(pn); + normalProps.put(pn, new BeanPropertyMeta.Builder(beanMeta, pn)); + BeanPropertyMeta.Builder bpm = normalProps.get(pn); if (! bm.isSetter) bpm.setGetter(m); } @@ -282,7 +282,7 @@ public class BeanMeta<T> { // Now iterate through all the setters. for (BeanMethod bm : bms) { if (bm.isSetter) { - BeanPropertyMeta bpm = normalProps.get(bm.propertyName); + BeanPropertyMeta.Builder bpm = normalProps.get(bm.propertyName); if (bm.matchesPropertyType(bpm)) bpm.setSetter(bm.method); } @@ -295,16 +295,16 @@ public class BeanMeta<T> { typeVarImpls = null; // Eliminate invalid properties, and set the contents of getterProps and setterProps. - for (Iterator<BeanPropertyMeta> i = normalProps.values().iterator(); i.hasNext();) { - BeanPropertyMeta p = i.next(); + for (Iterator<BeanPropertyMeta.Builder> i = normalProps.values().iterator(); i.hasNext();) { + BeanPropertyMeta.Builder p = i.next(); try { if (p.validate(ctx, beanRegistry, typeVarImpls)) { - if (p.getGetter() != null) - getterProps.put(p.getGetter(), p.getName()); + if (p.getter != null) + getterProps.put(p.getter, p.name); - if (p.getSetter() != null) - setterProps.put(p.getSetter(), p.getName()); + if (p.setter != null) + setterProps.put(p.setter, p.name); } else { i.remove(); @@ -321,7 +321,7 @@ public class BeanMeta<T> { // Mark constructor arg properties. for (String fp : constructorArgs) { - BeanPropertyMeta m = normalProps.get(fp); + BeanPropertyMeta.Builder m = normalProps.get(fp); if (m == null) throw new BeanRuntimeException(c, "The property ''{0}'' was defined on the @BeanConstructor(properties=X) annotation but was not found on the class definition.", fp); m.setAsConstructorArg(); @@ -337,11 +337,13 @@ public class BeanMeta<T> { if (beanFilter != null && beanFilter.getSubTypeProperty() != null) { String subTypeProperty = beanFilter.getSubTypeProperty(); - this.subTypeIdProperty = new SubTypePropertyMeta(beanMeta, subTypeProperty, beanFilter.getSubTypes(), normalProps.remove(subTypeProperty), beanRegistry); - properties.put(subTypeProperty, this.subTypeIdProperty); + BeanPropertyMeta.Builder stp = normalProps.remove(subTypeProperty); + this.subTypeIdProperty = new SubTypePropertyMeta.Builder(beanMeta, subTypeProperty, beanFilter.getSubTypes(), stp == null ? null : stp.build(), beanRegistry); + properties.put(subTypeProperty, this.subTypeIdProperty.build()); } - properties.putAll(normalProps); + for (Map.Entry<String,BeanPropertyMeta.Builder> e : normalProps.entrySet()) + properties.put(e.getKey(), e.getValue().build()); // If a beanFilter is defined, look for inclusion and exclusion lists. if (beanFilter != null) { @@ -374,9 +376,6 @@ public class BeanMeta<T> { properties = properties2; } - // We return this through the Bean.keySet() interface, so make sure it's not modifiable. - properties = Collections.unmodifiableMap(properties); - } catch (BeanRuntimeException e) { throw e; } catch (Exception e) { @@ -480,16 +479,16 @@ public class BeanMeta<T> { * Returns true if this method matches the class type of the specified property. * Only meant to be used for setters. */ - boolean matchesPropertyType(BeanPropertyMeta b) { + boolean matchesPropertyType(BeanPropertyMeta.Builder b) { if (b == null) return false; // Get the bean property type from the getter/field. Class<?> pt = null; - if (b.getGetter() != null) - pt = b.getGetter().getReturnType(); - else if (b.getField() != null) - pt = b.getField().getType(); + if (b.getter != null) + pt = b.getter.getReturnType(); + else if (b.field != null) + pt = b.field.getType(); // Doesn't match if no getter/field defined. if (pt == null) @@ -501,10 +500,10 @@ public class BeanMeta<T> { // If a setter was previously set, only use this setter if it's a closer // match (e.g. prev type is a superclass of this type). - if (b.getSetter() == null) + if (b.setter == null) return true; - Class<?> prevType = b.getSetter().getParameterTypes()[0]; + Class<?> prevType = b.setter.getParameterTypes()[0]; return isParentClass(prevType, type, true); } @@ -745,15 +744,29 @@ public class BeanMeta<T> { @SuppressWarnings({"rawtypes","unchecked"}) private static class SubTypePropertyMeta extends BeanPropertyMeta { - private Map<Class<?>,String> subTypes; - private BeanPropertyMeta realProperty; // Bean property if bean actually has a real subtype field. - private BeanMeta<?> beanMeta; + private final Map<Class<?>,String> subTypes; + private final BeanPropertyMeta realProperty; // Bean property if bean actually has a real subtype field. + + static class Builder extends BeanPropertyMeta.Builder { + Map<Class<?>,String> subTypes; + BeanPropertyMeta realProperty; + + Builder(BeanMeta beanMeta, String subTypeAttr, Map<Class<?>,String> subTypes, BeanPropertyMeta realProperty, BeanRegistry beanRegistry) { + super(beanMeta, subTypeAttr, beanMeta.ctx.string(), beanRegistry); + this.subTypes = subTypes; + this.realProperty = realProperty; + } + + @Override + public SubTypePropertyMeta build() { + return new SubTypePropertyMeta(this); + } + } - SubTypePropertyMeta(BeanMeta beanMeta, String subTypeAttr, Map<Class<?>,String> subTypes, BeanPropertyMeta realProperty, BeanRegistry beanRegistry) { - super(beanMeta, subTypeAttr, beanMeta.ctx.string(), beanRegistry); - this.subTypes = subTypes; - this.realProperty = realProperty; - this.beanMeta = beanMeta; + SubTypePropertyMeta(Builder b) { + super(b); + this.subTypes = b.subTypes; + this.realProperty = b.realProperty; } /* http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/58781bee/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java b/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java index 33a163a..516d3d4 100644 --- a/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java +++ b/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java @@ -42,45 +42,211 @@ import org.apache.juneau.utils.*; @SuppressWarnings({ "rawtypes", "unchecked" }) public class BeanPropertyMeta { - private Field field; - private Method getter, setter; - private boolean isConstructorArg, isUri; + final BeanMeta<?> beanMeta; // The bean that this property belongs to. + private final BeanContext beanContext; // The context that created this meta. - private final BeanMeta<?> beanMeta; - private final BeanContext beanContext; + private final String name; // The name of the property. + private final Field field; // The bean property field (if it has one). + private final Method getter, setter; // The bean property getter and setter. + private final boolean isUri; // True if this is a URL/URI or annotated with @URI. - private String name; - private ClassMeta<?> - rawTypeMeta, // The real class type of the bean property. - typeMeta; // The transformed class type of the bean property. - private String[] properties; - private PojoSwap swap; // PojoSwap defined only via @BeanProperty annotation. + private final ClassMeta<?> + rawTypeMeta, // The real class type of the bean property. + typeMeta; // The transformed class type of the bean property. - private MetadataMap extMeta = new MetadataMap(); // Extended metadata - BeanRegistry beanRegistry; + private final String[] properties; // The value of the @BeanProperty(properties) annotation. + private final PojoSwap swap; // PojoSwap defined only via @BeanProperty annotation. + + private final MetadataMap extMeta = new MetadataMap(); // Extended metadata + private final BeanRegistry beanRegistry; + + private final Object overrideValue; // The bean property value (if it's an overridden delegate). + private final BeanPropertyMeta delegateFor; // The bean property that this meta is a delegate for. /** - * Constructor. - * - * @param beanMeta The metadata of the bean containing this property. - * @param name This property name. + * BeanPropertyMeta builder class. */ - protected BeanPropertyMeta(BeanMeta<?> beanMeta, String name) { - this.beanMeta = beanMeta; - this.beanContext = beanMeta.ctx; - this.name = name; - } + public static class Builder { + private BeanMeta<?> beanMeta; + private BeanContext beanContext; + String name; + Field field; + Method getter, setter; + private boolean isConstructorArg, isUri; + private ClassMeta<?> rawTypeMeta, typeMeta; + private String[] properties; + private PojoSwap swap; + private BeanRegistry beanRegistry; + private Object overrideValue; + private BeanPropertyMeta delegateFor; + + Builder(BeanMeta<?> beanMeta, String name) { + this.beanMeta = beanMeta; + this.beanContext = beanMeta.ctx; + this.name = name; + } + + Builder(BeanMeta<?> beanMeta, String name, ClassMeta<?> rawTypeMeta, BeanRegistry beanRegistry) { + this(beanMeta, name); + this.rawTypeMeta = rawTypeMeta; + if (rawTypeMeta == null) + throw new RuntimeException("xxx"); + this.typeMeta = rawTypeMeta; + this.beanRegistry = beanRegistry; + } + + /** + * BeanPropertyMeta builder for delegate classes. + * + * @param beanMeta The Bean that this property belongs to. + * @param name The property name. + * @param overrideValue The overridden value of this bean property. + * @param delegateFor The original bean property that this one is overriding. + */ + public Builder(BeanMeta<?> beanMeta, String name, Object overrideValue, BeanPropertyMeta delegateFor) { + this(beanMeta, name); + this.delegateFor = delegateFor; + this.overrideValue = overrideValue; + } + + boolean validate(BeanContext f, BeanRegistry parentBeanRegistry, Map<Class<?>,Class<?>[]> typeVarImpls) throws Exception { + + List<Class<?>> bdClasses = new ArrayList<Class<?>>(); + + if (field == null && getter == null) + return false; + + if (field == null && setter == null && f.beansRequireSettersForGetters && ! isConstructorArg) + return false; + + if (field != null) { + BeanProperty p = field.getAnnotation(BeanProperty.class); + rawTypeMeta = f.resolveClassMeta(p, field.getGenericType(), typeVarImpls); + isUri |= (rawTypeMeta.isUri() || field.isAnnotationPresent(org.apache.juneau.annotation.URI.class)); + if (p != null) { + swap = getPropertyPojoSwap(p); + if (! p.properties().isEmpty()) + properties = StringUtils.split(p.properties(), ','); + bdClasses.addAll(Arrays.asList(p.beanDictionary())); + } + } + + if (getter != null) { + BeanProperty p = getter.getAnnotation(BeanProperty.class); + if (rawTypeMeta == null) + rawTypeMeta = f.resolveClassMeta(p, getter.getGenericReturnType(), typeVarImpls); + isUri |= (rawTypeMeta.isUri() || getter.isAnnotationPresent(org.apache.juneau.annotation.URI.class)); + if (p != null) { + if (swap == null) + swap = getPropertyPojoSwap(p); + if (properties != null && ! p.properties().isEmpty()) + properties = StringUtils.split(p.properties(), ','); + bdClasses.addAll(Arrays.asList(p.beanDictionary())); + } + } + + if (setter != null) { + BeanProperty p = setter.getAnnotation(BeanProperty.class); + if (rawTypeMeta == null) + rawTypeMeta = f.resolveClassMeta(p, setter.getGenericParameterTypes()[0], typeVarImpls); + isUri |= (rawTypeMeta.isUri() || setter.isAnnotationPresent(org.apache.juneau.annotation.URI.class)); + if (p != null) { + if (swap == null) + swap = getPropertyPojoSwap(p); + if (properties != null && ! p.properties().isEmpty()) + properties = StringUtils.split(p.properties(), ','); + bdClasses.addAll(Arrays.asList(p.beanDictionary())); + } + } + + if (rawTypeMeta == null) + return false; + + this.beanRegistry = new BeanRegistry(beanContext, parentBeanRegistry, bdClasses.toArray(new Class<?>[0])); + + // Do some annotation validation. + Class<?> c = rawTypeMeta.getInnerClass(); + if (getter != null && ! isParentClass(getter.getReturnType(), c)) + return false; + if (setter != null && ! isParentClass(setter.getParameterTypes()[0], c)) + return false; + if (field != null && ! isParentClass(field.getType(), c)) + return false; + + if (typeMeta == null) + typeMeta = (swap != null ? swap.getSwapClassMeta(beanContext) : rawTypeMeta == null ? beanContext.object() : rawTypeMeta.getSerializedClassMeta()); + if (typeMeta == null) + typeMeta = rawTypeMeta; + + return true; + } + + /** + * @return A new BeanPropertyMeta object using this builder. + */ + public BeanPropertyMeta build() { + return new BeanPropertyMeta(this); + } + + private PojoSwap getPropertyPojoSwap(BeanProperty p) throws Exception { + Class<?> c = p.swap(); + if (c == Null.class) + return null; + try { + if (ClassUtils.isParentClass(PojoSwap.class, c)) { + return (PojoSwap)c.newInstance(); + } + throw new RuntimeException("TODO - Surrogate swaps not yet supported."); + } catch (Exception e) { + throw new BeanRuntimeException(this.beanMeta.c, "Could not instantiate PojoSwap ''{0}'' for bean property ''{1}''", c.getName(), this.name).initCause(e); + } + } + + BeanPropertyMeta.Builder setGetter(Method getter) { + setAccessible(getter); + this.getter = getter; + return this; + } + + BeanPropertyMeta.Builder setSetter(Method setter) { + setAccessible(setter); + this.setter = setter; + return this; + } + + BeanPropertyMeta.Builder setField(Field field) { + setAccessible(field); + this.field = field; + return this; + } + + BeanPropertyMeta.Builder setAsConstructorArg() { + this.isConstructorArg = true; + return this; + } - BeanPropertyMeta(BeanMeta<?> beanMeta, String name, ClassMeta<?> rawTypeMeta, BeanRegistry beanRegistry) { - this(beanMeta, name); - this.rawTypeMeta = rawTypeMeta; - this.beanRegistry = beanRegistry; } - BeanPropertyMeta(BeanMeta<?> beanMeta, String name, Method getter, Method setter) { - this(beanMeta, name); - setGetter(getter); - setSetter(setter); + /** + * Creates a new BeanPropertyMeta using the contents of the specified builder. + * + * @param b The builder to copy fields from. + */ + protected BeanPropertyMeta(BeanPropertyMeta.Builder b) { + this.field = b.field; + this.getter = b.getter; + this.setter = b.setter; + this.isUri = b.isUri; + this.beanMeta = b.beanMeta; + this.beanContext = b.beanContext; + this.name = b.name; + this.rawTypeMeta = b.rawTypeMeta; + this.typeMeta = b.typeMeta; + this.properties = b.properties; + this.swap = b.swap; + this.beanRegistry = b.beanRegistry; + this.overrideValue = b.overrideValue; + this.delegateFor = b.delegateFor; } /** @@ -139,8 +305,6 @@ public class BeanPropertyMeta { * @return The {@link ClassMeta} of the class of this property. */ public ClassMeta<?> getClassMeta() { - if (typeMeta == null) - typeMeta = (swap != null ? swap.getSwapClassMeta(beanContext) : rawTypeMeta == null ? beanContext.object() : rawTypeMeta.getSerializedClassMeta()); return typeMeta; } @@ -158,52 +322,6 @@ public class BeanPropertyMeta { } /** - * Sets the getter method for this property. - * - * @param getter The getter method to associate with this property. - * @return This object (for method chaining). - */ - BeanPropertyMeta setGetter(Method getter) { - setAccessible(getter); - this.getter = getter; - return this; - } - - /** - * Sets the setter method for this property. - * - * @param setter The setter method to associate with this property. - * @return This object (for method chaining). - */ - BeanPropertyMeta setSetter(Method setter) { - setAccessible(setter); - this.setter = setter; - return this; - } - - /** - * Sets the field for this property. - * - * @param field The field to associate with this property. - * @return This object (for method chaining). - */ - BeanPropertyMeta setField(Field field) { - setAccessible(field); - this.field = field; - return this; - } - - /** - * Marks this property as only settable through a constructor arg. - * - * @return This object (for method chaining). - */ - BeanPropertyMeta setAsConstructorArg() { - this.isConstructorArg = true; - return this; - } - - /** * Returns <jk>true</jk> if this bean property is a URI. * <p> * A bean property can be considered a URI if any of the following are true: @@ -236,90 +354,11 @@ public class BeanPropertyMeta { * @return Extended metadata on this bean property. Never <jk>null</jk>. */ public <M extends BeanPropertyMetaExtended> M getExtendedMeta(Class<M> c) { + if (delegateFor != null) + return delegateFor.getExtendedMeta(c); return extMeta.get(c, this); } - boolean validate(BeanContext f, BeanRegistry parentBeanRegistry, Map<Class<?>,Class<?>[]> typeVarImpls) throws Exception { - - List<Class<?>> bdClasses = new ArrayList<Class<?>>(); - - if (field == null && getter == null) - return false; - - if (field == null && setter == null && f.beansRequireSettersForGetters && ! isConstructorArg) - return false; - - if (field != null) { - BeanProperty p = field.getAnnotation(BeanProperty.class); - rawTypeMeta = f.resolveClassMeta(p, field.getGenericType(), typeVarImpls); - isUri |= (rawTypeMeta.isUri() || field.isAnnotationPresent(org.apache.juneau.annotation.URI.class)); - if (p != null) { - swap = getPropertyPojoSwap(p); - if (! p.properties().isEmpty()) - properties = StringUtils.split(p.properties(), ','); - bdClasses.addAll(Arrays.asList(p.beanDictionary())); - } - } - - if (getter != null) { - BeanProperty p = getter.getAnnotation(BeanProperty.class); - if (rawTypeMeta == null) - rawTypeMeta = f.resolveClassMeta(p, getter.getGenericReturnType(), typeVarImpls); - isUri |= (rawTypeMeta.isUri() || getter.isAnnotationPresent(org.apache.juneau.annotation.URI.class)); - if (p != null) { - if (swap == null) - swap = getPropertyPojoSwap(p); - if (properties != null && ! p.properties().isEmpty()) - properties = StringUtils.split(p.properties(), ','); - bdClasses.addAll(Arrays.asList(p.beanDictionary())); - } - } - - if (setter != null) { - BeanProperty p = setter.getAnnotation(BeanProperty.class); - if (rawTypeMeta == null) - rawTypeMeta = f.resolveClassMeta(p, setter.getGenericParameterTypes()[0], typeVarImpls); - isUri |= (rawTypeMeta.isUri() || setter.isAnnotationPresent(org.apache.juneau.annotation.URI.class)); - if (p != null) { - if (swap == null) - swap = getPropertyPojoSwap(p); - if (properties != null && ! p.properties().isEmpty()) - properties = StringUtils.split(p.properties(), ','); - bdClasses.addAll(Arrays.asList(p.beanDictionary())); - } - } - - if (rawTypeMeta == null) - return false; - - this.beanRegistry = new BeanRegistry(beanContext, parentBeanRegistry, bdClasses.toArray(new Class<?>[0])); - - // Do some annotation validation. - Class<?> c = rawTypeMeta.getInnerClass(); - if (getter != null && ! isParentClass(getter.getReturnType(), c)) - return false; - if (setter != null && ! isParentClass(setter.getParameterTypes()[0], c)) - return false; - if (field != null && ! isParentClass(field.getType(), c)) - return false; - - return true; - } - - private PojoSwap getPropertyPojoSwap(BeanProperty p) throws Exception { - Class<?> c = p.swap(); - if (c == Null.class) - return null; - try { - if (ClassUtils.isParentClass(PojoSwap.class, c)) { - return (PojoSwap)c.newInstance(); - } - throw new RuntimeException("TODO - Surrogate swaps not yet supported."); - } catch (Exception e) { - throw new BeanRuntimeException(this.beanMeta.c, "Could not instantiate PojoSwap ''{0}'' for bean property ''{1}''", c.getName(), this.name).initCause(e); - } - } - /** * Equivalent to calling {@link BeanMap#get(Object)}, but is faster since it avoids looking up the property meta. * @@ -328,6 +367,9 @@ public class BeanPropertyMeta { */ public Object get(BeanMap<?> m) { try { + if (overrideValue != null) + return overrideValue; + // Read-only beans have their properties stored in a cache until getBean() is called. Object bean = m.bean; if (bean == null) http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/58781bee/juneau-core/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java ---------------------------------------------------------------------- diff --git a/juneau-core/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java b/juneau-core/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java index b5cc352..940eda3 100644 --- a/juneau-core/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java +++ b/juneau-core/src/main/java/org/apache/juneau/internal/DelegateBeanMap.java @@ -115,19 +115,8 @@ public class DelegateBeanMap<T> extends BeanMap<T> { List<BeanPropertyMeta> l = new ArrayList<BeanPropertyMeta>(keys.size()); for (final String key : keys) { BeanPropertyMeta p = this.getPropertyMeta(key); - if (overrideValues.containsKey(key)) { - final BeanPropertyMeta p2 = p; - p = new BeanPropertyMeta(this.meta, key) { - @Override /* BeanPropertyMeta */ - public Object get(BeanMap<?> m) { - return overrideValues.get(key); - } - @Override /* BeanPropertyMeta */ - public <M extends BeanPropertyMetaExtended> M getExtendedMeta(Class<M> c) { - return p2.getExtendedMeta(c); - } - }; - } + if (overrideValues.containsKey(key)) + p = new BeanPropertyMeta.Builder(this.meta, key, overrideValues.get(key), p).build(); if (p == null) throw new BeanRuntimeException(super.getClassMeta().getInnerClass(), "Property ''{0}'' not found on class.", key); l.add(p);
