You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by pr...@apache.org on 2003/06/22 21:43:01 UTC
cvs commit: jakarta-commons/jexl/src/test/org/apache/commons/jexl JexlTest.java
proyal 2003/06/22 12:43:01
Modified: jexl/src/java/org/apache/commons/jexl/parser ASTGENode.java
ASTGTNode.java ASTLENode.java ASTLTNode.java
jexl/src/java/org/apache/commons/jexl/util Coercion.java
jexl/src/test/org/apache/commons/jexl JexlTest.java
Log:
Fix 20728 - Implement JSTL-compliant parameter coercion for LT/GT/LE/GE expressions
Revision Changes Path
1.2 +46 -6 jakarta-commons/jexl/src/java/org/apache/commons/jexl/parser/ASTGENode.java
Index: ASTGENode.java
===================================================================
RCS file: /home/cvs/jakarta-commons/jexl/src/java/org/apache/commons/jexl/parser/ASTGENode.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ASTGENode.java 26 Apr 2002 04:23:14 -0000 1.1
+++ ASTGENode.java 22 Jun 2003 19:43:01 -0000 1.2
@@ -54,11 +54,15 @@
package org.apache.commons.jexl.parser;
import org.apache.commons.jexl.JexlContext;
+import org.apache.commons.jexl.util.Coercion;
/**
* GE : a >= b
*
+ * Follows A.3.6.1 of the JSTL 1.0 specification
+ *
* @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
+ * @author <a href="mailto:proyal@apache.org">Peter Royal</a>
* @version $Id$
*/
public class ASTGENode extends SimpleNode
@@ -90,16 +94,52 @@
Object left = ( (SimpleNode) jjtGetChild(0)).value(jc);
Object right = ( (SimpleNode) jjtGetChild(1)).value(jc);
- if ((left==null) || (right==null))
+ if( left == right )
+ {
+ return Boolean.TRUE;
+ }
+ else if ( ( left == null ) || ( right == null ) )
{
- throw new Exception("Null comparison : GE ");
+ return Boolean.FALSE;
+ }
+ else if( Coercion.isFloatingPoint( left ) || Coercion.isFloatingPoint( right ) )
+ {
+ double leftDouble = Coercion.coerceDouble( left ).doubleValue();
+ double rightDouble = Coercion.coerceDouble( right ).doubleValue();
+
+ return leftDouble >= rightDouble
+ ? Boolean.TRUE
+ : Boolean.FALSE;
}
+ else if( Coercion.isNumberable( left ) || Coercion.isNumberable( right ) )
+ {
+ long leftLong = Coercion.coerceLong( left ).longValue();
+ long rightLong = Coercion.coerceLong( right ).longValue();
- if (left instanceof Integer && right instanceof Integer)
+ return leftLong >= rightLong
+ ? Boolean.TRUE
+ : Boolean.FALSE;
+ }
+ else if( left instanceof String || right instanceof String )
{
- int val = ((Integer) left).compareTo((Integer)right);
+ String leftString = left.toString();
+ String rightString = right.toString();
- return new Boolean(val >= 0);
+ return leftString.compareTo( rightString ) >= 0
+ ? Boolean.TRUE
+ : Boolean.FALSE;
+ }
+ else if( left instanceof Comparable )
+ {
+ return ( (Comparable)left ).compareTo( right ) >= 0
+ ? Boolean.TRUE
+ : Boolean.FALSE;
+ }
+ else if( right instanceof Comparable )
+ {
+ return ( (Comparable)right ).compareTo( left ) <= 0
+ ? Boolean.TRUE
+ : Boolean.FALSE;
}
throw new Exception("Invalid comparison : GE ");
1.3 +52 -21 jakarta-commons/jexl/src/java/org/apache/commons/jexl/parser/ASTGTNode.java
Index: ASTGTNode.java
===================================================================
RCS file: /home/cvs/jakarta-commons/jexl/src/java/org/apache/commons/jexl/parser/ASTGTNode.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ASTGTNode.java 6 Mar 2003 21:34:32 -0000 1.2
+++ ASTGTNode.java 22 Jun 2003 19:43:01 -0000 1.3
@@ -54,58 +54,89 @@
package org.apache.commons.jexl.parser;
import org.apache.commons.jexl.JexlContext;
+import org.apache.commons.jexl.util.Coercion;
/**
* GT : a > b
*
+ * Follows A.3.6.1 of the JSTL 1.0 specification
+ *
* @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
+ * @author <a href="mailto:proyal@apache.org">Peter Royal</a>
* @version $Id$
*/
public class ASTGTNode extends SimpleNode
{
- public ASTGTNode(int id)
+ public ASTGTNode( int id )
{
- super(id);
+ super( id );
}
- public ASTGTNode(Parser p, int id)
+ public ASTGTNode( Parser p, int id )
{
- super(p, id);
+ super( p, id );
}
/** Accept the visitor. **/
- public Object jjtAccept(ParserVisitor visitor, Object data)
+ public Object jjtAccept( ParserVisitor visitor, Object data )
{
- return visitor.visit(this, data);
+ return visitor.visit( this, data );
}
- public Object value(JexlContext jc)
+ public Object value( JexlContext jc )
throws Exception
{
/*
* now get the values
*/
- Object left = ( (SimpleNode) jjtGetChild(0)).value(jc);
- Object right = ( (SimpleNode) jjtGetChild(1)).value(jc);
+ Object left = ( (SimpleNode)jjtGetChild( 0 ) ).value( jc );
+ Object right = ( (SimpleNode)jjtGetChild( 1 ) ).value( jc );
- if ((left==null) || (right==null))
+ if( ( left == right ) || ( left == null ) || ( right == null ) )
{
- throw new Exception("Null comparison : GT ");
+ return Boolean.FALSE;
}
+ else if( Coercion.isFloatingPoint( left ) || Coercion.isFloatingPoint( right ) )
+ {
+ double leftDouble = Coercion.coerceDouble( left ).doubleValue();
+ double rightDouble = Coercion.coerceDouble( right ).doubleValue();
- if ( (left instanceof Integer || left instanceof Long)
- && (right instanceof Integer || right instanceof Long) )
+ return leftDouble > rightDouble
+ ? Boolean.TRUE
+ : Boolean.FALSE;
+ }
+ else if( Coercion.isNumberable( left ) || Coercion.isNumberable( right ) )
{
- long leftLong = ((Number)left).longValue();
- long rightLong = ((Number)right).longValue();
+ long leftLong = Coercion.coerceLong( left ).longValue();
+ long rightLong = Coercion.coerceLong( right ).longValue();
- return ( ( leftLong > rightLong )
- ? Boolean.TRUE
- : Boolean.FALSE );
+ return leftLong > rightLong
+ ? Boolean.TRUE
+ : Boolean.FALSE;
}
+ else if( left instanceof String || right instanceof String )
+ {
+ String leftString = left.toString();
+ String rightString = right.toString();
- throw new Exception("Invalid comparison : GT ");
- }
+ return leftString.compareTo( rightString ) > 0
+ ? Boolean.TRUE
+ : Boolean.FALSE;
+ }
+ else if( left instanceof Comparable )
+ {
+ return ( (Comparable)left ).compareTo( right ) > 0
+ ? Boolean.TRUE
+ : Boolean.FALSE;
+ }
+ else if( right instanceof Comparable )
+ {
+ return ( (Comparable)right ).compareTo( left ) < 0
+ ? Boolean.TRUE
+ : Boolean.FALSE;
+ }
+ throw new Exception( "Invalid comparison : GT " );
+ }
}
1.2 +46 -6 jakarta-commons/jexl/src/java/org/apache/commons/jexl/parser/ASTLENode.java
Index: ASTLENode.java
===================================================================
RCS file: /home/cvs/jakarta-commons/jexl/src/java/org/apache/commons/jexl/parser/ASTLENode.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ASTLENode.java 26 Apr 2002 04:23:14 -0000 1.1
+++ ASTLENode.java 22 Jun 2003 19:43:01 -0000 1.2
@@ -54,11 +54,15 @@
package org.apache.commons.jexl.parser;
import org.apache.commons.jexl.JexlContext;
+import org.apache.commons.jexl.util.Coercion;
/**
* LE : a <= b
*
+ * Follows A.3.6.1 of the JSTL 1.0 specification
+ *
* @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
+ * @author <a href="mailto:proyal@apache.org">Peter Royal</a>
* @version $Id$
*/
public class ASTLENode extends SimpleNode
@@ -89,16 +93,52 @@
Object left = ( (SimpleNode) jjtGetChild(0)).value(jc);
Object right = ( (SimpleNode) jjtGetChild(1)).value(jc);
- if ((left==null) || (right==null))
+ if( left == right )
+ {
+ return Boolean.TRUE;
+ }
+ else if ( ( left == null ) || ( right == null ) )
{
- throw new Exception("Null comparison : LE ");
+ return Boolean.FALSE;
+ }
+ else if( Coercion.isFloatingPoint( left ) || Coercion.isFloatingPoint( right ) )
+ {
+ double leftDouble = Coercion.coerceDouble( left ).doubleValue();
+ double rightDouble = Coercion.coerceDouble( right ).doubleValue();
+
+ return leftDouble <= rightDouble
+ ? Boolean.TRUE
+ : Boolean.FALSE;
}
+ else if( Coercion.isNumberable( left ) || Coercion.isNumberable( right ) )
+ {
+ long leftLong = Coercion.coerceLong( left ).longValue();
+ long rightLong = Coercion.coerceLong( right ).longValue();
- if (left instanceof Integer && right instanceof Integer)
+ return leftLong <= rightLong
+ ? Boolean.TRUE
+ : Boolean.FALSE;
+ }
+ else if( left instanceof String || right instanceof String )
{
- int val = ((Integer) left).compareTo((Integer)right);
+ String leftString = left.toString();
+ String rightString = right.toString();
- return new Boolean(val <= 0);
+ return leftString.compareTo( rightString ) <= 0
+ ? Boolean.TRUE
+ : Boolean.FALSE;
+ }
+ else if( left instanceof Comparable )
+ {
+ return ( (Comparable)left ).compareTo( right ) <= 0
+ ? Boolean.TRUE
+ : Boolean.FALSE;
+ }
+ else if( right instanceof Comparable )
+ {
+ return ( (Comparable)right ).compareTo( left ) >= 0
+ ? Boolean.TRUE
+ : Boolean.FALSE;
}
throw new Exception("Invalid comparison : LE ");
1.3 +42 -10 jakarta-commons/jexl/src/java/org/apache/commons/jexl/parser/ASTLTNode.java
Index: ASTLTNode.java
===================================================================
RCS file: /home/cvs/jakarta-commons/jexl/src/java/org/apache/commons/jexl/parser/ASTLTNode.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ASTLTNode.java 6 Mar 2003 21:34:32 -0000 1.2
+++ ASTLTNode.java 22 Jun 2003 19:43:01 -0000 1.3
@@ -55,11 +55,15 @@
package org.apache.commons.jexl.parser;
import org.apache.commons.jexl.JexlContext;
+import org.apache.commons.jexl.util.Coercion;
/**
* LT : a < b
*
+ * Follows A.3.6.1 of the JSTL 1.0 specification
+ *
* @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
+ * @author <a href="mailto:proyal@apache.org">Peter Royal</a>
* @version $Id$
*/
public class ASTLTNode extends SimpleNode
@@ -90,20 +94,48 @@
Object left = ( (SimpleNode) jjtGetChild(0)).value(jc);
Object right = ( (SimpleNode) jjtGetChild(1)).value(jc);
- if ((left==null) || (right==null))
+ if( ( left == right ) || ( left == null ) || ( right == null ) )
{
- throw new Exception("Null comparison : LT ");
+ return Boolean.FALSE;
}
+ else if( Coercion.isFloatingPoint( left ) || Coercion.isFloatingPoint( right ) )
+ {
+ double leftDouble = Coercion.coerceDouble( left ).doubleValue();
+ double rightDouble = Coercion.coerceDouble( right ).doubleValue();
+
+ return leftDouble < rightDouble
+ ? Boolean.TRUE
+ : Boolean.FALSE;
+ }
+ else if( Coercion.isNumberable( left ) || Coercion.isNumberable( right ) )
+ {
+ long leftLong = Coercion.coerceLong( left ).longValue();
+ long rightLong = Coercion.coerceLong( right ).longValue();
- if ( (left instanceof Integer || left instanceof Long)
- && ( right instanceof Integer || right instanceof Long) )
+ return leftLong < rightLong
+ ? Boolean.TRUE
+ : Boolean.FALSE;
+ }
+ else if( left instanceof String || right instanceof String )
{
- long leftLong = ((Number)left).longValue();
- long rightLong = ((Number)right).longValue();
+ String leftString = left.toString();
+ String rightString = right.toString();
- return ( ( leftLong < rightLong )
- ? Boolean.TRUE
- : Boolean.FALSE );
+ return leftString.compareTo( rightString ) < 0
+ ? Boolean.TRUE
+ : Boolean.FALSE;
+ }
+ else if( left instanceof Comparable )
+ {
+ return ( (Comparable)left ).compareTo( right ) < 0
+ ? Boolean.TRUE
+ : Boolean.FALSE;
+ }
+ else if( right instanceof Comparable )
+ {
+ return ( (Comparable)right ).compareTo( left ) > 0
+ ? Boolean.TRUE
+ : Boolean.FALSE;
}
throw new Exception("Invalid comparison : LT ");
1.3 +16 -0 jakarta-commons/jexl/src/java/org/apache/commons/jexl/util/Coercion.java
Index: Coercion.java
===================================================================
RCS file: /home/cvs/jakarta-commons/jexl/src/java/org/apache/commons/jexl/util/Coercion.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Coercion.java 17 May 2002 12:23:22 -0000 1.2
+++ Coercion.java 22 Jun 2003 19:43:01 -0000 1.3
@@ -175,10 +175,26 @@
}
else if (val instanceof Number)
{
+ //The below construct is used rather than ((Number)val).doubleValue() to ensure
+ //equality between comparint new Double( 6.4 / 3 ) and the jexl expression of 6.4 / 3
return new Double(Double.parseDouble(String.valueOf(val)));
}
throw new Exception("Double coercion exception");
+ }
+
+ public static boolean isFloatingPoint( final Object o )
+ {
+ return o instanceof Float || o instanceof Double;
+ }
+
+ public static boolean isNumberable( final Object o )
+ {
+ return o instanceof Integer
+ || o instanceof Long
+ || o instanceof Byte
+ || o instanceof Short
+ || o instanceof Character;
}
}
1.29 +13 -1 jakarta-commons/jexl/src/test/org/apache/commons/jexl/JexlTest.java
Index: JexlTest.java
===================================================================
RCS file: /home/cvs/jakarta-commons/jexl/src/test/org/apache/commons/jexl/JexlTest.java,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- JexlTest.java 9 May 2003 12:22:29 -0000 1.28
+++ JexlTest.java 22 Jun 2003 19:43:01 -0000 1.29
@@ -946,6 +946,18 @@
}
}
+ public void testCoercionWithComparisionOperators()
+ throws Exception
+ {
+ JexlContext jc = JexlHelper.createContext();
+
+ assertExpression(jc, "'2' > 1", Boolean.TRUE);
+ assertExpression(jc, "'2' >= 1", Boolean.TRUE);
+ assertExpression(jc, "'2' >= 2", Boolean.TRUE);
+ assertExpression(jc, "'2' < 1", Boolean.FALSE);
+ assertExpression(jc, "'2' <= 1", Boolean.FALSE);
+ assertExpression(jc, "'2' <= 2", Boolean.TRUE);
+ }
public void testResolver()
throws Exception
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org