Repository: cayenne Updated Branches: refs/heads/STABLE-3.1 0cf1ab043 -> 33300f6dc
CAY-2066 Fixes for inner enums handling in ExtendedTypeMap *porting fix from master Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/33300f6d Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/33300f6d Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/33300f6d Branch: refs/heads/STABLE-3.1 Commit: 33300f6dc24f4ca77cea0807716feec8719db968 Parents: 0cf1ab0 Author: aadamchik <aadamc...@apache.org> Authored: Sat Mar 5 16:31:06 2016 -0800 Committer: aadamchik <aadamc...@apache.org> Committed: Sat Mar 5 16:37:22 2016 -0800 ---------------------------------------------------------------------- docs/doc/src/main/resources/RELEASE-NOTES.txt | 1 + .../apache/cayenne/access/types/EnumType.java | 4 ++- .../cayenne/access/types/ExtendedTypeMap.java | 32 +++++++++++++++++--- .../access/types/ExtendedTypeMapEnumsTest.java | 26 ++++++++++++++-- 4 files changed, 56 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/33300f6d/docs/doc/src/main/resources/RELEASE-NOTES.txt ---------------------------------------------------------------------- diff --git a/docs/doc/src/main/resources/RELEASE-NOTES.txt b/docs/doc/src/main/resources/RELEASE-NOTES.txt index 3c8ef6a..861658e 100644 --- a/docs/doc/src/main/resources/RELEASE-NOTES.txt +++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt @@ -23,6 +23,7 @@ CAY-1978 ESCAPE clause should be included in LIKE parenthesis CAY-1979 Prefetches on Many-to-Many Relationships with Longvarchar CAY-2047 Relationship mapping with target inheritance CAY-2049 Changing the Relationship name in ObjRelationship Inspector has no effect +CAY-2066 Memory leak in ExtendedTypeMap for inner classes ---------------------------------- Release: 3.1-final http://git-wip-us.apache.org/repos/asf/cayenne/blob/33300f6d/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/EnumType.java ---------------------------------------------------------------------- diff --git a/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/EnumType.java b/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/EnumType.java index 02f776c..d8ef3bb 100644 --- a/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/EnumType.java +++ b/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/EnumType.java @@ -40,6 +40,7 @@ public class EnumType<T extends Enum<T>> implements ExtendedType { protected Class<T> enumClass; protected Object[] values; + protected String canonicalName; public EnumType(Class<T> enumClass) { if (enumClass == null) { @@ -47,6 +48,7 @@ public class EnumType<T extends Enum<T>> implements ExtendedType { } this.enumClass = enumClass; + this.canonicalName = enumClass.getCanonicalName(); try { Method m = enumClass.getMethod("values"); @@ -60,7 +62,7 @@ public class EnumType<T extends Enum<T>> implements ExtendedType { } public String getClassName() { - return enumClass.getName(); + return canonicalName; } public void setJdbcObject( http://git-wip-us.apache.org/repos/asf/cayenne/blob/33300f6d/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java ---------------------------------------------------------------------- diff --git a/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java b/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java index cb46ef1..4e95829 100644 --- a/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java +++ b/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java @@ -49,6 +49,7 @@ public class ExtendedTypeMap { classesForPrimitives.put("int", Integer.class.getName()); } + protected Map<String, String> typeAliases; protected final Map<String, ExtendedType> typeMap; protected ExtendedType defaultType; @@ -65,6 +66,7 @@ public class ExtendedTypeMap { public ExtendedTypeMap() { this.defaultType = new ObjectType(); this.typeMap = new ConcurrentHashMap<String, ExtendedType>(); + this.typeAliases = new ConcurrentHashMap<String, String>(classesForPrimitives); this.extendedTypeFactories = new CopyOnWriteArrayList<ExtendedTypeFactory>(); this.internalTypeFactories = new CopyOnWriteArrayList<ExtendedTypeFactory>(); @@ -161,10 +163,7 @@ public class ExtendedTypeMap { return getDefaultType(); } - String nonPrimitive = classesForPrimitives.get(javaClassName); - if (nonPrimitive != null) { - javaClassName = nonPrimitive; - } + javaClassName = canonicalizedTypeName(javaClassName); ExtendedType type = getExplictlyRegisteredType(javaClassName); @@ -280,4 +279,29 @@ public class ExtendedTypeMap { return null; } + + /** + * For the class name returns a name "canonicalized" for the purpose of + * ExtendedType lookup. + * + * @since 3.1.1 + */ + protected String canonicalizedTypeName(String className) { + + String canonicalized = typeAliases.get(className); + if (canonicalized == null) { + + int index = className.indexOf('$'); + if (index >= 0) { + canonicalized = className.replace('$', '.'); + } else { + canonicalized = className; + } + + typeAliases.put(className, canonicalized); + + } + + return canonicalized; + } } http://git-wip-us.apache.org/repos/asf/cayenne/blob/33300f6d/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/types/ExtendedTypeMapEnumsTest.java ---------------------------------------------------------------------- diff --git a/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/types/ExtendedTypeMapEnumsTest.java b/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/types/ExtendedTypeMapEnumsTest.java index bb32508..86ec350 100644 --- a/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/types/ExtendedTypeMapEnumsTest.java +++ b/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/types/ExtendedTypeMapEnumsTest.java @@ -19,6 +19,8 @@ package org.apache.cayenne.access.types; +import org.apache.cayenne.access.types.InnerEnumHolder.InnerEnum; + import junit.framework.TestCase; public class ExtendedTypeMapEnumsTest extends TestCase { @@ -47,13 +49,13 @@ public class ExtendedTypeMapEnumsTest extends TestCase { ExtendedType type1 = map.createType(InnerEnumHolder.class.getName() + "$InnerEnum"); assertNotNull(type1); - assertSame(type.getClassName(), type1.getClassName()); + assertEquals(type.getClassName(), type1.getClassName()); // use a string name with . ExtendedType type2 = map.createType(InnerEnumHolder.class.getName() + ".InnerEnum"); assertNotNull(type2); - assertSame(type.getClassName(), type2.getClassName()); + assertEquals(type.getClassName(), type2.getClassName()); } public void testGetDefaultType1_4() { @@ -71,4 +73,24 @@ public class ExtendedTypeMapEnumsTest extends TestCase { assertNotNull(type); assertTrue(type instanceof EnumType); } + + public void testGetRegisteredType_InnerEnum() { + ExtendedTypeMap map = new ExtendedTypeMap(); + assertEquals(0, map.extendedTypeFactories.size()); + + ExtendedType byType = map.getRegisteredType(InnerEnum.class); + + // this and subsequent tests verify that no memory leak occurs per + // CAY-2066 + assertEquals(1, map.extendedTypeFactories.size()); + + assertSame(byType, map.getRegisteredType(InnerEnum.class)); + assertEquals(1, map.extendedTypeFactories.size()); + + assertSame(byType, map.getRegisteredType(InnerEnumHolder.class.getName() + "$InnerEnum")); + assertEquals(1, map.extendedTypeFactories.size()); + + assertSame(byType, map.getRegisteredType(InnerEnumHolder.class.getName() + ".InnerEnum")); + assertEquals(1, map.extendedTypeFactories.size()); + } }