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 2015/05/23 12:48:32 UTC
cayenne git commit: unit test reorg by expression type ,
some cleanup and fixing warnings
Repository: cayenne
Updated Branches:
refs/heads/master 069b8fbb2 -> 5faca1c3a
unit test reorg by expression type , some cleanup and fixing warnings
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/5faca1c3
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/5faca1c3
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/5faca1c3
Branch: refs/heads/master
Commit: 5faca1c3a48e291022c6f7516b6d6afdf0d543db
Parents: 069b8fb
Author: aadamchik <aa...@apache.org>
Authored: Sat May 23 13:18:10 2015 +0300
Committer: aadamchik <aa...@apache.org>
Committed: Sat May 23 13:48:24 2015 +0300
----------------------------------------------------------------------
.../apache/cayenne/exp/parser/ASTDivide.java | 4 +-
.../org/apache/cayenne/exp/parser/ASTEqual.java | 252 ++++++++++---------
.../org/apache/cayenne/exp/parser/ASTFalse.java | 84 ++++---
.../apache/cayenne/exp/parser/ASTGreater.java | 84 ++++---
.../cayenne/exp/parser/ASTGreaterOrEqual.java | 86 +++----
.../org/apache/cayenne/exp/parser/ASTIn.java | 191 +++++++-------
.../org/apache/cayenne/exp/parser/ASTLess.java | 85 ++++---
.../cayenne/exp/parser/ASTLessOrEqual.java | 84 ++++---
.../apache/cayenne/exp/parser/ASTInTest.java | 73 ++++++
.../parser/ExpressionEvaluateInMemoryTest.java | 43 +---
10 files changed, 517 insertions(+), 469 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5faca1c3/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDivide.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDivide.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDivide.java
index 66b92a8..7e48b8c 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDivide.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTDivide.java
@@ -53,10 +53,10 @@ public class ASTDivide extends SimpleNode {
connectChildren();
}
- public ASTDivide(Collection nodes) {
+ public ASTDivide(Collection<?> nodes) {
super(ExpressionParserTreeConstants.JJTDIVIDE);
int len = nodes.size();
- Iterator it = nodes.iterator();
+ Iterator<?> it = nodes.iterator();
for (int i = 0; i < len; i++) {
jjtAddChild(wrapChild(it.next()), i);
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5faca1c3/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTEqual.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTEqual.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTEqual.java
index c6b6806..579545d 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTEqual.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTEqual.java
@@ -32,129 +32,131 @@ import org.apache.commons.logging.LogFactory;
* @since 1.1
*/
public class ASTEqual extends ConditionNode implements ValueInjector {
-
- private static final Log logObj = LogFactory.getLog(ASTEqual.class);
-
- /**
- * Constructor used by expression parser. Do not invoke directly.
- */
- ASTEqual(int id) {
- super(id);
- }
-
- public ASTEqual() {
- super(ExpressionParserTreeConstants.JJTEQUAL);
- }
-
- /**
- * Creates "Equal To" expression.
- */
- public ASTEqual(ASTPath path, Object value) {
- super(ExpressionParserTreeConstants.JJTEQUAL);
- jjtAddChild(path, 0);
- jjtAddChild(new ASTScalar(value), 1);
- connectChildren();
- }
-
- @Override
- protected Object evaluateNode(Object o) throws Exception {
- int len = jjtGetNumChildren();
- if (len != 2) {
- return Boolean.FALSE;
- }
-
- 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 true;
- } else if (o1 != null) {
-
- // 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 && Evaluator.evaluator(element).eq(element, o2)) {
- return true;
- }
- }
- return false;
- }
- if (o2 instanceof List && !(o1 instanceof List)) {
- for (Object element : ((List<?>) o2)) {
- if (element != null && Evaluator.evaluator(element).eq(element, o1)) {
- return true;
- }
- }
- return false;
- }
-
- return Evaluator.evaluator(o1).eq(o1, o2);
- }
- return false;
- }
-
- /**
- * Creates a copy of this expression node, without copying children.
- */
- @Override
- public Expression shallowCopy() {
- return new ASTEqual(id);
- }
-
- @Override
- protected String getExpressionOperator(int index) {
- return "=";
- }
-
- @Override
- protected String getEJBQLExpressionOperator(int index) {
- if (jjtGetChild(1) instanceof ASTScalar && ((ASTScalar) jjtGetChild(1)).getValue() == null) {
- // for ejbql, we need "is null" instead of "= null"
- return "is";
- }
- return getExpressionOperator(index);
- }
-
- @Override
- public int getType() {
- return Expression.EQUAL_TO;
- }
-
- public void injectValue(Object o) {
- // try to inject value, if one of the operands is scalar, and other is a
- // path
-
- Node[] args = new Node[] { jjtGetChild(0), jjtGetChild(1) };
-
- int scalarIndex = -1;
- if (args[0] instanceof ASTScalar) {
- scalarIndex = 0;
- } else if (args[1] instanceof ASTScalar) {
- scalarIndex = 1;
- }
-
- if (scalarIndex != -1 && args[1 - scalarIndex] instanceof ASTObjPath) {
- // inject
- ASTObjPath path = (ASTObjPath) args[1 - scalarIndex];
- try {
- path.injectValue(o, evaluateChild(scalarIndex, o));
- } catch (Exception ex) {
- logObj.warn("Failed to inject value " + " on path " + path.getPath() + " to " + o, ex);
- }
- }
- }
+
+ private static final long serialVersionUID = 1211234198602067833L;
+
+ private static final Log LOGGER = LogFactory.getLog(ASTEqual.class);
+
+ /**
+ * Constructor used by expression parser. Do not invoke directly.
+ */
+ ASTEqual(int id) {
+ super(id);
+ }
+
+ public ASTEqual() {
+ super(ExpressionParserTreeConstants.JJTEQUAL);
+ }
+
+ /**
+ * Creates "Equal To" expression.
+ */
+ public ASTEqual(ASTPath path, Object value) {
+ super(ExpressionParserTreeConstants.JJTEQUAL);
+ jjtAddChild(path, 0);
+ jjtAddChild(new ASTScalar(value), 1);
+ connectChildren();
+ }
+
+ @Override
+ protected Object evaluateNode(Object o) throws Exception {
+ int len = jjtGetNumChildren();
+ if (len != 2) {
+ return Boolean.FALSE;
+ }
+
+ 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 true;
+ } else if (o1 != null) {
+
+ // 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 && Evaluator.evaluator(element).eq(element, o2)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ if (o2 instanceof List && !(o1 instanceof List)) {
+ for (Object element : ((List<?>) o2)) {
+ if (element != null && Evaluator.evaluator(element).eq(element, o1)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ return Evaluator.evaluator(o1).eq(o1, o2);
+ }
+ return false;
+ }
+
+ /**
+ * Creates a copy of this expression node, without copying children.
+ */
+ @Override
+ public Expression shallowCopy() {
+ return new ASTEqual(id);
+ }
+
+ @Override
+ protected String getExpressionOperator(int index) {
+ return "=";
+ }
+
+ @Override
+ protected String getEJBQLExpressionOperator(int index) {
+ if (jjtGetChild(1) instanceof ASTScalar && ((ASTScalar) jjtGetChild(1)).getValue() == null) {
+ // for ejbql, we need "is null" instead of "= null"
+ return "is";
+ }
+ return getExpressionOperator(index);
+ }
+
+ @Override
+ public int getType() {
+ return Expression.EQUAL_TO;
+ }
+
+ public void injectValue(Object o) {
+ // try to inject value, if one of the operands is scalar, and other is a
+ // path
+
+ Node[] args = new Node[] { jjtGetChild(0), jjtGetChild(1) };
+
+ int scalarIndex = -1;
+ if (args[0] instanceof ASTScalar) {
+ scalarIndex = 0;
+ } else if (args[1] instanceof ASTScalar) {
+ scalarIndex = 1;
+ }
+
+ if (scalarIndex != -1 && args[1 - scalarIndex] instanceof ASTObjPath) {
+ // inject
+ ASTObjPath path = (ASTObjPath) args[1 - scalarIndex];
+ try {
+ path.injectValue(o, evaluateChild(scalarIndex, o));
+ } catch (Exception ex) {
+ LOGGER.warn("Failed to inject value " + " on path " + path.getPath() + " to " + o, ex);
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5faca1c3/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTFalse.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTFalse.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTFalse.java
index e59f9f9..a117cba 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTFalse.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTFalse.java
@@ -29,7 +29,7 @@ import org.apache.cayenne.exp.Expression;
* Notice that there is one ASTTrue and one ASTFalse instead of a ASTBoolean
* with a Boolean value. The main reason for doing this is that a common
* ASTBoolean will have operand count of 1 and that will default to a prepared
- * statmenet like " where ? and (...)", but we only need " where true and
+ * statement like " where ? and (...)", but we only need " where true and
* (...)".
*
* @see ASTTrue
@@ -37,51 +37,53 @@ import org.apache.cayenne.exp.Expression;
*/
public class ASTFalse extends ConditionNode {
- /**
- * Constructor used by expression parser. Do not invoke directly.
- */
- ASTFalse(int id) {
- super(id);
- }
+ private static final long serialVersionUID = -8441997825701749863L;
- public ASTFalse() {
- super(ExpressionParserTreeConstants.JJTFALSE);
- }
+ /**
+ * Constructor used by expression parser. Do not invoke directly.
+ */
+ ASTFalse(int id) {
+ super(id);
+ }
- @Override
- protected Object evaluateNode(Object o) throws Exception {
- return Boolean.FALSE;
- }
+ public ASTFalse() {
+ super(ExpressionParserTreeConstants.JJTFALSE);
+ }
- @Override
- protected String getExpressionOperator(int index) {
- throw new UnsupportedOperationException("No operator for '" + ExpressionParserTreeConstants.jjtNodeName[id]
- + "'");
- }
+ @Override
+ protected Object evaluateNode(Object o) throws Exception {
+ return Boolean.FALSE;
+ }
- @Override
- public Expression shallowCopy() {
- return new ASTFalse(id);
- }
+ @Override
+ protected String getExpressionOperator(int index) {
+ throw new UnsupportedOperationException("No operator for '" + ExpressionParserTreeConstants.jjtNodeName[id]
+ + "'");
+ }
- @Override
- public int getType() {
- return Expression.FALSE;
- }
+ @Override
+ public Expression shallowCopy() {
+ return new ASTFalse(id);
+ }
- /**
- * @since 4.0
- */
- @Override
- public void appendAsString(Appendable out) throws IOException {
- out.append("false");
- }
+ @Override
+ public int getType() {
+ return Expression.FALSE;
+ }
- /**
- * @since 4.0
- */
- @Override
- public void appendAsEJBQL(List<Object> parameterAccumulator, Appendable out, String rootId) throws IOException {
- out.append("false");
- }
+ /**
+ * @since 4.0
+ */
+ @Override
+ public void appendAsString(Appendable out) throws IOException {
+ out.append("false");
+ }
+
+ /**
+ * @since 4.0
+ */
+ @Override
+ public void appendAsEJBQL(List<Object> parameterAccumulator, Appendable out, String rootId) throws IOException {
+ out.append("false");
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5faca1c3/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTGreater.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTGreater.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTGreater.java
index 575eb2b..f990e24 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTGreater.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTGreater.java
@@ -26,53 +26,55 @@ import org.apache.cayenne.exp.Expression;
*/
public class ASTGreater extends ConditionNode {
- /**
- * Constructor used by expression parser. Do not invoke directly.
- */
- ASTGreater(int id) {
- super(id);
- }
+ private static final long serialVersionUID = 2796092142001150018L;
- public ASTGreater() {
- super(ExpressionParserTreeConstants.JJTGREATER);
- }
+ /**
+ * Constructor used by expression parser. Do not invoke directly.
+ */
+ ASTGreater(int id) {
+ super(id);
+ }
- public ASTGreater(ASTPath path, Object value) {
- super(ExpressionParserTreeConstants.JJTGREATER);
- jjtAddChild(path, 0);
- jjtAddChild(new ASTScalar(value), 1);
- connectChildren();
- }
+ public ASTGreater() {
+ super(ExpressionParserTreeConstants.JJTGREATER);
+ }
- @Override
- protected Object evaluateNode(Object o) throws Exception {
- int len = jjtGetNumChildren();
- if (len != 2) {
- return Boolean.FALSE;
- }
+ public ASTGreater(ASTPath path, Object value) {
+ super(ExpressionParserTreeConstants.JJTGREATER);
+ jjtAddChild(path, 0);
+ jjtAddChild(new ASTScalar(value), 1);
+ connectChildren();
+ }
- Object o1 = evaluateChild(0, o);
- Object o2 = evaluateChild(1, o);
- Integer c = Evaluator.evaluator(o1).compare(o1, o2);
+ @Override
+ protected Object evaluateNode(Object o) throws Exception {
+ int len = jjtGetNumChildren();
+ if (len != 2) {
+ return Boolean.FALSE;
+ }
- return c != null && c > 0 ? Boolean.TRUE : Boolean.FALSE;
- }
+ Object o1 = evaluateChild(0, o);
+ Object o2 = evaluateChild(1, o);
+ Integer c = Evaluator.evaluator(o1).compare(o1, o2);
- /**
- * Creates a copy of this expression node, without copying children.
- */
- @Override
- public Expression shallowCopy() {
- return new ASTGreater(id);
- }
+ return c != null && c > 0 ? Boolean.TRUE : Boolean.FALSE;
+ }
- @Override
- protected String getExpressionOperator(int index) {
- return ">";
- }
+ /**
+ * Creates a copy of this expression node, without copying children.
+ */
+ @Override
+ public Expression shallowCopy() {
+ return new ASTGreater(id);
+ }
- @Override
- public int getType() {
- return Expression.GREATER_THAN;
- }
+ @Override
+ protected String getExpressionOperator(int index) {
+ return ">";
+ }
+
+ @Override
+ public int getType() {
+ return Expression.GREATER_THAN;
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5faca1c3/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTGreaterOrEqual.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTGreaterOrEqual.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTGreaterOrEqual.java
index 36a6820..22d9e97 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTGreaterOrEqual.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTGreaterOrEqual.java
@@ -28,53 +28,55 @@ import org.apache.cayenne.exp.Expression;
*/
public class ASTGreaterOrEqual extends ConditionNode {
- /**
- * Constructor used by expression parser. Do not invoke directly.
- */
- ASTGreaterOrEqual(int id) {
- super(id);
- }
-
- public ASTGreaterOrEqual() {
- super(ExpressionParserTreeConstants.JJTGREATEROREQUAL);
- }
+ private static final long serialVersionUID = -2926530926896058935L;
- public ASTGreaterOrEqual(ASTPath path, Object value) {
- super(ExpressionParserTreeConstants.JJTGREATEROREQUAL);
- jjtAddChild(path, 0);
- jjtAddChild(new ASTScalar(value), 1);
- connectChildren();
- }
+ /**
+ * Constructor used by expression parser. Do not invoke directly.
+ */
+ ASTGreaterOrEqual(int id) {
+ super(id);
+ }
- @Override
- protected Object evaluateNode(Object o) throws Exception {
- int len = jjtGetNumChildren();
- if (len != 2) {
- return Boolean.FALSE;
- }
+ public ASTGreaterOrEqual() {
+ super(ExpressionParserTreeConstants.JJTGREATEROREQUAL);
+ }
- Object o1 = evaluateChild(0, o);
- Object o2 = evaluateChild(1, o);
- Integer c = Evaluator.evaluator(o1).compare(o1, o2);
+ public ASTGreaterOrEqual(ASTPath path, Object value) {
+ super(ExpressionParserTreeConstants.JJTGREATEROREQUAL);
+ jjtAddChild(path, 0);
+ jjtAddChild(new ASTScalar(value), 1);
+ connectChildren();
+ }
- return c != null && c >= 0 ? Boolean.TRUE : Boolean.FALSE;
- }
+ @Override
+ protected Object evaluateNode(Object o) throws Exception {
+ int len = jjtGetNumChildren();
+ if (len != 2) {
+ return Boolean.FALSE;
+ }
- /**
- * Creates a copy of this expression node, without copying children.
- */
- @Override
- public Expression shallowCopy() {
- return new ASTGreaterOrEqual(id);
- }
+ Object o1 = evaluateChild(0, o);
+ Object o2 = evaluateChild(1, o);
+ Integer c = Evaluator.evaluator(o1).compare(o1, o2);
- @Override
- protected String getExpressionOperator(int index) {
- return ">=";
- }
+ return c != null && c >= 0 ? Boolean.TRUE : Boolean.FALSE;
+ }
- @Override
- public int getType() {
- return Expression.GREATER_THAN_EQUAL_TO;
- }
+ /**
+ * Creates a copy of this expression node, without copying children.
+ */
+ @Override
+ public Expression shallowCopy() {
+ return new ASTGreaterOrEqual(id);
+ }
+
+ @Override
+ protected String getExpressionOperator(int index) {
+ return ">=";
+ }
+
+ @Override
+ public int getType() {
+ return Expression.GREATER_THAN_EQUAL_TO;
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5faca1c3/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTIn.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTIn.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTIn.java
index 1d29ef1..10d7dc7 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTIn.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTIn.java
@@ -30,99 +30,102 @@ import org.apache.commons.collections.Transformer;
*/
public class ASTIn extends ConditionNode {
- /**
- * Constructor used by expression parser. Do not invoke directly.
- */
- ASTIn(int id) {
- super(id);
- }
-
- public ASTIn() {
- super(ExpressionParserTreeConstants.JJTIN);
- }
-
- public ASTIn(ASTPath path, ASTList list) {
- super(ExpressionParserTreeConstants.JJTIN);
- jjtAddChild(path, 0);
- jjtAddChild(list, 1);
- connectChildren();
- }
-
- @Override
- protected Object evaluateNode(Object o) throws Exception {
- int len = jjtGetNumChildren();
- if (len != 2) {
- return Boolean.FALSE;
- }
-
- Object o1 = evaluateChild(0, o);
- // TODO: what if there's a NULL inside IN list?
- // e.g. ASTEqual evals as "NULL == NULL"
- if (o1 == null) {
- return Boolean.FALSE;
- }
-
- Object[] objects = (Object[]) evaluateChild(1, o);
- if (objects == null) {
- return Boolean.FALSE;
- }
-
- int size = objects.length;
- for (int i = 0; i < size; i++) {
- if (objects[i] != null) {
- if (o1 instanceof Collection) {
- // handle the case where we have a collection of objects
- for (Object obj : (Collection) o1) {
- if (Evaluator.evaluator(obj).eq(obj, objects[i])) {
- return Boolean.TRUE;
- }
- }
- } else {
- if (Evaluator.evaluator(o1).eq(o1, objects[i])) {
- return Boolean.TRUE;
- }
- }
- }
- }
-
- return Boolean.FALSE;
- }
-
- /**
- * Creates a copy of this expression node, without copying children.
- */
- @Override
- public Expression shallowCopy() {
- return new ASTIn(id);
- }
-
- @Override
- protected String getExpressionOperator(int index) {
- return "in";
- }
-
- @Override
- public int getType() {
- return Expression.IN;
- }
-
- @Override
- protected Object transformExpression(Transformer transformer) {
- Object transformed = super.transformExpression(transformer);
-
- // transform empty ASTIn to ASTFalse
- if (transformed instanceof ASTIn) {
- ASTIn exp = (ASTIn) transformed;
- if (exp.jjtGetNumChildren() == 2) {
- ASTList list = (ASTList) exp.jjtGetChild(1);
- Object[] objects = (Object[]) list.evaluate(null);
- if (objects.length == 0) {
- transformed = new ASTFalse();
- }
- }
- }
-
- return transformed;
- }
+ private static final long serialVersionUID = -211084571117172965L;
+
+ /**
+ * Constructor used by expression parser. Do not invoke directly.
+ */
+ ASTIn(int id) {
+ super(id);
+ }
+
+ public ASTIn() {
+ super(ExpressionParserTreeConstants.JJTIN);
+ }
+
+ public ASTIn(ASTPath path, ASTList list) {
+ super(ExpressionParserTreeConstants.JJTIN);
+ jjtAddChild(path, 0);
+ jjtAddChild(list, 1);
+ connectChildren();
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ protected Object evaluateNode(Object o) throws Exception {
+ int len = jjtGetNumChildren();
+ if (len != 2) {
+ return Boolean.FALSE;
+ }
+
+ Object o1 = evaluateChild(0, o);
+ // TODO: what if there's a NULL inside IN list?
+ // e.g. ASTEqual evals as "NULL == NULL"
+ if (o1 == null) {
+ return Boolean.FALSE;
+ }
+
+ Object[] objects = (Object[]) evaluateChild(1, o);
+ if (objects == null) {
+ return Boolean.FALSE;
+ }
+
+ int size = objects.length;
+ for (int i = 0; i < size; i++) {
+ if (objects[i] != null) {
+ if (o1 instanceof Collection) {
+ // handle the case where we have a collection of objects
+ for (Object obj : (Collection) o1) {
+ if (Evaluator.evaluator(obj).eq(obj, objects[i])) {
+ return Boolean.TRUE;
+ }
+ }
+ } else {
+ if (Evaluator.evaluator(o1).eq(o1, objects[i])) {
+ return Boolean.TRUE;
+ }
+ }
+ }
+ }
+
+ return Boolean.FALSE;
+ }
+
+ /**
+ * Creates a copy of this expression node, without copying children.
+ */
+ @Override
+ public Expression shallowCopy() {
+ return new ASTIn(id);
+ }
+
+ @Override
+ protected String getExpressionOperator(int index) {
+ return "in";
+ }
+
+ @Override
+ public int getType() {
+ return Expression.IN;
+ }
+
+ @Override
+ protected Object transformExpression(Transformer transformer) {
+ Object transformed = super.transformExpression(transformer);
+
+ // transform empty ASTIn to ASTFalse
+ if (transformed instanceof ASTIn) {
+ ASTIn exp = (ASTIn) transformed;
+ if (exp.jjtGetNumChildren() == 2) {
+ ASTList list = (ASTList) exp.jjtGetChild(1);
+ Object[] objects = (Object[]) list.evaluate(null);
+ if (objects.length == 0) {
+ transformed = new ASTFalse();
+ }
+ }
+ }
+
+ return transformed;
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5faca1c3/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLess.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLess.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLess.java
index 4494620..5a44f62 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLess.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLess.java
@@ -27,53 +27,56 @@ import org.apache.cayenne.exp.Expression;
* @since 1.1
*/
public class ASTLess extends ConditionNode {
- /**
- * Constructor used by expression parser. Do not invoke directly.
- */
- ASTLess(int id) {
- super(id);
- }
- public ASTLess() {
- super(ExpressionParserTreeConstants.JJTLESS);
- }
+ private static final long serialVersionUID = -3846841914847489596L;
- public ASTLess(ASTPath path, Object value) {
- super(ExpressionParserTreeConstants.JJTLESS);
- jjtAddChild(path, 0);
- jjtAddChild(new ASTScalar(value), 1);
- connectChildren();
- }
+ /**
+ * Constructor used by expression parser. Do not invoke directly.
+ */
+ ASTLess(int id) {
+ super(id);
+ }
- @Override
- protected Object evaluateNode(Object o) throws Exception {
- int len = jjtGetNumChildren();
- if (len != 2) {
- return Boolean.FALSE;
- }
+ public ASTLess() {
+ super(ExpressionParserTreeConstants.JJTLESS);
+ }
- Object o1 = evaluateChild(0, o);
- Object o2 = evaluateChild(1, o);
- Integer c = Evaluator.evaluator(o1).compare(o1, o2);
+ public ASTLess(ASTPath path, Object value) {
+ super(ExpressionParserTreeConstants.JJTLESS);
+ jjtAddChild(path, 0);
+ jjtAddChild(new ASTScalar(value), 1);
+ connectChildren();
+ }
- return c != null && c < 0 ? Boolean.TRUE : Boolean.FALSE;
- }
+ @Override
+ protected Object evaluateNode(Object o) throws Exception {
+ int len = jjtGetNumChildren();
+ if (len != 2) {
+ return Boolean.FALSE;
+ }
- /**
- * Creates a copy of this expression node, without copying children.
- */
- @Override
- public Expression shallowCopy() {
- return new ASTLess(id);
- }
+ Object o1 = evaluateChild(0, o);
+ Object o2 = evaluateChild(1, o);
+ Integer c = Evaluator.evaluator(o1).compare(o1, o2);
- @Override
- protected String getExpressionOperator(int index) {
- return "<";
- }
+ return c != null && c < 0 ? Boolean.TRUE : Boolean.FALSE;
+ }
- @Override
- public int getType() {
- return Expression.LESS_THAN;
- }
+ /**
+ * Creates a copy of this expression node, without copying children.
+ */
+ @Override
+ public Expression shallowCopy() {
+ return new ASTLess(id);
+ }
+
+ @Override
+ protected String getExpressionOperator(int index) {
+ return "<";
+ }
+
+ @Override
+ public int getType() {
+ return Expression.LESS_THAN;
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5faca1c3/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLessOrEqual.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLessOrEqual.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLessOrEqual.java
index 02fa9d0..9065631 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLessOrEqual.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ASTLessOrEqual.java
@@ -28,53 +28,55 @@ import org.apache.cayenne.exp.Expression;
*/
public class ASTLessOrEqual extends ConditionNode {
- /**
- * Constructor used by expression parser. Do not invoke directly.
- */
- ASTLessOrEqual(int id) {
- super(id);
- }
+ private static final long serialVersionUID = -710886570064202360L;
- public ASTLessOrEqual() {
- super(ExpressionParserTreeConstants.JJTLESSOREQUAL);
- }
+ /**
+ * Constructor used by expression parser. Do not invoke directly.
+ */
+ ASTLessOrEqual(int id) {
+ super(id);
+ }
- public ASTLessOrEqual(ASTPath path, Object value) {
- super(ExpressionParserTreeConstants.JJTLESSOREQUAL);
- jjtAddChild(path, 0);
- jjtAddChild(new ASTScalar(value), 1);
- connectChildren();
- }
+ public ASTLessOrEqual() {
+ super(ExpressionParserTreeConstants.JJTLESSOREQUAL);
+ }
- @Override
- protected Object evaluateNode(Object o) throws Exception {
- int len = jjtGetNumChildren();
- if (len != 2) {
- return Boolean.FALSE;
- }
+ public ASTLessOrEqual(ASTPath path, Object value) {
+ super(ExpressionParserTreeConstants.JJTLESSOREQUAL);
+ jjtAddChild(path, 0);
+ jjtAddChild(new ASTScalar(value), 1);
+ connectChildren();
+ }
- Object o1 = evaluateChild(0, o);
- Object o2 = evaluateChild(1, o);
- Integer c = Evaluator.evaluator(o1).compare(o1, o2);
+ @Override
+ protected Object evaluateNode(Object o) throws Exception {
+ int len = jjtGetNumChildren();
+ if (len != 2) {
+ return Boolean.FALSE;
+ }
- return c != null && c <= 0 ? Boolean.TRUE : Boolean.FALSE;
- }
+ Object o1 = evaluateChild(0, o);
+ Object o2 = evaluateChild(1, o);
+ Integer c = Evaluator.evaluator(o1).compare(o1, o2);
- /**
- * Creates a copy of this expression node, without copying children.
- */
- @Override
- public Expression shallowCopy() {
- return new ASTLessOrEqual(id);
- }
+ return c != null && c <= 0 ? Boolean.TRUE : Boolean.FALSE;
+ }
- @Override
- protected String getExpressionOperator(int index) {
- return "<=";
- }
+ /**
+ * Creates a copy of this expression node, without copying children.
+ */
+ @Override
+ public Expression shallowCopy() {
+ return new ASTLessOrEqual(id);
+ }
- @Override
- public int getType() {
- return Expression.LESS_THAN_EQUAL_TO;
- }
+ @Override
+ protected String getExpressionOperator(int index) {
+ return "<=";
+ }
+
+ @Override
+ public int getType() {
+ return Expression.LESS_THAN_EQUAL_TO;
+ }
}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5faca1c3/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTInTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTInTest.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTInTest.java
new file mode 100644
index 0000000..fc5edb4
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTInTest.java
@@ -0,0 +1,73 @@
+/*****************************************************************
+ * 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.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigDecimal;
+
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.testdo.testmap.Painting;
+import org.junit.Test;
+
+public class ASTInTest {
+
+ @Test
+ public void testEvaluate() {
+ Expression in = new ASTIn(new ASTObjPath("estimatedPrice"), new ASTList(new Object[] { new BigDecimal("10"),
+ new BigDecimal("20") }));
+
+ Expression notIn = new ASTNotIn(new ASTObjPath("estimatedPrice"), new ASTList(new Object[] {
+ new BigDecimal("10"), new BigDecimal("20") }));
+
+ Painting noMatch1 = new Painting();
+ noMatch1.setEstimatedPrice(new BigDecimal("21"));
+ assertFalse(in.match(noMatch1));
+ assertTrue(notIn.match(noMatch1));
+
+ Painting noMatch2 = new Painting();
+ noMatch2.setEstimatedPrice(new BigDecimal("11"));
+ assertFalse("Failed: " + in, in.match(noMatch2));
+ assertTrue("Failed: " + notIn, notIn.match(noMatch2));
+
+ Painting match1 = new Painting();
+ match1.setEstimatedPrice(new BigDecimal("20"));
+ assertTrue(in.match(match1));
+ assertFalse(notIn.match(match1));
+
+ Painting match2 = new Painting();
+ match2.setEstimatedPrice(new BigDecimal("10"));
+ assertTrue("Failed: " + in, in.match(match2));
+ assertFalse("Failed: " + notIn, notIn.match(match2));
+ }
+
+ @Test
+ public void testEvaluate_Null() {
+ Expression in = new ASTIn(new ASTObjPath("estimatedPrice"), new ASTList(new Object[] { new BigDecimal("10"),
+ new BigDecimal("20") }));
+ Expression notIn = new ASTNotIn(new ASTObjPath("estimatedPrice"), new ASTList(new Object[] {
+ new BigDecimal("10"), new BigDecimal("20") }));
+
+ Painting noMatch = new Painting();
+ assertFalse(in.match(noMatch));
+ assertFalse(notIn.match(noMatch));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/5faca1c3/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ExpressionEvaluateInMemoryTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ExpressionEvaluateInMemoryTest.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ExpressionEvaluateInMemoryTest.java
index 2eaf907..5cd107e 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ExpressionEvaluateInMemoryTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ExpressionEvaluateInMemoryTest.java
@@ -26,9 +26,9 @@ import java.math.BigDecimal;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.testdo.testmap.Artist;
-import org.apache.cayenne.testdo.testmap.Painting;
import org.junit.Test;
+// TODO: split it between AST* unit tests (partially done already)
public class ExpressionEvaluateInMemoryTest {
@Test
@@ -82,47 +82,6 @@ public class ExpressionEvaluateInMemoryTest {
}
@Test
- public void testEvaluateIN() {
- Expression in = new ASTIn(new ASTObjPath("estimatedPrice"), new ASTList(new Object[] { new BigDecimal("10"),
- new BigDecimal("20") }));
-
- Expression notIn = new ASTNotIn(new ASTObjPath("estimatedPrice"), new ASTList(new Object[] {
- new BigDecimal("10"), new BigDecimal("20") }));
-
- Painting noMatch1 = new Painting();
- noMatch1.setEstimatedPrice(new BigDecimal("21"));
- assertFalse(in.match(noMatch1));
- assertTrue(notIn.match(noMatch1));
-
- Painting noMatch2 = new Painting();
- noMatch2.setEstimatedPrice(new BigDecimal("11"));
- assertFalse("Failed: " + in, in.match(noMatch2));
- assertTrue("Failed: " + notIn, notIn.match(noMatch2));
-
- Painting match1 = new Painting();
- match1.setEstimatedPrice(new BigDecimal("20"));
- assertTrue(in.match(match1));
- assertFalse(notIn.match(match1));
-
- Painting match2 = new Painting();
- match2.setEstimatedPrice(new BigDecimal("10"));
- assertTrue("Failed: " + in, in.match(match2));
- assertFalse("Failed: " + notIn, notIn.match(match2));
- }
-
- @Test
- public void testEvaluateIN_Null() {
- Expression in = new ASTIn(new ASTObjPath("estimatedPrice"), new ASTList(new Object[] { new BigDecimal("10"),
- new BigDecimal("20") }));
- Expression notIn = new ASTNotIn(new ASTObjPath("estimatedPrice"), new ASTList(new Object[] {
- new BigDecimal("10"), new BigDecimal("20") }));
-
- Painting noMatch = new Painting();
- assertFalse(in.match(noMatch));
- assertFalse(notIn.match(noMatch));
- }
-
- @Test
public void testEvaluateADD() {
Expression add = new ASTAdd(new Object[] { new Integer(1), new Double(5.5) });
assertEquals(6.5, ((Number) add.evaluate(null)).doubleValue(), 0.0001);