Repository: cayenne
Updated Branches:
  refs/heads/master 6ad05a090 -> 0e0da8064


CAY-2066 Fixes for inner enums handling in ExtendedTypeMap

 * unit test that demonstrates the problem
 * a fix that canonicalizes class names used in the map

    this closes PR #90

commit 6d40a72f0158757146ccdbf64bbf6f32b5df53e8
Author: Andrus Adamchik <and...@objectstyle.com>
Date:   Sat Mar 5 04:17:58 2016 -0800

    ExtendedTypeMap unit test cleanup


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/0e0da806
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/0e0da806
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/0e0da806

Branch: refs/heads/master
Commit: 0e0da8064cde5499b48858bf9b47dc5169f5782c
Parents: 6ad05a0
Author: Andrus Adamchik <and...@objectstyle.com>
Authored: Sat Mar 5 16:07:27 2016 -0800
Committer: Andrus Adamchik <and...@objectstyle.com>
Committed: Sat Mar 5 16:07:27 2016 -0800

----------------------------------------------------------------------
 .../apache/cayenne/access/types/EnumType.java   |   4 +-
 .../cayenne/access/types/ExtendedTypeMap.java   |  33 ++++-
 .../access/types/ExtendedTypeMapEnumsTest.java  | 129 +++++++++++--------
 docs/doc/src/main/resources/RELEASE-NOTES.txt   |   1 +
 4 files changed, 107 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e0da806/cayenne-server/src/main/java/org/apache/cayenne/access/types/EnumType.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/types/EnumType.java 
b/cayenne-server/src/main/java/org/apache/cayenne/access/types/EnumType.java
index 55cc89e..1261a26 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/types/EnumType.java
+++ b/cayenne-server/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");
@@ -61,7 +63,7 @@ public class EnumType<T extends Enum<T>> implements 
ExtendedType {
 
     @Override
     public String getClassName() {
-        return enumClass.getName();
+        return canonicalName;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e0da806/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java
index 08c51db..387fe77 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/types/ExtendedTypeMap.java
+++ 
b/cayenne-server/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;
 
@@ -67,6 +68,7 @@ public class ExtendedTypeMap {
        public ExtendedTypeMap() {
                this.defaultType = new ObjectType();
                this.typeMap = new ConcurrentHashMap<>();
+               this.typeAliases = new 
ConcurrentHashMap<>(classesForPrimitives);
                this.extendedTypeFactories = new CopyOnWriteArrayList<>();
                this.internalTypeFactories = new CopyOnWriteArrayList<>();
 
@@ -168,13 +170,9 @@ public class ExtendedTypeMap {
                        return getDefaultType();
                }
 
-               String nonPrimitive = classesForPrimitives.get(javaClassName);
-               if (nonPrimitive != null) {
-                       javaClassName = nonPrimitive;
-               }
+               javaClassName = canonicalizedTypeName(javaClassName);
 
                ExtendedType type = getExplictlyRegisteredType(javaClassName);
-
                if (type != null) {
                        return type;
                }
@@ -276,4 +274,29 @@ public class ExtendedTypeMap {
 
                return null;
        }
+       
+       /**
+        * For the class name returns a name "canonicalized" for the purpose of
+        * ExtendedType lookup.
+        * 
+        * @since 4.0
+        */
+       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/0e0da806/cayenne-server/src/test/java/org/apache/cayenne/access/types/ExtendedTypeMapEnumsTest.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/access/types/ExtendedTypeMapEnumsTest.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/access/types/ExtendedTypeMapEnumsTest.java
index 37b8afc..21ac50b 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/access/types/ExtendedTypeMapEnumsTest.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/access/types/ExtendedTypeMapEnumsTest.java
@@ -19,8 +19,6 @@
 
 package org.apache.cayenne.access.types;
 
-import org.junit.Test;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNotSame;
@@ -28,58 +26,81 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
+import org.apache.cayenne.access.types.InnerEnumHolder.InnerEnum;
+import org.junit.Before;
+import org.junit.Test;
+
 public class ExtendedTypeMapEnumsTest {
 
-    @Test
-    public void testCreateType1_5() {
-        ExtendedTypeMap map = new ExtendedTypeMap();
-
-        assertNull(map.createType(Object.class.getName()));
-
-        ExtendedType type = map.createType(MockEnum.class.getName());
-        assertTrue(type instanceof EnumType);
-        assertEquals(MockEnum.class, ((EnumType) type).enumClass);
-
-        ExtendedType type2 = map.createType(MockEnum2.class.getName());
-        assertNotSame(type, type2);
-    }
-
-    @Test
-    public void testCreateType1_5InnerEnum() {
-        ExtendedTypeMap map = new ExtendedTypeMap();
-
-        ExtendedType type = 
map.createType(InnerEnumHolder.InnerEnum.class.getName());
-        assertTrue(type instanceof EnumType);
-        assertEquals(InnerEnumHolder.InnerEnum.class, ((EnumType) 
type).enumClass);
-
-        // use a string name with $
-        ExtendedType type1 = map.createType(InnerEnumHolder.class.getName()
-                + "$InnerEnum");
-        assertNotNull(type1);
-        assertSame(type.getClassName(), type1.getClassName());
-
-        // use a string name with .
-        ExtendedType type2 = map.createType(InnerEnumHolder.class.getName()
-                + ".InnerEnum");
-        assertNotNull(type2);
-        assertSame(type.getClassName(), type2.getClassName());
-    }
-
-    @Test
-    public void testGetDefaultType1_4() {
-        ExtendedTypeMap map = new ExtendedTypeMap();
-        map.internalTypeFactories.clear();
-
-        assertNull(map.createType(Object.class.getName()));
-        assertNull(map.createType(MockEnum.class.getName()));
-        assertNull(map.createType(MockEnum2.class.getName()));
-    }
-
-    @Test
-    public void testGetType() {
-        ExtendedTypeMap map = new ExtendedTypeMap();
-        ExtendedType type = map.getRegisteredType(MockEnum.class.getName());
-        assertNotNull(type);
-        assertTrue(type instanceof EnumType);
-    }
+       private ExtendedTypeMap map;
+
+       @Before
+       public void before() {
+               this.map = new ExtendedTypeMap();
+       }
+
+       @Test
+       public void testCreateType_NoFactory() {
+               assertNull(map.createType(Object.class.getName()));
+       }
+
+       @Test
+       public void testCreateType_Enum() {
+
+               ExtendedType type1 = map.createType(MockEnum.class.getName());
+               assertTrue(type1 instanceof EnumType);
+               assertEquals(MockEnum.class, ((EnumType<?>) type1).enumClass);
+
+               ExtendedType type2 = map.createType(MockEnum2.class.getName());
+               assertNotSame(type1, type2);
+       }
+
+       @Test
+       public void testCreateType_InnerEnum() {
+
+               ExtendedType type = 
map.createType(InnerEnumHolder.InnerEnum.class.getName());
+               assertTrue(type instanceof EnumType);
+               assertEquals(InnerEnumHolder.InnerEnum.class, ((EnumType<?>) 
type).enumClass);
+
+               // use a string name with $
+               ExtendedType type1 = 
map.createType(InnerEnumHolder.class.getName() + "$InnerEnum");
+               assertNotNull(type1);
+               assertEquals(type.getClassName(), type1.getClassName());
+
+               // use a string name with .
+               ExtendedType type2 = 
map.createType(InnerEnumHolder.class.getName() + ".InnerEnum");
+               assertNotNull(type2);
+               assertEquals(type.getClassName(), type2.getClassName());
+       }
+
+       @Test
+       public void testGetRegisteredType() {
+               ExtendedType type = map.getRegisteredType(MockEnum.class);
+               assertNotNull(type);
+               assertTrue(type instanceof EnumType);
+
+               assertSame(type, map.getRegisteredType(MockEnum.class));
+               assertSame(type, 
map.getRegisteredType(MockEnum.class.getName()));
+       }
+
+       @Test
+       public void testGetRegisteredType_InnerEnum() {
+
+               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());
+       }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/0e0da806/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 e1118b2..c595659 100644
--- a/docs/doc/src/main/resources/RELEASE-NOTES.txt
+++ b/docs/doc/src/main/resources/RELEASE-NOTES.txt
@@ -23,6 +23,7 @@ CAY-2065 Pluggable serialization and connectivity layers for 
ROP
 Bug Fixes:
 
 CAY-2064 Issue with BeanAccessor for classes with complex inheritance
+CAY-2066 Fixes for inner enums handling in ExtendedTypeMap
 
 ----------------------------------
 Release: 4.0.M3

Reply via email to