You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2013/08/03 17:06:44 UTC

svn commit: r1510006 - in /cayenne/main/trunk/framework/cayenne-core-unpublished/src: main/java/org/apache/cayenne/exp/parser/Evaluator.java test/java/org/apache/cayenne/exp/parser/EvaluatorTest.java

Author: aadamchik
Date: Sat Aug  3 15:06:44 2013
New Revision: 1510006

URL: http://svn.apache.org/r1510006
Log:
CAY-1860  In-memory matching of DataObjects against ObjectId or int

unit tests
better null handling
adding map comparison

Added:
    cayenne/main/trunk/framework/cayenne-core-unpublished/src/test/java/org/apache/cayenne/exp/parser/EvaluatorTest.java
Modified:
    cayenne/main/trunk/framework/cayenne-core-unpublished/src/main/java/org/apache/cayenne/exp/parser/Evaluator.java

Modified: cayenne/main/trunk/framework/cayenne-core-unpublished/src/main/java/org/apache/cayenne/exp/parser/Evaluator.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-core-unpublished/src/main/java/org/apache/cayenne/exp/parser/Evaluator.java?rev=1510006&r1=1510005&r2=1510006&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-core-unpublished/src/main/java/org/apache/cayenne/exp/parser/Evaluator.java (original)
+++ cayenne/main/trunk/framework/cayenne-core-unpublished/src/main/java/org/apache/cayenne/exp/parser/Evaluator.java Sat Aug  3 15:06:44 2013
@@ -19,6 +19,7 @@
 package org.apache.cayenne.exp.parser;
 
 import java.math.BigDecimal;
+import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
@@ -36,6 +37,7 @@ import org.apache.cayenne.util.Conversio
 abstract class Evaluator {
 
     private static final ConcurrentMap<Class<?>, Evaluator> evaluators;
+    private static final Evaluator NULL_LHS_EVALUATOR;
     private static final Evaluator DEFAULT_EVALUATOR;
     private static final Evaluator PERSISTENT_EVALUATOR;
     private static final Evaluator BIG_DECIMAL_EVALUATOR;
@@ -73,6 +75,19 @@ abstract class Evaluator {
 
     static {
         evaluators = new ConcurrentHashMap<Class<?>, Evaluator>();
+
+        NULL_LHS_EVALUATOR = new Evaluator() {
+            @Override
+            int compare(Object lhs, Object rhs) {
+                throw new UnsupportedOperationException("Unsupported");
+            }
+
+            @Override
+            boolean eq(Object lhs, Object rhs) {
+                return rhs == null;
+            }
+        };
+
         DEFAULT_EVALUATOR = new NullEvaluator(new Evaluator() {
             @Override
             boolean eq(Object lhs, Object rhs) {
@@ -102,11 +117,15 @@ abstract class Evaluator {
                 }
 
                 if (rhs instanceof ObjectId) {
-                    return lhsPersistent.getObjectId().equals((ObjectId) rhs);
+                    return lhsPersistent.getObjectId().equals(rhs);
+                }
+
+                if (rhs instanceof Map) {
+                    return lhsPersistent.getObjectId().getIdSnapshot().equals(rhs);
                 }
 
-                // comparing ObjectId with a single value ...
                 if (lhsPersistent.getObjectId().getIdSnapshot().size() != 1) {
+                    // the only options left below are for the single key IDs
                     return false;
                 }
 
@@ -161,7 +180,7 @@ abstract class Evaluator {
     static <T> Evaluator evaluator(Object lhs) {
 
         if (lhs == null) {
-            return DEFAULT_EVALUATOR;
+            return NULL_LHS_EVALUATOR;
         }
 
         Class<?> lhsType = lhs.getClass();

Added: cayenne/main/trunk/framework/cayenne-core-unpublished/src/test/java/org/apache/cayenne/exp/parser/EvaluatorTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-core-unpublished/src/test/java/org/apache/cayenne/exp/parser/EvaluatorTest.java?rev=1510006&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-core-unpublished/src/test/java/org/apache/cayenne/exp/parser/EvaluatorTest.java (added)
+++ cayenne/main/trunk/framework/cayenne-core-unpublished/src/test/java/org/apache/cayenne/exp/parser/EvaluatorTest.java Sat Aug  3 15:06:44 2013
@@ -0,0 +1,147 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.exp.parser;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cayenne.ObjectId;
+import org.apache.cayenne.Persistent;
+
+import junit.framework.TestCase;
+
+public class EvaluatorTest extends TestCase {
+
+    public void testEvaluator_Null() {
+        Evaluator e = Evaluator.evaluator(null);
+        assertNotNull(e);
+        assertTrue(e.eq(null, null));
+        assertFalse(e.eq(null, new Object()));
+    }
+
+    public void testEvaluator_Object() {
+        Object o = new Object();
+        Evaluator e = Evaluator.evaluator(o);
+        assertNotNull(e);
+        assertTrue(e.eq(o, o));
+        assertFalse(e.eq(o, null));
+    }
+
+    public void testEvaluator_BigDecimal() {
+        Object lhs = new BigDecimal("1.10");
+        Evaluator e = Evaluator.evaluator(lhs);
+        assertNotNull(e);
+        assertTrue(e.eq(lhs, new BigDecimal("1.1")));
+        assertFalse(e.eq(lhs, new BigDecimal("1.10001")));
+
+        assertEquals(-1, e.compare(lhs, new BigDecimal("1.10001")));
+    }
+
+    public void testEvaluator_Persistent() {
+
+        ObjectId lhsId = new ObjectId("X", "k", 3);
+        Persistent lhs = mock(Persistent.class);
+        when(lhs.getObjectId()).thenReturn(lhsId);
+
+        Evaluator e = Evaluator.evaluator(lhs);
+        assertNotNull(e);
+
+        ObjectId rhsId1 = new ObjectId("X", "k", 3);
+        Persistent rhs1 = mock(Persistent.class);
+        when(rhs1.getObjectId()).thenReturn(rhsId1);
+
+        assertTrue(e.eq(lhs, rhs1));
+        assertTrue(e.eq(lhs, rhsId1));
+        assertTrue(e.eq(lhs, 3));
+
+        ObjectId rhsId2 = new ObjectId("X", "k", 4);
+        Persistent rhs2 = mock(Persistent.class);
+        when(rhs2.getObjectId()).thenReturn(rhsId2);
+
+        assertFalse(e.eq(lhs, rhs2));
+        assertFalse(e.eq(lhs, rhsId2));
+        assertFalse(e.eq(lhs, 4));
+    }
+
+    public void testEvaluator_Persistent_StringId() {
+
+        ObjectId lhsId = new ObjectId("X", "k", "A");
+        Persistent lhs = mock(Persistent.class);
+        when(lhs.getObjectId()).thenReturn(lhsId);
+
+        Evaluator e = Evaluator.evaluator(lhs);
+        assertNotNull(e);
+
+        ObjectId rhsId1 = new ObjectId("X", "k", "A");
+        Persistent rhs1 = mock(Persistent.class);
+        when(rhs1.getObjectId()).thenReturn(rhsId1);
+
+        assertTrue(e.eq(lhs, rhs1));
+        assertTrue(e.eq(lhs, rhsId1));
+        assertTrue(e.eq(lhs, "A"));
+
+        ObjectId rhsId2 = new ObjectId("X", "k", "B");
+        Persistent rhs2 = mock(Persistent.class);
+        when(rhs2.getObjectId()).thenReturn(rhsId2);
+
+        assertFalse(e.eq(lhs, rhs2));
+        assertFalse(e.eq(lhs, rhsId2));
+        assertFalse(e.eq(lhs, "B"));
+    }
+
+    public void testEvaluator_Persistent_MultiKey() {
+
+        Map<String, Object> lhsIdMap = new HashMap<String, Object>();
+        lhsIdMap.put("a", 1);
+        lhsIdMap.put("b", "B");
+        ObjectId lhsId = new ObjectId("X", lhsIdMap);
+        Persistent lhs = mock(Persistent.class);
+        when(lhs.getObjectId()).thenReturn(lhsId);
+
+        Evaluator e = Evaluator.evaluator(lhs);
+        assertNotNull(e);
+
+        Map<String, Object> rhsId1Map = new HashMap<String, Object>();
+        rhsId1Map.put("a", 1);
+        rhsId1Map.put("b", "B");
+        ObjectId rhsId1 = new ObjectId("X", rhsId1Map);
+        Persistent rhs1 = mock(Persistent.class);
+        when(rhs1.getObjectId()).thenReturn(rhsId1);
+
+        assertTrue(e.eq(lhs, rhs1));
+        assertTrue(e.eq(lhs, rhsId1));
+        assertTrue(e.eq(lhs, rhsId1Map));
+
+        Map<String, Object> rhsId2Map = new HashMap<String, Object>();
+        rhsId2Map.put("a", 1);
+        rhsId2Map.put("b", "BX");
+        ObjectId rhsId2 = new ObjectId("X", rhsId2Map);
+        Persistent rhs2 = mock(Persistent.class);
+        when(rhs2.getObjectId()).thenReturn(rhsId2);
+
+        assertFalse(e.eq(lhs, rhs2));
+        assertFalse(e.eq(lhs, rhsId2));
+        assertFalse(e.eq(lhs, rhsId2Map));
+        assertFalse(e.eq(lhs, "B"));
+    }
+}