commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d...@apache.org
Subject svn commit: r588450 - /commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java
Date Fri, 26 Oct 2007 00:39:29 GMT
Author: dion
Date: Thu Oct 25 17:39:29 2007
New Revision: 588450

URL: http://svn.apache.org/viewvc?rev=588450&view=rev
Log:
passing tests

Modified:
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java?rev=588450&r1=588449&r2=588450&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java Thu
Oct 25 17:39:29 2007
@@ -22,11 +22,13 @@
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
-import java.util.Stack;
 
 import org.apache.commons.jexl.parser.ASTAddNode;
+import org.apache.commons.jexl.parser.ASTAndNode;
 import org.apache.commons.jexl.parser.ASTArrayAccess;
 import org.apache.commons.jexl.parser.ASTAssignment;
 import org.apache.commons.jexl.parser.ASTBitwiseAndNode;
@@ -34,23 +36,41 @@
 import org.apache.commons.jexl.parser.ASTBitwiseOrNode;
 import org.apache.commons.jexl.parser.ASTBitwiseXorNode;
 import org.apache.commons.jexl.parser.ASTBlock;
+import org.apache.commons.jexl.parser.ASTDivNode;
 import org.apache.commons.jexl.parser.ASTEQNode;
 import org.apache.commons.jexl.parser.ASTEmptyFunction;
 import org.apache.commons.jexl.parser.ASTExpression;
 import org.apache.commons.jexl.parser.ASTExpressionExpression;
+import org.apache.commons.jexl.parser.ASTFalseNode;
+import org.apache.commons.jexl.parser.ASTFloatLiteral;
 import org.apache.commons.jexl.parser.ASTForeachStatement;
+import org.apache.commons.jexl.parser.ASTGENode;
+import org.apache.commons.jexl.parser.ASTGTNode;
 import org.apache.commons.jexl.parser.ASTIdentifier;
 import org.apache.commons.jexl.parser.ASTIfStatement;
 import org.apache.commons.jexl.parser.ASTIntegerLiteral;
+import org.apache.commons.jexl.parser.ASTJexlScript;
+import org.apache.commons.jexl.parser.ASTLENode;
+import org.apache.commons.jexl.parser.ASTLTNode;
+import org.apache.commons.jexl.parser.ASTMapEntry;
+import org.apache.commons.jexl.parser.ASTMapLiteral;
 import org.apache.commons.jexl.parser.ASTMethod;
+import org.apache.commons.jexl.parser.ASTModNode;
 import org.apache.commons.jexl.parser.ASTMulNode;
+import org.apache.commons.jexl.parser.ASTNENode;
+import org.apache.commons.jexl.parser.ASTNotNode;
 import org.apache.commons.jexl.parser.ASTNullLiteral;
+import org.apache.commons.jexl.parser.ASTOrNode;
 import org.apache.commons.jexl.parser.ASTReference;
 import org.apache.commons.jexl.parser.ASTReferenceExpression;
 import org.apache.commons.jexl.parser.ASTSizeFunction;
+import org.apache.commons.jexl.parser.ASTSizeMethod;
 import org.apache.commons.jexl.parser.ASTStatementExpression;
 import org.apache.commons.jexl.parser.ASTStringLiteral;
+import org.apache.commons.jexl.parser.ASTSubtractNode;
 import org.apache.commons.jexl.parser.ASTTrueNode;
+import org.apache.commons.jexl.parser.ASTUnaryMinusNode;
+import org.apache.commons.jexl.parser.ASTWhileStatement;
 import org.apache.commons.jexl.parser.Node;
 import org.apache.commons.jexl.parser.SimpleNode;
 import org.apache.commons.jexl.parser.VisitorAdapter;
@@ -70,8 +90,6 @@
     private Uberspect uberspect;
     /** The context to store/retrieve variables. */
     private JexlContext context;
-    /** the stack that holds values during expressions. */
-    private Stack valueStack;
     /** dummy velocity info. */
     private static final Info DUMMY = new Info("", 1, 1);
 
@@ -91,7 +109,6 @@
      */
     public Object interpret(SimpleNode node, JexlContext aContext) {
         setContext(aContext);
-        valueStack = new Stack();
         System.out.println("node is: " + node);
         return node.jjtAccept(this, null);
     }
@@ -158,11 +175,31 @@
     }
 
     /** {@inheritDoc} */
-    public Object visit(ASTArrayAccess node, Object data) {
+    public Object visit(ASTAndNode node, Object data) {
         node.dump("+");
-        return node.childrenAccept(this, data);
+        Object left = node.jjtGetChild(0).jjtAccept(this, data);
+        boolean leftValue = Coercion.coerceboolean(left);
+
+        // coercion rules
+        return (leftValue && Coercion.coerceboolean(
+                node.jjtGetChild(1).jjtAccept(this, data))) ? Boolean.TRUE
+                : Boolean.FALSE;
     }
 
+    /** {@inheritDoc} */
+    public Object visit(ASTArrayAccess node, Object data) {
+        node.dump("+");
+        // first child is the identifier
+        Object object = node.jjtGetChild(0).jjtAccept(this, data);
+        // can have multiple nodes - either an expression, integer literal or reference
+        int numChildren = node.jjtGetNumChildren();
+        for (int i = 1; i < numChildren; i++) {
+            Object index = node.jjtGetChild(i).jjtAccept(this, null);
+            object = getAttribute(object, index);
+        }
+        
+        return object;
+    }
 
     /** {@inheritDoc} */
     public Object visit(ASTAssignment node, Object data) {
@@ -236,6 +273,28 @@
     }
 
     /** {@inheritDoc} */
+    public Object visit(ASTDivNode node, Object data) {
+        node.dump("+");
+        Object left = node.jjtGetChild(0).jjtAccept(this, data);
+        Object right = node.jjtGetChild(1).jjtAccept(this, data);
+
+        // the spec says 'and', I think 'or'
+        if (left == null && right == null) {
+            return new Byte((byte) 0);
+        }
+
+        Double l = Coercion.coerceDouble(left);
+        Double r = Coercion.coerceDouble(right);
+
+        // catch div/0
+        if (r.doubleValue() == 0.0) {
+            return r;
+        }
+
+        return new Double(l.doubleValue() / r.doubleValue());
+    }
+
+    /** {@inheritDoc} */
     public Object visit(ASTEmptyFunction node, Object data) {
         node.dump("+");
         Object o = node.jjtGetChild(0).jjtAccept(this, data);
@@ -270,38 +329,7 @@
         Object left = node.jjtGetChild(0).jjtAccept(this, data);
         Object right = node.jjtGetChild(1).jjtAccept(this, data);
 
-        if (left == null && right == null) {
-            /*
-             * if both are null L == R
-             */
-            return Boolean.TRUE;
-        } else if (left == null || right == null) {
-            /*
-             * we know both aren't null, therefore L != R
-             */
-            return Boolean.FALSE;
-        } else if (left.getClass().equals(right.getClass())) {
-            return left.equals(right) ? Boolean.TRUE : Boolean.FALSE;
-        } else if (left instanceof Float || left instanceof Double
-                || right instanceof Float || right instanceof Double) {
-            Double l = Coercion.coerceDouble(left);
-            Double r = Coercion.coerceDouble(right);
-
-            return l.equals(r) ? Boolean.TRUE : Boolean.FALSE;
-        } else if (left instanceof Number || right instanceof Number
-                || left instanceof Character || right instanceof Character) {
-            return Coercion.coerceLong(left).equals(Coercion.coerceLong(right)) ? Boolean.TRUE
-                    : Boolean.FALSE;
-        } else if (left instanceof Boolean || right instanceof Boolean) {
-            return Coercion.coerceBoolean(left).equals(
-                    Coercion.coerceBoolean(right)) ? Boolean.TRUE
-                    : Boolean.FALSE;
-        } else if (left instanceof java.lang.String || right instanceof String) {
-            return left.toString().equals(right.toString()) ? Boolean.TRUE
-                    : Boolean.FALSE;
-        }
-
-        return left.equals(right) ? Boolean.TRUE : Boolean.FALSE;
+        return equals(left, right) ? Boolean.TRUE : Boolean.FALSE; 
     }
 
     /** {@inheritDoc} */
@@ -315,6 +343,18 @@
     }
 
     /** {@inheritDoc} */
+    public Object visit(ASTFalseNode node, Object data) {
+        node.dump("+");
+        return Boolean.FALSE;
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTFloatLiteral node, Object data) {
+        node.dump("+");
+        return Float.valueOf(node.image);
+    }
+
+    /** {@inheritDoc} */
     public Object visit(ASTForeachStatement node, Object data) {
         node.dump("+");
 
@@ -343,31 +383,31 @@
     }
 
     /** {@inheritDoc} */
+    public Object visit(ASTGENode node, Object data) {
+        node.dump("+");
+        Object left = node.jjtGetChild(0).jjtAccept(this, data);
+        Object right = node.jjtGetChild(1).jjtAccept(this, data);
+
+        return greaterThanOrEqual(left, right) ? Boolean.TRUE : Boolean.FALSE; 
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTGTNode node, Object data) {
+        node.dump("+");
+        Object left = node.jjtGetChild(0).jjtAccept(this, data);
+        Object right = node.jjtGetChild(1).jjtAccept(this, data);
+
+        return greaterThan(left, right) ? Boolean.TRUE : Boolean.FALSE; 
+    }
+
+    /** {@inheritDoc} */
     public Object visit(ASTIdentifier node, Object data) { 
         node.dump("+");
         String name = node.image;
         if (data == null) {
             return context.getVars().get(name);
         } else {
-            // bean.property, map.key etc
-
-            // TODO: implement map stuff here
-            if (data instanceof Map) {
-                return ((Map) data).get(name);
-            }
-            // look up bean property of data and return
-            VelPropertyGet vg = getUberspect().getPropertyGet(data, node.image, DUMMY);
-
-            if (vg != null) {
-                try {
-                    return vg.invoke(data);
-                } catch (Exception e) {
-                    throw new RuntimeException(e);
-                }
-            } else {
-                return null;
-            }
-                
+            return getAttribute(data, name);
         }
     }
     
@@ -391,8 +431,66 @@
     }
     
     /** {@inheritDoc} */
-    public Object visit(ASTIntegerLiteral node, Object data) { 
-        return Integer.valueOf(node.image); 
+    public Object visit(ASTIntegerLiteral node, Object data) {
+        Integer value = Integer.valueOf(node.image);
+        if (data == null) {
+            return value;
+        } else {
+            return getAttribute(data, value);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTJexlScript node, Object data) {
+        node.dump("+");
+        int numChildren = node.jjtGetNumChildren();
+        Object result = null;
+        for (int i = 0; i < numChildren; i++) {
+            Node child = node.jjtGetChild(i);
+            result = child.jjtAccept(this, data);
+        }
+        return result;
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTLENode node, Object data) {
+        node.dump("+");
+        Object left = node.jjtGetChild(0).jjtAccept(this, data);
+        Object right = node.jjtGetChild(1).jjtAccept(this, data);
+
+        return lessThanOrEqual(left, right) ? Boolean.TRUE : Boolean.FALSE; 
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTLTNode node, Object data) {
+        node.dump("+");
+        Object left = node.jjtGetChild(0).jjtAccept(this, data);
+        Object right = node.jjtGetChild(1).jjtAccept(this, data);
+
+        return lessThan(left, right) ? Boolean.TRUE : Boolean.FALSE; 
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTMapEntry node, Object data) {
+        node.dump("+");
+        return new Object[]{
+            (node.jjtGetChild(0)).jjtAccept(this, data),
+            (node.jjtGetChild(1)).jjtAccept(this, data) 
+        };
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTMapLiteral node, Object data) {
+        node.dump("+");
+        int childCount = node.jjtGetNumChildren();
+        Map map = new HashMap();
+
+        for (int i = 0; i < childCount; i++) {
+            Object[] entry = (Object[]) (node.jjtGetChild(i)).jjtAccept(this, data);
+            map.put(entry[0], entry[1]);
+        }
+
+        return map;
     }
 
     /** {@inheritDoc} */
@@ -444,6 +542,44 @@
     }
 
     /** {@inheritDoc} */
+    public Object visit(ASTModNode node, Object data) {
+        node.dump("+");
+        Object left = node.jjtGetChild(0).jjtAccept(this, data);
+        Object right = node.jjtGetChild(1).jjtAccept(this, data);
+
+        // the spec says 'and', I think 'or'
+        if (left == null && right == null) {
+            return new Byte((byte) 0);
+        }
+
+        // if anything is float, double or string with ( "." | "E" | "e") coerce
+        // all to doubles and do it
+        if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
+            Double l = Coercion.coerceDouble(left);
+            Double r = Coercion.coerceDouble(right);
+
+            // catch div/0
+            if (r.doubleValue() == 0.0) {
+                return r;
+            }
+
+            return new Double(l.doubleValue() % r.doubleValue());
+        }
+
+        // otherwise to longs with thee!
+
+        long l = Coercion.coercelong(left);
+        long r = Coercion.coercelong(right);
+
+        // catch the div/0
+        if (r == 0) {
+            return new Long(0);
+        }
+
+        return new Long(l % r);
+    }
+
+    /** {@inheritDoc} */
     public Object visit(ASTMulNode node, Object data) {
         node.dump("+");
         Object left = node.jjtGetChild(0).jjtAccept(this, data);
@@ -486,30 +622,71 @@
 
 
     /** {@inheritDoc} */
+    public Object visit(ASTNENode node, Object data) {
+        node.dump("+");
+        Object left = node.jjtGetChild(0).jjtAccept(this, data);
+        Object right = node.jjtGetChild(1).jjtAccept(this, data);
+
+        return equals(left, right) ? Boolean.FALSE : Boolean.TRUE; 
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTNotNode node, Object data) {
+        node.dump("+");
+        Object val = node.jjtGetChild(0).jjtAccept(this, data);
+
+        // coercion rules
+        if (val != null) {
+            return Coercion.coerceboolean(val) ? Boolean.FALSE : Boolean.TRUE;
+        }
+
+        throw new IllegalArgumentException("not expression: not boolean valued " + val);
+    }
+
+    /** {@inheritDoc} */
     public Object visit(ASTNullLiteral node, Object data) { 
         return null; 
     }
 
     /** {@inheritDoc} */
+    public Object visit(ASTOrNode node, Object data) {
+        node.dump("+");
+        Object left = node.jjtGetChild(0).jjtAccept(this, data);
+        boolean leftValue = Coercion.coerceboolean(left);
+
+        // coercion rules
+        return (leftValue || Coercion.coerceboolean(
+                node.jjtGetChild(1).jjtAccept(this, data))) ? Boolean.TRUE
+                : Boolean.FALSE;
+    }
+
+    /** {@inheritDoc} */
     public Object visit(ASTReference node, Object data) {
         // could be array access, identifier or map literal
         // followed by zero or more ("." and array access, method, size, identifier or integer
literal)
         node.dump("+");
         int numChildren = node.jjtGetNumChildren();
-        Object baseValue = node.jjtGetChild(0).jjtAccept(this, data);
-        if (numChildren == 1) {
-            return baseValue;
-        }
+
         // pass  first piece of data in and loop through children
-        Object result = baseValue;
-        for (int i = 1; i < numChildren; i++) {
-            result = node.jjtGetChild(i).jjtAccept(this, result);
-            // if we get null back a result, stop evaluating the rest of the expr
-            if (result == null) {
-                break;
+        Object result = null;
+        StringBuffer variableName = new StringBuffer();
+        boolean isVariable = true;
+        for (int i = 0; i < numChildren; i++) {
+            Node theNode = node.jjtGetChild(i);
+            isVariable = isVariable && (theNode instanceof ASTIdentifier);
+            result = theNode.jjtAccept(this, result);
+            // if we get null back a result, check for an ant variable
+            if (result == null && isVariable) {
+                if (i != 0) {
+                    variableName.append('.');
+                } 
+                String name = ((ASTIdentifier) theNode).image;
+                variableName.append(name);
+                result = context.getVars().get(variableName.toString());
             }
         }
-        return result;
+        
+        return result;            
     }
 
     /** {@inheritDoc} */
@@ -531,6 +708,12 @@
     }
 
     /** {@inheritDoc} */
+    public Object visit(ASTSizeMethod node, Object data) {
+        node.dump("+");
+        return new Integer(sizeOf(data));
+    }
+
+    /** {@inheritDoc} */
     public Object visit(ASTStatementExpression node, Object data) {
         node.dump("+");
         return node.jjtGetChild(0).jjtAccept(this, data);
@@ -542,10 +725,86 @@
     }
 
     /** {@inheritDoc} */
+    public Object visit(ASTSubtractNode node, Object data) {
+        node.dump("+");
+        Object left = node.jjtGetChild(0).jjtAccept(this, data);
+        Object right = node.jjtGetChild(1).jjtAccept(this, data);
+
+        // the spec says 'and', I think 'or'
+        if (left == null && right == null) {
+            return new Byte((byte) 0);
+        }
+
+        // if anything is float, double or string with ( "." | "E" | "e") coerce
+        // all to doubles and do it
+        if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
+
+            // in the event that either is null and not both, then just make the null a 0
+            double l = Coercion.coercedouble(left);
+            double r = Coercion.coercedouble(right);
+            return new Double(l - r);
+        }
+
+        // otherwise to longs with thee!
+
+        long l = Coercion.coercelong(left);
+        long r = Coercion.coercelong(right);
+
+        return new Long(l - r);
+    }
+
+    /** {@inheritDoc} */
     public Object visit(ASTTrueNode node, Object data) {
         return Boolean.TRUE;
     }
 
+    /** {@inheritDoc} */
+    public Object visit(ASTUnaryMinusNode node, Object data) {
+        node.dump("+");
+        Object val = node.jjtGetChild(0).jjtAccept(this, data);
+
+        if (val instanceof Byte) {
+            byte valueAsByte = ((Byte) val).byteValue();
+            return new Byte((byte) -valueAsByte);
+        } else if (val instanceof Short) {
+            short valueAsShort = ((Short) val).shortValue();
+            return new Short((short) -valueAsShort);
+        } else if (val instanceof Integer) {
+            int valueAsInt = ((Integer) val).intValue();
+            return new Integer(-valueAsInt);
+        } else if (val instanceof Long) {
+            long valueAsLong = ((Long) val).longValue();
+            return new Long(-valueAsLong);
+        } else if (val instanceof Float) {
+            float valueAsFloat = ((Float) val).floatValue();
+            return new Float(-valueAsFloat);
+        } else if (val instanceof Double) {
+            double valueAsDouble = ((Double) val).doubleValue();
+            return new Double(-valueAsDouble);
+        } else if (val instanceof BigDecimal) {
+            BigDecimal valueAsBigD = (BigDecimal) val;
+            return valueAsBigD.negate();
+        } else if (val instanceof BigInteger) {
+            BigInteger valueAsBigI = (BigInteger) val;
+            return valueAsBigI.negate();
+        }
+        throw new NumberFormatException("expression not a number: " + val);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTWhileStatement node, Object data) {
+        node.dump("+");
+        Object result = null;
+        /* first child is the expression */
+        Node expressionNode = (Node) node.jjtGetChild(0);
+        while (Coercion.coerceboolean(expressionNode.jjtAccept(this, data))) {
+            // execute statement
+            result = node.jjtGetChild(1).jjtAccept(this, data);
+        }
+
+        return result;
+    }
+
 // other stuff    
 
     /**
@@ -635,6 +894,163 @@
             return string.indexOf(".") != -1 || string.indexOf("e") != -1 || string.indexOf("E")
!= -1;
         }
         return false;
+    }
+
+
+    /**
+     * Get an attribute of an object. 
+     * @param object to retrieve value from  
+     * @param attribute the attribute of the object, e.g. an index (1, 0, 2) or
+     *      key for a map
+     * @return the attribute.
+     */
+    private Object getAttribute(Object object, Object attribute) {
+        if (object == null) {
+            return null;
+        }
+        if (attribute == null) {
+            return null;
+        }
+        if (object instanceof Map) {
+            return ((Map) object).get(attribute);
+        } else if (object instanceof List) {
+            int idx = Coercion.coerceinteger(attribute);
+
+            try {
+                return ((List) object).get(idx);
+            } catch (IndexOutOfBoundsException iobe) {
+                return null;
+            }
+        } else if (object.getClass().isArray()) {
+            int idx = Coercion.coerceinteger(attribute);
+
+            try {
+                return Array.get(object, idx);
+            } catch (ArrayIndexOutOfBoundsException aiobe) {
+                return null;
+            }
+        } else {
+            // look up bean property of data and return
+            VelPropertyGet vg = getUberspect().getPropertyGet(object, attribute.toString(),
DUMMY);
+
+            if (vg != null) {
+                try {
+                    return vg.invoke(object);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            } else {
+                return null;
+            }
+
+        }
+    }
+
+    /**
+     * Test if left and right are equal.
+     * @param left first value
+     * @param right second value
+     * @return test result.
+     */
+    private boolean equals(Object left, Object right) {
+        if (left == null && right == null) {
+            /*
+             * if both are null L == R
+             */
+            return true;
+        } else if (left == null || right == null) {
+            /*
+             * we know both aren't null, therefore L != R
+             */
+            return false;
+        } else if (left.getClass().equals(right.getClass())) {
+            return left.equals(right);
+        } else if (left instanceof Float || left instanceof Double
+                || right instanceof Float || right instanceof Double) {
+            Double l = Coercion.coerceDouble(left);
+            Double r = Coercion.coerceDouble(right);
+
+            return l.equals(r);
+        } else if (left instanceof Number || right instanceof Number
+                || left instanceof Character || right instanceof Character) {
+            return Coercion.coerceLong(left).equals(Coercion.coerceLong(right));
+        } else if (left instanceof Boolean || right instanceof Boolean) {
+            return Coercion.coerceBoolean(left).equals(
+                    Coercion.coerceBoolean(right));
+        } else if (left instanceof java.lang.String || right instanceof String) {
+            return left.toString().equals(right.toString());
+        }
+
+        return left.equals(right);
+    }
+
+    /**
+     * Test if left < right.
+     * @param left first value
+     * @param right second value
+     * @return test result.
+     */
+    private boolean lessThan(Object left, Object right) {
+        if ((left == right) || (left == null) || (right == null)) {
+            return false;
+        } else if (Coercion.isFloatingPoint(left)
+                || Coercion.isFloatingPoint(right)) {
+            double leftDouble = Coercion.coerceDouble(left).doubleValue();
+            double rightDouble = Coercion.coerceDouble(right).doubleValue();
+
+            return leftDouble < rightDouble;
+        } else if (Coercion.isNumberable(left) || Coercion.isNumberable(right)) {
+            long leftLong = Coercion.coerceLong(left).longValue();
+            long rightLong = Coercion.coerceLong(right).longValue();
+
+            return leftLong < rightLong;
+        } else if (left instanceof String || right instanceof String) {
+            String leftString = left.toString();
+            String rightString = right.toString();
+
+            return leftString.compareTo(rightString) < 0;
+        } else if (left instanceof Comparable) {
+            return ((Comparable) left).compareTo(right) < 0;
+        } else if (right instanceof Comparable) {
+            return ((Comparable) right).compareTo(left) > 0;
+        }
+
+        throw new IllegalArgumentException("Invalid comparison : comparing cardinality for
left: " 
+            + left + " and right: " + right);
+
+    }
+    
+    /**
+     * Test if left > right.
+     * @param left first value
+     * @param right second value
+     * @return test result.
+     */
+    private boolean greaterThan(Object left, Object right) {
+        if (left == null || right == null) {
+            return false;
+        }
+        return !equals(left, right) && !lessThan(left, right);
+    }
+
+    /**
+     * Test if left <= right.
+     * @param left first value
+     * @param right second value
+     * @return test result.
+     */
+    private boolean lessThanOrEqual(Object left, Object right) {
+        return equals(left, right) || lessThan(left, right);
+    }
+
+    /**
+     * Test if left >= right.
+     * @param left first value
+     * @param right second value
+     * @return test result.
+     */
+    private boolean greaterThanOrEqual(Object left, Object right) {
+        return equals(left, right) || greaterThan(left, right);
     }
 
 }



Mime
View raw message