Repository: cayenne
Updated Branches:
  refs/heads/STABLE-4.0 4cd249778 -> ba750c5b2


CAY-2411 Wrong resolution of ExtendedType with ValueObjectType for inherited 
class
(cherry picked from commit fd0d06e)


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

Branch: refs/heads/STABLE-4.0
Commit: a16d7c435f86cb25c987d054704d8210ff855ae6
Parents: 4cd2497
Author: Nikita Timofeev <stari...@gmail.com>
Authored: Tue Feb 27 16:05:47 2018 +0300
Committer: Nikita Timofeev <stari...@gmail.com>
Committed: Tue Feb 27 17:14:47 2018 +0300

----------------------------------------------------------------------
 RELEASE-NOTES.txt                               |  1 +
 .../types/DefaultValueObjectTypeRegistry.java   | 45 ----------------
 .../cayenne/access/types/ExtendedTypeMap.java   |  3 --
 .../access/types/SubclassTypeFactory.java       |  3 ++
 .../DefaultValueObjectTypeRegistryTest.java     |  8 +--
 .../access/types/ExtendedTypeMapEnumsTest.java  | 11 ++--
 .../access/types/ExtendedTypeMapTest.java       |  2 +-
 .../types/ValueObjectTypeFactoryTest.java       | 55 +++++++++++++++++++-
 8 files changed, 68 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/a16d7c43/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 030b5f1..49863ba 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -27,6 +27,7 @@ CAY-2389 DbEntity qualifier with DbPath expression translates 
into wrong SQL
 CAY-2392 Modeler: Unable to remove DataNode
 CAY-2401 Modeler: NPE in ObjEntity sync action
 CAY-2405 Broken prefetch of entity with inheritance and attribute with custom 
java type
+CAY-2411 Wrong resolution of ExtendedType with ValueObjectType for inherited 
class
 
 ----------------------------------
 Release: 4.0.B2

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a16d7c43/cayenne-server/src/main/java/org/apache/cayenne/access/types/DefaultValueObjectTypeRegistry.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/types/DefaultValueObjectTypeRegistry.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/types/DefaultValueObjectTypeRegistry.java
index 3dda771..7943ee8 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/types/DefaultValueObjectTypeRegistry.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/access/types/DefaultValueObjectTypeRegistry.java
@@ -52,53 +52,8 @@ public class DefaultValueObjectTypeRegistry implements 
ValueObjectTypeRegistry {
     public <T> ValueObjectType<T, ?> getValueType(Class<? extends T> 
valueClass) {
         ValueObjectType type = typeCache.get(valueClass.getName());
         if(type == null) {
-            type = findBySuperclasses(valueClass);
-        } else if(type == NULL_DUMMY) {
             return null;
         }
         return type;
     }
-
-    protected ValueObjectType<?, ?> findBySuperclasses(final Class<?> 
baseClass) {
-        ValueObjectType<?,?> type = null;
-        Class<?> searchClass = baseClass.getSuperclass();
-
-        while(searchClass != null && !searchClass.equals(Object.class)) {
-            type = typeCache.get(searchClass.getName());
-            if(type != null) {
-                // cache it for faster search later
-                typeCache.put(baseClass.getName(), type);
-                break;
-            }
-            searchClass = searchClass.getSuperclass();
-        }
-        // as well cache null result
-        if(type == null) {
-            typeCache.put(baseClass.getName(), NULL_DUMMY);
-        }
-        return type;
-    }
-
-    private static final ValueObjectType<?, ?> NULL_DUMMY = new 
ValueObjectType() {
-        @Override
-        public Class<?> getTargetType() {
-            return null;
-        }
-        @Override
-        public Class<?> getValueType() {
-            return null;
-        }
-        @Override
-        public Object toJavaObject(Object value) {
-            return null;
-        }
-        @Override
-        public Object fromJavaObject(Object object) {
-            return null;
-        }
-        @Override
-        public String toCacheKey(Object object) {
-            return null;
-        }
-    };
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a16d7c43/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 8d3d31b..3caf3f8 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
@@ -128,9 +128,6 @@ public class ExtendedTypeMap {
         */
        public void registerType(ExtendedType type) {
                typeMap.put(type.getClassName(), type);
-
-               // factory to handle subclasses of type.className
-               addFactory(new SubclassTypeFactory(type));
        }
 
        /**

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a16d7c43/cayenne-server/src/main/java/org/apache/cayenne/access/types/SubclassTypeFactory.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/types/SubclassTypeFactory.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/types/SubclassTypeFactory.java
index 6938759..182d0c3 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/types/SubclassTypeFactory.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/access/types/SubclassTypeFactory.java
@@ -25,6 +25,9 @@ import org.apache.cayenne.util.Util;
  * of the className in the {@link ExtendedType}.
  * 
  * @since 3.0
+ * @deprecated since 4.1 it is unused, as this factory is faulty assuming that
+ *              we can freely interchange base class and it's subclasses.
+ *
  */
 class SubclassTypeFactory implements ExtendedTypeFactory {
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a16d7c43/cayenne-server/src/test/java/org/apache/cayenne/access/types/DefaultValueObjectTypeRegistryTest.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/access/types/DefaultValueObjectTypeRegistryTest.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/access/types/DefaultValueObjectTypeRegistryTest.java
index 28c7467..d761f34 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/access/types/DefaultValueObjectTypeRegistryTest.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/access/types/DefaultValueObjectTypeRegistryTest.java
@@ -69,14 +69,14 @@ public class DefaultValueObjectTypeRegistryTest {
         assertSame(valueObjectType1, valueObjectType);
 
         valueObjectType = registry.getValueType(Float.class);
-        assertSame(valueObjectType2, valueObjectType);
+        assertNull(valueObjectType);
 
         valueObjectType = registry.getValueType(String.class);
         assertNull(valueObjectType);
 
-        assertEquals(4, registry.typeCache.size());
-        assertTrue(registry.typeCache.containsKey(String.class.getName()));
-        assertTrue(registry.typeCache.containsKey(Float.class.getName()));
+        assertEquals(2, registry.typeCache.size());
+        assertFalse(registry.typeCache.containsKey(String.class.getName()));
+        assertFalse(registry.typeCache.containsKey(Float.class.getName()));
     }
 
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a16d7c43/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 21ac50b..b9e5b73 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
@@ -90,17 +90,16 @@ public class ExtendedTypeMapEnumsTest {
 
                ExtendedType byType = map.getRegisteredType(InnerEnum.class);
 
-               // this and subsequent tests verify that no memory leak occurs 
per
-               // CAY-2066
-               assertEquals(1, map.extendedTypeFactories.size());
+               // this and subsequent tests verify that no memory leak occurs 
per CAY-2066
+               assertEquals(0, map.extendedTypeFactories.size());
 
                assertSame(byType, map.getRegisteredType(InnerEnum.class));
-               assertEquals(1, map.extendedTypeFactories.size());
+               assertEquals(0, map.extendedTypeFactories.size());
 
                assertSame(byType, 
map.getRegisteredType(InnerEnumHolder.class.getName() + "$InnerEnum"));
-               assertEquals(1, map.extendedTypeFactories.size());
+               assertEquals(0, map.extendedTypeFactories.size());
 
                assertSame(byType, 
map.getRegisteredType(InnerEnumHolder.class.getName() + ".InnerEnum"));
-               assertEquals(1, map.extendedTypeFactories.size());
+               assertEquals(0, map.extendedTypeFactories.size());
        }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a16d7c43/cayenne-server/src/test/java/org/apache/cayenne/access/types/ExtendedTypeMapTest.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/access/types/ExtendedTypeMapTest.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/access/types/ExtendedTypeMapTest.java
index fc68377..769e715 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/access/types/ExtendedTypeMapTest.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/access/types/ExtendedTypeMapTest.java
@@ -55,7 +55,7 @@ public class ExtendedTypeMapTest {
         // List
         map.registerType(tstType1);
         assertSame(tstType1, map.getRegisteredType(List.class));
-        assertSame(tstType1, map.getRegisteredType(ArrayList.class));
+        assertNotSame(tstType1, map.getRegisteredType(ArrayList.class));
         
         map = new ExtendedTypeMap();
         

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a16d7c43/cayenne-server/src/test/java/org/apache/cayenne/access/types/ValueObjectTypeFactoryTest.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/access/types/ValueObjectTypeFactoryTest.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/access/types/ValueObjectTypeFactoryTest.java
index 293cf5f..8151a64 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/access/types/ValueObjectTypeFactoryTest.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/access/types/ValueObjectTypeFactoryTest.java
@@ -22,18 +22,21 @@ package org.apache.cayenne.access.types;
 import org.junit.Before;
 import org.junit.Test;
 
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
+import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 public class ValueObjectTypeFactoryTest {
 
-    ExtendedType tstType1, tstType2, tstType3, tstType4;
+    ExtendedType tstType1, tstType2, tstType3, tstType4, tstType5;
 
     ValueObjectTypeFactory factory;
 
@@ -44,6 +47,7 @@ public class ValueObjectTypeFactoryTest {
         list.add(createMockValueType(String.class, String.class));
         list.add(createMockValueType(int.class, int.class));
         list.add(createMockValueType(String[].class, String[].class));
+        list.add(createMockValueType(TestClass.class, BigDecimal.class));
 
         DefaultValueObjectTypeRegistry registry = new 
DefaultValueObjectTypeRegistry(list);
 
@@ -63,6 +67,9 @@ public class ValueObjectTypeFactoryTest {
         
when(tstType4.getClassName()).thenReturn(String[].class.getCanonicalName());
         extendedTypeMap.registerType(tstType4);
 
+        tstType5 = new MockExtendedType(BigDecimal.class);
+        extendedTypeMap.registerType(tstType5);
+
         factory = new ValueObjectTypeFactory(extendedTypeMap,registry);
     }
 
@@ -100,4 +107,50 @@ public class ValueObjectTypeFactoryTest {
         assertNotNull(converter4);
         assertSame(tstType4, converter4.extendedType);
     }
+
+    @Test
+    public void testInheritantType() {
+        ValueObjectTypeFactory.ExtendedTypeConverter converter5 = 
(ValueObjectTypeFactory.ExtendedTypeConverter) factory.getType(TestClass.class);
+        assertNotNull(converter5);
+        assertSame(tstType5, converter5.extendedType);
+    }
+
+    /**
+     * Test case for CAY-2411
+     */
+    @Test
+    public void testInheritantValueTypeOverExtendedType() {
+        // setup
+        ExtendedTypeMap map;
+        BigDecimalType bigDecimalType = new BigDecimalType();
+        ValueObjectType valueObjectType;
+        {
+            map = new ExtendedTypeMap();
+            map.registerType(bigDecimalType);
+
+            List<ValueObjectType<?, ?>> list = new ArrayList<>();
+            valueObjectType = mock(ValueObjectType.class);
+            when(valueObjectType.getValueType()).thenReturn(TestClass.class);
+            when(valueObjectType.getTargetType()).thenReturn(BigDecimal.class);
+            list.add(valueObjectType);
+
+            DefaultValueObjectTypeRegistry registry = new 
DefaultValueObjectTypeRegistry(list);
+            map.addFactory(new ValueObjectTypeFactory(map, registry));
+        }
+
+        // test
+        ExtendedType type1 = map.getRegisteredType(BigDecimal.class);
+        assertSame(bigDecimalType, type1);
+
+        ExtendedType type2 = map.getRegisteredType(TestClass.class);
+        assertThat(type2, 
instanceOf(ValueObjectTypeFactory.ExtendedTypeConverter.class));
+        assertSame(valueObjectType, 
((ValueObjectTypeFactory.ExtendedTypeConverter)type2).valueObjectType);
+    }
+
+    private class TestClass extends BigDecimal {
+
+        public TestClass(long val) {
+            super(val);
+        }
+    }
 }

Reply via email to