You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2016/08/29 00:35:51 UTC
incubator-juneau git commit: Make fields in BeanMeta final.
Repository: incubator-juneau
Updated Branches:
refs/heads/master ecc843021 -> 83f2b35ba
Make fields in BeanMeta final.
Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/83f2b35b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/83f2b35b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/83f2b35b
Branch: refs/heads/master
Commit: 83f2b35ba002b4d0fbefa02358476e00e332e467
Parents: ecc8430
Author: jamesbognar <ja...@gmail.com>
Authored: Sun Aug 28 20:35:47 2016 -0400
Committer: jamesbognar <ja...@gmail.com>
Committed: Sun Aug 28 20:35:47 2016 -0400
----------------------------------------------------------------------
.../main/java/org/apache/juneau/BeanMeta.java | 517 ++++++++++---------
.../org/apache/juneau/BeanMetaFiltered.java | 32 +-
.../org/apache/juneau/BeanPropertyMeta.java | 6 +-
.../main/java/org/apache/juneau/ClassMeta.java | 5 +-
4 files changed, 287 insertions(+), 273 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/83f2b35b/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 1453dbb..840b68b 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanMeta.java
@@ -62,44 +62,43 @@ import org.apache.juneau.utils.*;
public class BeanMeta<T> {
/** The target class type that this meta object describes. */
- protected ClassMeta<T> classMeta;
+ protected final ClassMeta<T> classMeta;
/** The target class that this meta object describes. */
- protected Class<T> c;
+ protected final Class<T> c;
/** The properties on the target class. */
- protected Map<String,BeanPropertyMeta> properties;
+ protected final Map<String,BeanPropertyMeta> properties;
/** The getter properties on the target class. */
- protected Map<Method,String> getterProps = new HashMap<Method,String>();
+ protected final Map<Method,String> getterProps;
/** The setter properties on the target class. */
- protected Map<Method,String> setterProps = new HashMap<Method,String>();
+ protected final Map<Method,String> setterProps;
/** The bean context that created this metadata object. */
- protected BeanContext ctx;
+ protected final BeanContext ctx;
/** Optional bean filter associated with the target class. */
- protected BeanFilter<? extends T> beanFilter;
+ protected final BeanFilter<? extends T> beanFilter;
/** Type variables implemented by this bean. */
- protected Map<Class<?>,Class<?>[]> typeVarImpls;
+ protected final Map<Class<?>,Class<?>[]> typeVarImpls;
/** The constructor for this bean. */
- protected Constructor<T> constructor;
+ protected final Constructor<T> constructor;
/** For beans with constructors with BeanConstructor annotation, this is the list of constructor arg properties. */
- protected String[] constructorArgs = new String[0];
+ protected final String[] constructorArgs;
- private MetadataMap extMeta = new MetadataMap(); // Extended metadata
+ private final MetadataMap extMeta; // Extended metadata
// Other fields
- BeanPropertyMeta uriProperty; // The property identified as the URI for this bean (annotated with @BeanProperty.beanUri).
- BeanPropertyMeta subTypeIdProperty; // The property indentified as the sub type differentiator property (identified by @Bean.subTypeProperty annotation).
- PropertyNamer propertyNamer; // Class used for calculating bean property names.
- BeanPropertyMeta classProperty; // "_class" mock bean property.
+ final BeanPropertyMeta uriProperty; // The property identified as the URI for this bean (annotated with @BeanProperty.beanUri).
+ final BeanPropertyMeta subTypeIdProperty; // The property indentified as the sub type differentiator property (identified by @Bean.subTypeProperty annotation).
+ private final BeanPropertyMeta classProperty; // "_class" mock bean property.
- BeanMeta() {}
+ final String notABeanReason;
/**
* Constructor.
@@ -107,253 +106,315 @@ public class BeanMeta<T> {
* @param classMeta The target class.
* @param ctx The bean context that created this object.
* @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) {
+ protected BeanMeta(final ClassMeta<T> classMeta, BeanContext ctx, BeanFilter<? extends T> beanFilter, String[] pNames) {
this.classMeta = classMeta;
this.ctx = ctx;
+ this.c = classMeta.getInnerClass();
+
+ Builder<T> b = new Builder<T>(classMeta, ctx, beanFilter, pNames);
+ this.notABeanReason = b.init(this);
+
this.beanFilter = beanFilter;
+ this.properties = b.properties;
+ this.getterProps = Collections.unmodifiableMap(b.getterProps);
+ this.setterProps = Collections.unmodifiableMap(b.setterProps);
+ this.typeVarImpls = b.typeVarImpls;
+ this.constructor = b.constructor;
+ this.constructorArgs = b.constructorArgs;
+ this.extMeta = b.extMeta;
+ this.uriProperty = b.uriProperty;
+ this.subTypeIdProperty = b.subTypeIdProperty;
this.classProperty = new BeanPropertyMeta(this, "_class", ctx.string());
- this.c = classMeta.getInnerClass();
}
- /**
- * Returns the {@link ClassMeta} of this bean.
- *
- * @return The {@link ClassMeta} of this bean.
- */
- @BeanIgnore
- public ClassMeta<T> getClassMeta() {
- return classMeta;
- }
- /**
- * Initializes this bean meta, and returns an error message if the specified class is not
- * a bean for any reason.
- *
- * @return Reason why this class isn't a bean, or <jk>null</jk> if no problems detected.
- * @throws BeanRuntimeException If unexpected error occurs such as invalid annotations on the bean class.
- */
- @SuppressWarnings("unchecked")
- protected String init() throws BeanRuntimeException {
-
- try {
- Visibility
- conVis = ctx.beanConstructorVisibility,
- cVis = ctx.beanClassVisibility,
- mVis = ctx.beanMethodVisibility,
- fVis = ctx.beanFieldVisibility;
-
- // If @Bean.interfaceClass is specified on the parent class, then we want
- // to use the properties defined on that class, not the subclass.
- Class<?> c2 = (beanFilter != null && beanFilter.getInterfaceClass() != null ? beanFilter.getInterfaceClass() : c);
-
- Class<?> stopClass = (beanFilter != null ? beanFilter.getStopClass() : Object.class);
- if (stopClass == null)
- stopClass = Object.class;
-
- Map<String,BeanPropertyMeta> normalProps = new LinkedHashMap<String,BeanPropertyMeta>();
-
- /// See if this class matches one the patterns in the exclude-class list.
- if (ctx.isNotABean(c))
- return "Class matches exclude-class list";
-
- if (! cVis.isVisible(c.getModifiers()))
- return "Class is not public";
-
- if (c.isAnnotationPresent(BeanIgnore.class))
- return "Class is annotated with @BeanIgnore";
-
- // Make sure it's serializable.
- if (beanFilter == null && ctx.beansRequireSerializable && ! isParentClass(Serializable.class, c))
- return "Class is not serializable";
-
- // Look for @BeanConstructor constructor.
- for (Constructor<?> x : c.getConstructors()) {
- if (x.isAnnotationPresent(BeanConstructor.class)) {
- if (constructor != null)
- throw new BeanRuntimeException(c, "Multiple instances of '@BeanConstructor' found.");
- constructor = (Constructor<T>)x;
- constructorArgs = x.getAnnotation(BeanConstructor.class).properties();
- if (constructorArgs.length != x.getParameterTypes().length)
- throw new BeanRuntimeException(c, "Number of properties defined in '@BeanConstructor' annotation does not match number of parameters in constructor.");
- if (! setAccessible(constructor))
- throw new BeanRuntimeException(c, "Could not set accessibility to true on method with @BeanConstructor annotation. Method=''{0}''", constructor.getName());
+ private static final class Builder<T> {
+ ClassMeta<T> classMeta;
+ BeanContext ctx;
+ BeanFilter<? extends T> beanFilter;
+ String[] pNames;
+ Map<String,BeanPropertyMeta> properties;
+ Map<Method,String> getterProps = new HashMap<Method,String>();
+ Map<Method,String> setterProps = new HashMap<Method,String>();
+ Map<Class<?>,Class<?>[]> typeVarImpls;
+ Constructor<T> constructor;
+ String[] constructorArgs = new String[0];
+ MetadataMap extMeta = new MetadataMap();
+ BeanPropertyMeta uriProperty;
+ BeanPropertyMeta subTypeIdProperty;
+ PropertyNamer propertyNamer;
+
+ private Builder(ClassMeta<T> classMeta, BeanContext ctx, BeanFilter<? extends T> beanFilter, String[] pNames) {
+ this.classMeta = classMeta;
+ this.ctx = ctx;
+ this.beanFilter = beanFilter;
+ this.pNames = pNames;
+ }
+
+ @SuppressWarnings("unchecked")
+ private String init(BeanMeta<T> beanMeta) {
+ Class<?> c = classMeta.getInnerClass();
+
+ try {
+ Visibility
+ conVis = ctx.beanConstructorVisibility,
+ cVis = ctx.beanClassVisibility,
+ mVis = ctx.beanMethodVisibility,
+ fVis = ctx.beanFieldVisibility;
+
+ // If @Bean.interfaceClass is specified on the parent class, then we want
+ // to use the properties defined on that class, not the subclass.
+ Class<?> c2 = (beanFilter != null && beanFilter.getInterfaceClass() != null ? beanFilter.getInterfaceClass() : c);
+
+ Class<?> stopClass = (beanFilter != null ? beanFilter.getStopClass() : Object.class);
+ if (stopClass == null)
+ stopClass = Object.class;
+
+ Map<String,BeanPropertyMeta> normalProps = new LinkedHashMap<String,BeanPropertyMeta>();
+
+ /// See if this class matches one the patterns in the exclude-class list.
+ if (ctx.isNotABean(c))
+ return "Class matches exclude-class list";
+
+ if (! cVis.isVisible(c.getModifiers()))
+ return "Class is not public";
+
+ if (c.isAnnotationPresent(BeanIgnore.class))
+ return "Class is annotated with @BeanIgnore";
+
+ // Make sure it's serializable.
+ if (beanFilter == null && ctx.beansRequireSerializable && ! isParentClass(Serializable.class, c))
+ return "Class is not serializable";
+
+ // Look for @BeanConstructor constructor.
+ for (Constructor<?> x : c.getConstructors()) {
+ if (x.isAnnotationPresent(BeanConstructor.class)) {
+ if (constructor != null)
+ throw new BeanRuntimeException(c, "Multiple instances of '@BeanConstructor' found.");
+ constructor = (Constructor<T>)x;
+ constructorArgs = x.getAnnotation(BeanConstructor.class).properties();
+ if (constructorArgs.length != x.getParameterTypes().length)
+ throw new BeanRuntimeException(c, "Number of properties defined in '@BeanConstructor' annotation does not match number of parameters in constructor.");
+ if (! setAccessible(constructor))
+ throw new BeanRuntimeException(c, "Could not set accessibility to true on method with @BeanConstructor annotation. Method=''{0}''", constructor.getName());
+ }
}
- }
- // If this is an interface, look for impl classes defined in the context.
- if (constructor == null)
- constructor = (Constructor<T>)ctx.getImplClassConstructor(c, conVis);
+ // If this is an interface, look for impl classes defined in the context.
+ if (constructor == null)
+ constructor = (Constructor<T>)ctx.getImplClassConstructor(c, conVis);
- if (constructor == null)
- constructor = (Constructor<T>)ClassMeta.findNoArgConstructor(c, conVis);
+ if (constructor == null)
+ constructor = (Constructor<T>)ClassMeta.findNoArgConstructor(c, conVis);
- if (constructor == null && beanFilter == null && ctx.beansRequireDefaultConstructor)
- return "Class does not have the required no-arg constructor";
+ if (constructor == null && beanFilter == null && ctx.beansRequireDefaultConstructor)
+ return "Class does not have the required no-arg constructor";
- if (! setAccessible(constructor))
- throw new BeanRuntimeException(c, "Could not set accessibility to true on no-arg constructor");
+ if (! setAccessible(constructor))
+ throw new BeanRuntimeException(c, "Could not set accessibility to true on no-arg constructor");
- // Explicitly defined property names in @Bean annotation.
- Set<String> fixedBeanProps = new LinkedHashSet<String>();
+ // Explicitly defined property names in @Bean annotation.
+ Set<String> fixedBeanProps = new LinkedHashSet<String>();
- if (beanFilter != null) {
+ if (beanFilter != null) {
- // Get the 'properties' attribute if specified.
- if (beanFilter.getProperties() != null)
- for (String p : beanFilter.getProperties())
- fixedBeanProps.add(p);
+ // Get the 'properties' attribute if specified.
+ if (beanFilter.getProperties() != null)
+ for (String p : beanFilter.getProperties())
+ fixedBeanProps.add(p);
- if (beanFilter.getPropertyNamer() != null)
- propertyNamer = beanFilter.getPropertyNamer();
- }
+ if (beanFilter.getPropertyNamer() != null)
+ propertyNamer = beanFilter.getPropertyNamer();
+ }
- if (propertyNamer == null)
- propertyNamer = new PropertyNamerDefault();
-
- // 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(this, name));
-
- if (ctx.useJavaBeanIntrospector) {
- BeanInfo bi = null;
- if (! c2.isInterface())
- bi = Introspector.getBeanInfo(c2, stopClass);
- else
- bi = Introspector.getBeanInfo(c2, null);
- if (bi != null) {
- for (PropertyDescriptor pd : bi.getPropertyDescriptors()) {
- String name = pd.getName();
- if (! normalProps.containsKey(name))
- normalProps.put(name, new BeanPropertyMeta(this, name));
- normalProps.get(name).setGetter(pd.getReadMethod()).setSetter(pd.getWriteMethod());
+ if (propertyNamer == null)
+ propertyNamer = new PropertyNamerDefault();
+
+ // 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));
+
+ if (ctx.useJavaBeanIntrospector) {
+ BeanInfo bi = null;
+ if (! c2.isInterface())
+ bi = Introspector.getBeanInfo(c2, stopClass);
+ else
+ bi = Introspector.getBeanInfo(c2, null);
+ if (bi != null) {
+ for (PropertyDescriptor pd : bi.getPropertyDescriptors()) {
+ String name = pd.getName();
+ if (! normalProps.containsKey(name))
+ normalProps.put(name, new BeanPropertyMeta(beanMeta, name));
+ normalProps.get(name).setGetter(pd.getReadMethod()).setSetter(pd.getWriteMethod());
+ }
}
- }
- } else /* Use 'better' introspection */ {
+ } else /* Use 'better' introspection */ {
- for (Field f : findBeanFields(c2, stopClass, fVis)) {
- String name = findPropertyName(f, fixedBeanProps);
- if (name != null) {
- if (! normalProps.containsKey(name))
- normalProps.put(name, new BeanPropertyMeta(this, name));
- normalProps.get(name).setField(f);
+ for (Field f : findBeanFields(c2, stopClass, fVis)) {
+ String name = findPropertyName(f, fixedBeanProps);
+ if (name != null) {
+ if (! normalProps.containsKey(name))
+ normalProps.put(name, new BeanPropertyMeta(beanMeta, name));
+ normalProps.get(name).setField(f);
+ }
}
- }
- List<BeanMethod> bms = findBeanMethods(c2, stopClass, mVis, fixedBeanProps, propertyNamer);
-
- // Iterate through all the getters.
- for (BeanMethod bm : bms) {
- String pn = bm.propertyName;
- Method m = bm.method;
- if (! normalProps.containsKey(pn))
- normalProps.put(pn, new BeanPropertyMeta(this, pn));
- BeanPropertyMeta bpm = normalProps.get(pn);
- if (! bm.isSetter)
- bpm.setGetter(m);
- }
+ List<BeanMethod> bms = findBeanMethods(c2, stopClass, mVis, fixedBeanProps, propertyNamer);
+
+ // Iterate through all the getters.
+ for (BeanMethod bm : bms) {
+ String pn = bm.propertyName;
+ Method m = bm.method;
+ if (! normalProps.containsKey(pn))
+ normalProps.put(pn, new BeanPropertyMeta(beanMeta, pn));
+ BeanPropertyMeta bpm = normalProps.get(pn);
+ if (! bm.isSetter)
+ bpm.setGetter(m);
+ }
- // Now iterate through all the setters.
- for (BeanMethod bm : bms) {
- if (bm.isSetter) {
- BeanPropertyMeta bpm = normalProps.get(bm.propertyName);
- if (bm.matchesPropertyType(bpm))
- bpm.setSetter(bm.method);
+ // Now iterate through all the setters.
+ for (BeanMethod bm : bms) {
+ if (bm.isSetter) {
+ BeanPropertyMeta bpm = normalProps.get(bm.propertyName);
+ if (bm.matchesPropertyType(bpm))
+ bpm.setSetter(bm.method);
+ }
}
}
- }
- typeVarImpls = new HashMap<Class<?>,Class<?>[]>();
- findTypeVarImpls(c, typeVarImpls);
- if (typeVarImpls.isEmpty())
- typeVarImpls = null;
+ typeVarImpls = new HashMap<Class<?>,Class<?>[]>();
+ findTypeVarImpls(c, typeVarImpls);
+ if (typeVarImpls.isEmpty())
+ 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();
- try {
- if (p.validate()) {
+ // Eliminate invalid properties, and set the contents of getterProps and setterProps.
+ for (Iterator<BeanPropertyMeta> i = normalProps.values().iterator(); i.hasNext();) {
+ BeanPropertyMeta p = i.next();
+ try {
+ if (p.validate(ctx, typeVarImpls)) {
- if (p.getGetter() != null)
- getterProps.put(p.getGetter(), p.getName());
+ if (p.getGetter() != null)
+ getterProps.put(p.getGetter(), p.getName());
- if (p.getSetter() != null)
- setterProps.put(p.getSetter(), p.getName());
+ if (p.getSetter() != null)
+ setterProps.put(p.getSetter(), p.getName());
- if (p.isBeanUri())
- uriProperty = p;
+ if (p.isBeanUri())
+ uriProperty = p;
- } else {
- i.remove();
+ } else {
+ i.remove();
+ }
+ } catch (ClassNotFoundException e) {
+ throw new BeanRuntimeException(c, e.getLocalizedMessage());
}
- } catch (ClassNotFoundException e) {
- throw new BeanRuntimeException(c, e.getLocalizedMessage());
}
- }
-
- // Check for missing properties.
- for (String fp : fixedBeanProps)
- if (! normalProps.containsKey(fp))
- throw new BeanRuntimeException(c, "The property ''{0}'' was defined on the @Bean(properties=X) annotation but was not found on the class definition.", fp);
-
- // Mark constructor arg properties.
- for (String fp : constructorArgs) {
- BeanPropertyMeta 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();
- }
-
- // Make sure at least one property was found.
- if (beanFilter == null && ctx.beansRequireSomeProperties && normalProps.size() == 0)
- return "No properties detected on bean class";
- boolean sortProperties = (ctx.sortProperties || (beanFilter != null && beanFilter.isSortProperties())) && fixedBeanProps.isEmpty();
+ // Check for missing properties.
+ for (String fp : fixedBeanProps)
+ if (! normalProps.containsKey(fp))
+ throw new BeanRuntimeException(c, "The property ''{0}'' was defined on the @Bean(properties=X) annotation but was not found on the class definition.", fp);
+
+ // Mark constructor arg properties.
+ for (String fp : constructorArgs) {
+ BeanPropertyMeta 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();
+ }
- properties = sortProperties ? new TreeMap<String,BeanPropertyMeta>() : new LinkedHashMap<String,BeanPropertyMeta>();
+ // Make sure at least one property was found.
+ if (beanFilter == null && ctx.beansRequireSomeProperties && normalProps.size() == 0)
+ return "No properties detected on bean class";
- if (beanFilter != null && beanFilter.getSubTypeProperty() != null) {
- String subTypeProperty = beanFilter.getSubTypeProperty();
- this.subTypeIdProperty = new SubTypePropertyMeta(subTypeProperty, beanFilter.getSubTypes(), normalProps.remove(subTypeProperty));
- properties.put(subTypeProperty, this.subTypeIdProperty);
- }
+ boolean sortProperties = (ctx.sortProperties || (beanFilter != null && beanFilter.isSortProperties())) && fixedBeanProps.isEmpty();
- properties.putAll(normalProps);
+ properties = sortProperties ? new TreeMap<String,BeanPropertyMeta>() : new LinkedHashMap<String,BeanPropertyMeta>();
- // If a beanFilter is defined, look for inclusion and exclusion lists.
- if (beanFilter != null) {
+ if (beanFilter != null && beanFilter.getSubTypeProperty() != null) {
+ String subTypeProperty = beanFilter.getSubTypeProperty();
+ this.subTypeIdProperty = new SubTypePropertyMeta(beanMeta, subTypeProperty, beanFilter.getSubTypes(), normalProps.remove(subTypeProperty));
+ properties.put(subTypeProperty, this.subTypeIdProperty);
+ }
- // Eliminated excluded properties if BeanFilter.excludeKeys is specified.
- String[] includeKeys = beanFilter.getProperties();
- String[] excludeKeys = beanFilter.getExcludeProperties();
- if (excludeKeys != null) {
- for (String k : excludeKeys)
- properties.remove(k);
+ properties.putAll(normalProps);
+
+ // If a beanFilter is defined, look for inclusion and exclusion lists.
+ if (beanFilter != null) {
+
+ // Eliminated excluded properties if BeanFilter.excludeKeys is specified.
+ String[] includeKeys = beanFilter.getProperties();
+ String[] excludeKeys = beanFilter.getExcludeProperties();
+ if (excludeKeys != null) {
+ for (String k : excludeKeys)
+ properties.remove(k);
+
+ // Only include specified properties if BeanFilter.includeKeys is specified.
+ // Note that the order must match includeKeys.
+ } else if (includeKeys != null) {
+ Map<String,BeanPropertyMeta> properties2 = new LinkedHashMap<String,BeanPropertyMeta>();
+ for (String k : includeKeys) {
+ if (properties.containsKey(k))
+ properties2.put(k, properties.get(k));
+ }
+ properties = properties2;
+ }
+ }
- // Only include specified properties if BeanFilter.includeKeys is specified.
- // Note that the order must match includeKeys.
- } else if (includeKeys != null) {
+ if (pNames != null) {
Map<String,BeanPropertyMeta> properties2 = new LinkedHashMap<String,BeanPropertyMeta>();
- for (String k : includeKeys) {
+ for (String k : pNames) {
if (properties.containsKey(k))
properties2.put(k, properties.get(k));
}
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) {
+ return "Exception: " + StringUtils.getStackTrace(e);
}
- // We return this through the Bean.keySet() interface, so make sure it's not modifiable.
- properties = Collections.unmodifiableMap(properties);
+ return null;
+ }
- } catch (BeanRuntimeException e) {
- throw e;
- } catch (Exception e) {
- return "Exception: " + StringUtils.getStackTrace(e);
+ /*
+ * Returns the property name of the specified field if it's a valid property.
+ * Returns null if the field isn't a valid property.
+ */
+ private String findPropertyName(Field f, Set<String> fixedBeanProps) {
+ BeanProperty bp = f.getAnnotation(BeanProperty.class);
+ if (bp != null && ! bp.name().equals("")) {
+ String name = bp.name();
+ if (fixedBeanProps.isEmpty() || fixedBeanProps.contains(name))
+ return name;
+ throw new BeanRuntimeException(classMeta.getInnerClass(), "Method property ''{0}'' identified in @BeanProperty, but missing from @Bean", name);
+ }
+ String name = propertyNamer.getPropertyName(f.getName());
+ if (fixedBeanProps.isEmpty() || fixedBeanProps.contains(name))
+ return name;
+ return null;
}
- return null;
+ }
+
+
+ /**
+ * Returns the {@link ClassMeta} of this bean.
+ *
+ * @return The {@link ClassMeta} of this bean.
+ */
+ @BeanIgnore
+ public ClassMeta<T> getClassMeta() {
+ return classMeta;
}
/**
@@ -621,24 +682,6 @@ public class BeanMeta<T> {
return null;
}
- /*
- * Returns the property name of the specified field if it's a valid property.
- * Returns null if the field isn't a valid property.
- */
- private String findPropertyName(Field f, Set<String> fixedBeanProps) {
- BeanProperty bp = f.getAnnotation(BeanProperty.class);
- if (bp != null && ! bp.name().equals("")) {
- String name = bp.name();
- if (fixedBeanProps.isEmpty() || fixedBeanProps.contains(name))
- return name;
- throw new BeanRuntimeException(c, "Method property ''{0}'' identified in @BeanProperty, but missing from @Bean", name);
- }
- String name = propertyNamer.getPropertyName(f.getName());
- if (fixedBeanProps.isEmpty() || fixedBeanProps.contains(name))
- return name;
- return null;
- }
-
/**
* Recursively determines the classes represented by parameterized types in the class hierarchy of
* the specified type, and puts the results in the specified map.<br>
@@ -699,15 +742,17 @@ public class BeanMeta<T> {
* Bean property for getting and setting bean subtype.
*/
@SuppressWarnings({"rawtypes","unchecked"})
- private class SubTypePropertyMeta extends BeanPropertyMeta {
+ 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;
- SubTypePropertyMeta(String subTypeAttr, Map<Class<?>,String> subTypes, BeanPropertyMeta realProperty) {
- super(BeanMeta.this, subTypeAttr, ctx.string());
+ SubTypePropertyMeta(BeanMeta beanMeta, String subTypeAttr, Map<Class<?>,String> subTypes, BeanPropertyMeta realProperty) {
+ super(beanMeta, subTypeAttr, beanMeta.ctx.string());
this.subTypes = subTypes;
this.realProperty = realProperty;
+ this.beanMeta = beanMeta;
}
/*
@@ -721,7 +766,7 @@ public class BeanMeta<T> {
for (Entry<Class<?>,String> e : subTypes.entrySet()) {
if (e.getValue().equals(subTypeId)) {
Class subTypeClass = e.getKey();
- m.meta = ctx.getBeanMeta(subTypeClass);
+ m.meta = beanMeta.ctx.getBeanMeta(subTypeClass);
try {
m.setBean(subTypeClass.newInstance());
if (realProperty != null)
@@ -736,14 +781,14 @@ public class BeanMeta<T> {
return null;
}
}
- throw new BeanRuntimeException(c, "Unknown subtype ID ''{0}''", subTypeId);
+ throw new BeanRuntimeException(beanMeta.c, "Unknown subtype ID ''{0}''", subTypeId);
}
@Override /* BeanPropertyMeta */
public Object get(BeanMap<?> m) throws BeanRuntimeException {
- String subTypeId = beanFilter.getSubTypes().get(c);
+ String subTypeId = beanMeta.beanFilter.getSubTypes().get(beanMeta.c);
if (subTypeId == null)
- throw new BeanRuntimeException(c, "Unmapped sub type class");
+ throw new BeanRuntimeException(beanMeta.c, "Unmapped sub type class");
return subTypeId;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/83f2b35b/juneau-core/src/main/java/org/apache/juneau/BeanMetaFiltered.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanMetaFiltered.java b/juneau-core/src/main/java/org/apache/juneau/BeanMetaFiltered.java
index b9d1d9e..f731d9d 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanMetaFiltered.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanMetaFiltered.java
@@ -25,8 +25,6 @@ import org.apache.juneau.annotation.*;
*/
public final class BeanMetaFiltered<T> extends BeanMeta<T> {
- private final BeanMeta<T> innerMeta;
-
/**
* Wrapper constructor.
*
@@ -34,10 +32,7 @@ public final class BeanMetaFiltered<T> extends BeanMeta<T> {
* @param pNames The list of transformed property names.
*/
public BeanMetaFiltered(BeanMeta<T> innerMeta, String[] pNames) {
- this.innerMeta = innerMeta;
- this.properties = new LinkedHashMap<String,BeanPropertyMeta>();
- for (String p : pNames)
- properties.put(p, innerMeta.getPropertyMeta(p));
+ super(innerMeta.classMeta, innerMeta.ctx, innerMeta.beanFilter, pNames);
}
/**
@@ -49,29 +44,4 @@ public final class BeanMetaFiltered<T> extends BeanMeta<T> {
public BeanMetaFiltered(BeanMeta<T> innerMeta, Collection<String> pNames) {
this(innerMeta, pNames.toArray(new String[pNames.size()]));
}
-
- @Override /* Delagate */
- public ClassMeta<T> getClassMeta() {
- return innerMeta.classMeta;
- }
-
- @Override /* Delagate */
- public <M extends BeanMetaExtended> M getExtendedMeta(Class<M> m) {
- return innerMeta.getExtendedMeta(m);
- }
-
- @Override /* BeanMeta */
- public Collection<BeanPropertyMeta> getPropertyMetas() {
- return properties.values();
- }
-
- @Override /* BeanMeta */
- public BeanPropertyMeta getPropertyMeta(String name) {
- return properties.get(name);
- }
-
- @Override /* Object */
- public String toString() {
- return innerMeta.c.getName();
- }
}
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/83f2b35b/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 b9d18b9..0d0a8b4 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanPropertyMeta.java
@@ -233,10 +233,7 @@ public class BeanPropertyMeta {
return extMeta.get(c, this);
}
- boolean validate() throws Exception {
-
- BeanContext f = beanMeta.ctx;
- Map<Class<?>,Class<?>[]> typeVarImpls = beanMeta.typeVarImpls;
+ boolean validate(BeanContext f, Map<Class<?>,Class<?>[]> typeVarImpls) throws Exception {
if (field == null && getter == null)
return false;
@@ -565,6 +562,7 @@ public class BeanPropertyMeta {
} catch (BeanRuntimeException e) {
throw e;
} catch (Exception e) {
+ e.printStackTrace();
if (beanMeta.ctx.ignoreInvocationExceptionsOnSetters) {
if (rawTypeMeta.isPrimitive())
return rawTypeMeta.getPrimitiveDefault();
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/83f2b35b/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 6da687c..eb60730 100644
--- a/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java
@@ -299,9 +299,10 @@ public final class ClassMeta<T> implements Type {
// Note that this needs to be done after all other initialization has been done.
else if (classCategory == UNKNOWN) {
- BeanMeta newMeta = new BeanMeta(this, beanContext, beanFilter);
+ BeanMeta newMeta = null;
try {
- notABeanReason = newMeta.init();
+ newMeta = new BeanMeta(this, beanContext, beanFilter, null);
+ notABeanReason = newMeta.notABeanReason;
} catch (RuntimeException e) {
notABeanReason = e.getMessage();
throw e;