Repository: incubator-juneau Updated Branches: refs/heads/master bdeb4f02c -> c8fa4ed45
Improvements to ClassMeta/BeanContext. Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/c8fa4ed4 Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/c8fa4ed4 Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/c8fa4ed4 Branch: refs/heads/master Commit: c8fa4ed455c797b71a0d5d0fde881df4695121f3 Parents: bdeb4f0 Author: JamesBognar <[email protected]> Authored: Sat Feb 4 15:44:34 2017 -0500 Committer: JamesBognar <[email protected]> Committed: Sat Feb 4 15:44:34 2017 -0500 ---------------------------------------------------------------------- .../java/org/apache/juneau/BeanContext.java | 14 +++--- .../main/java/org/apache/juneau/ClassMeta.java | 49 +++++++++++++++++--- 2 files changed, 50 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c8fa4ed4/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 7690729..05006f3 100644 --- a/juneau-core/src/main/java/org/apache/juneau/BeanContext.java +++ b/juneau-core/src/main/java/org/apache/juneau/BeanContext.java @@ -1346,10 +1346,11 @@ public class BeanContext extends Context { if (oc instanceof Class) { Class c = (Class)oc; if (Collection.class.isAssignableFrom(c)) { + ClassMeta<?> rawType = getClassMeta(c); ClassMeta<?> ce = getClassMeta(Array.get(o, 1)); if (ce.isObject()) - return getClassMeta(c); - return new ClassMeta(c, this).setElementType(ce); + return (ClassMeta<T>)rawType; + return new ClassMeta(rawType, null, null, ce); } } } else if (len == 3) { @@ -1357,11 +1358,12 @@ public class BeanContext extends Context { if (oc instanceof Class) { Class c = (Class)oc; if (Map.class.isAssignableFrom(c)) { + ClassMeta<?> rawType = getClassMeta(c); ClassMeta<?> ck = getClassMeta(Array.get(o, 1)); ClassMeta<?> cv = getClassMeta(Array.get(o, 2)); if (ck.isObject() && cv.isObject()) - return getClassMeta(c); - return new ClassMeta(c, this).setKeyType(ck).setValueType(cv); + return (ClassMeta<T>)rawType; + return new ClassMeta(rawType, ck, cv, null); } } } @@ -1601,7 +1603,7 @@ public class BeanContext extends Context { ClassMeta<?> valueType = resolveType(pParams[1], cm2.getValueType(), cm.getValueType()); if (keyType.isObject() && valueType.isObject()) return cm2; - return new ClassMeta<T>(cm2.innerClass, this).setKeyType(keyType).setValueType(valueType); + return new ClassMeta<T>(cm2, keyType, valueType, null); } if (cm2.isCollection()) { @@ -1611,7 +1613,7 @@ public class BeanContext extends Context { ClassMeta<?> elementType = resolveType(pParams[0], cm2.getElementType(), cm.getElementType()); if (elementType.isObject()) return cm2; - return new ClassMeta<T>(cm2.innerClass, this).setElementType(elementType); + return new ClassMeta<T>(cm2, null, null, elementType); } return cm2; http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/c8fa4ed4/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 c36ffd8..e98f595 100644 --- a/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java +++ b/juneau-core/src/main/java/org/apache/juneau/ClassMeta.java @@ -455,33 +455,33 @@ public final class ClassMeta<T> implements Type { }; } - serializedClassMeta = (pojoSwap == null ? this : beanContext.getClassMeta(pojoSwap.getSwapClass())); + serializedClassMeta = (pojoSwap == null ? this : findClassMeta(pojoSwap.getSwapClass())); if (serializedClassMeta == null) serializedClassMeta = this; // If this is an array, get the element type. if (cc == ARRAY) - elementType = beanContext.getClassMeta(innerClass.getComponentType()); + elementType = findClassMeta(innerClass.getComponentType()); // If this is a MAP, see if it's parameterized (e.g. AddressBook extends HashMap<String,Person>) else if (cc == MAP) { - ClassMeta[] parameters = beanContext.findParameters(innerClass, innerClass); + ClassMeta[] parameters = findParameters(); if (parameters != null && parameters.length == 2) { keyType = parameters[0]; valueType = parameters[1]; } else { - keyType = beanContext.getClassMeta(Object.class); - valueType = beanContext.getClassMeta(Object.class); + keyType = findClassMeta(Object.class); + valueType = findClassMeta(Object.class); } } // If this is a COLLECTION, see if it's parameterized (e.g. AddressBook extends LinkedList<Person>) else if (cc == COLLECTION) { - ClassMeta[] parameters = beanContext.findParameters(innerClass, innerClass); + ClassMeta[] parameters = findParameters(); if (parameters != null && parameters.length == 1) { elementType = parameters[0]; } else { - elementType = beanContext.getClassMeta(Object.class); + elementType = findClassMeta(Object.class); } } @@ -520,6 +520,14 @@ public final class ClassMeta<T> implements Type { return this; } + private ClassMeta<?> findClassMeta(Class<?> c) { + return beanContext.getClassMeta(c); + } + + private ClassMeta<?>[] findParameters() { + return beanContext.findParameters(innerClass, innerClass); + } + /** * Returns the bean dictionary name associated with this class. * <p> @@ -1504,4 +1512,31 @@ public final class ClassMeta<T> implements Type { public int hashCode() { return super.hashCode(); } + + public abstract static class CreateSession { + LinkedList<ClassMeta<?>> stack; + + public CreateSession push(ClassMeta<?> cm) { + if (stack == null) + stack = new LinkedList<ClassMeta<?>>(); + stack.add(cm); + return this; + } + + public CreateSession pop(ClassMeta<?> expected) { + if (stack == null || stack.removeLast() != expected) + throw new BeanRuntimeException("ClassMetaSession creation stack corruption!"); + return this; + } + + public <T> ClassMeta<T> getClassMeta(Class<T> c) { + if (stack != null) + for (ClassMeta<?> cm : stack) + if (cm.innerClass == c) + return (ClassMeta<T>)cm; + return createClassMeta(c); + } + + public abstract <T> ClassMeta<T> createClassMeta(Class<T> c); + } }
