Author: andrey
Date: Mon Jun 15 07:08:08 2009
New Revision: 784672
URL: http://svn.apache.org/viewvc?rev=784672&view=rev
Log:
CAY-419 Collections aren't supported with in-memory filtering
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTEqual.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTIn.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTNotEqual.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTNotIn.java
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/exp/ExpressionFactoryTest.java
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTEqual.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTEqual.java?rev=784672&r1=784671&r2=784672&view=diff
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTEqual.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTEqual.java
Mon Jun 15 07:08:08 2009
@@ -20,6 +20,7 @@
package org.apache.cayenne.exp.parser;
import java.math.BigDecimal;
+import java.util.List;
import org.apache.cayenne.exp.Expression;
@@ -60,31 +61,62 @@
Object o1 = evaluateChild(0, o);
Object o2 = evaluateChild(1, o);
+ return evaluateImpl(o1, o2);
+ }
+
+ /**
+ * Compares two objects, if one of them is array, 'in' operation is
performed
+ */
+ static boolean evaluateImpl(Object o1, Object o2) {
// TODO: maybe we need a comparison "strategy" here, instead of
// a switch of all possible cases? ... there were other requests for
// more relaxed type-unsafe comparison (e.g. numbers to strings)
-
+
if (o1 == null && o2 == null) {
- return Boolean.TRUE;
+ return true;
}
else if (o1 != null) {
- // BigDecimals must be compared using compareTo (
- // see CAY-280 and BigDecimal.equals JavaDoc)
- if (o1 instanceof BigDecimal) {
- if (o2 instanceof BigDecimal) {
- return ((BigDecimal) o1).compareTo((BigDecimal) o2) == 0
- ? Boolean.TRUE
- : Boolean.FALSE;
+ /**
+ * Per CAY-419 we perform 'in' comparison if one object is a list,
+ * and other is not
+ */
+ if (o1 instanceof List && !(o2 instanceof List)) {
+ for (Object element : ((List<?>) o1)) {
+ if (element != null && evaluateAtomic(element, o2)) {
+ return true;
+ }
}
-
- return Boolean.FALSE;
+ return false;
}
-
- return o1.equals(o2) ? Boolean.TRUE : Boolean.FALSE;
+ if (o2 instanceof List && !(o1 instanceof List)) {
+ for (Object element : ((List<?>) o2)) {
+ if (element != null && evaluateAtomic(element, o1)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ return evaluateAtomic(o1, o2);
}
- else {
- return Boolean.FALSE;
+ return false;
+ }
+
+ /**
+ * Compares two objects. They must not be null
+ */
+ static boolean evaluateAtomic(Object o1, Object o2) {
+ // BigDecimals must be compared using compareTo (
+ // see CAY-280 and BigDecimal.equals JavaDoc)
+ if (o1 instanceof BigDecimal) {
+ if (o2 instanceof BigDecimal) {
+ return ((BigDecimal) o1).compareTo((BigDecimal) o2) == 0;
+ }
+
+ return false;
}
+
+ return o1.equals(o2);
}
/**
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTIn.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTIn.java?rev=784672&r1=784671&r2=784672&view=diff
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTIn.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTIn.java
Mon Jun 15 07:08:08 2009
@@ -65,7 +65,7 @@
int size = objects.length;
for (int i = 0; i < size; i++) {
- if (o1.equals(objects[i])) {
+ if (objects[i] != null && ASTEqual.evaluateAtomic(o1, objects[i]))
{
return Boolean.TRUE;
}
}
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTNotEqual.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTNotEqual.java?rev=784672&r1=784671&r2=784672&view=diff
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTNotEqual.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTNotEqual.java
Mon Jun 15 07:08:08 2009
@@ -21,7 +21,6 @@
package org.apache.cayenne.exp.parser;
import org.apache.cayenne.exp.Expression;
-import org.apache.cayenne.util.Util;
/**
* "Not equal to" expression.
@@ -55,7 +54,7 @@
Object o1 = evaluateChild(0, o);
Object o2 = evaluateChild(1, o);
- return Util.nullSafeEquals(o1, o2) ? Boolean.FALSE : Boolean.TRUE;
+ return !ASTEqual.evaluateImpl(o1, o2);
}
/**
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTNotIn.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTNotIn.java?rev=784672&r1=784671&r2=784672&view=diff
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTNotIn.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/parser/ASTNotIn.java
Mon Jun 15 07:08:08 2009
@@ -62,7 +62,7 @@
int size = objects.length;
for (int i = 0; i < size; i++) {
- if (o1.equals(objects[i])) {
+ if (objects[i] != null && ASTEqual.evaluateAtomic(o1, objects[i]))
{
return Boolean.FALSE;
}
}
Modified:
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/exp/ExpressionFactoryTest.java
URL:
http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/exp/ExpressionFactoryTest.java?rev=784672&r1=784671&r2=784672&view=diff
==============================================================================
---
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/exp/ExpressionFactoryTest.java
(original)
+++
cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/exp/ExpressionFactoryTest.java
Mon Jun 15 07:08:08 2009
@@ -22,9 +22,12 @@
import java.util.ArrayList;
import java.util.List;
-import junit.framework.TestCase;
+import org.apache.art.Artist;
+import org.apache.art.Painting;
+import org.apache.cayenne.ObjectContext;
+import org.apache.cayenne.unit.CayenneCase;
-public class ExpressionFactoryTest extends TestCase {
+public class ExpressionFactoryTest extends CayenneCase {
// non-existent type
private static final int badType = -50;
@@ -215,4 +218,30 @@
assertEquals(Expression.OBJ_PATH, path.getType());
assertNull(exp.getOperand(1));
}
+
+ //CAY-416
+ public void testCollectionMatch() {
+ ObjectContext dc = createDataContext();
+ Artist artist = dc.newObject(Artist.class);
+ Painting p1 = dc.newObject(Painting.class), p2 =
dc.newObject(Painting.class),
+ p3 = dc.newObject(Painting.class);
+ p1.setPaintingTitle("p1");
+ p2.setPaintingTitle("p2");
+ p3.setPaintingTitle("p3");
+ artist.addToPaintingArray(p1);
+ artist.addToPaintingArray(p2);
+
+ assertTrue(ExpressionFactory.matchExp("paintingArray",
p1).match(artist));
+ assertFalse(ExpressionFactory.matchExp("paintingArray",
p3).match(artist));
+ assertFalse(ExpressionFactory.noMatchExp("paintingArray",
p1).match(artist));
+ assertTrue(ExpressionFactory.noMatchExp("paintingArray",
p3).match(artist));
+
+ assertTrue(ExpressionFactory.matchExp("paintingArray.paintingTitle",
"p1").match(artist));
+ assertFalse(ExpressionFactory.matchExp("paintingArray.paintingTitle",
"p3").match(artist));
+
assertFalse(ExpressionFactory.noMatchExp("paintingArray.paintingTitle",
"p1").match(artist));
+ assertTrue(ExpressionFactory.noMatchExp("paintingArray.paintingTitle",
"p3").match(artist));
+
+ assertTrue(ExpressionFactory.inExp("paintingTitle", "p1").match(p1));
+ assertFalse(ExpressionFactory.notInExp("paintingTitle",
"p3").match(p3));
+ }
}