Author: henrib Date: Wed Aug 11 18:26:09 2010 New Revision: 984516 URL: http://svn.apache.org/viewvc?rev=984516&view=rev Log: Fix for JEXL-104
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlArithmetic.java commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/ArrayLiteralTest.java Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlArithmetic.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlArithmetic.java?rev=984516&r1=984515&r2=984516&view=diff ============================================================================== --- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlArithmetic.java (original) +++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlArithmetic.java Wed Aug 11 18:26:09 2010 @@ -203,24 +203,36 @@ public class JexlArithmetic { final int size = untyped.length; Class<?> commonClass = null; if (size > 0) { - // base common class on first entry - commonClass = untyped[0].getClass(); - final boolean isNumber = Number.class.isAssignableFrom(commonClass); + boolean isNumber = true; // for all children after first... - for (int i = 1; i < size; i++) { - Class<?> eclass = untyped[i].getClass(); - // detect same type for all elements in array - if (!Object.class.equals(commonClass) && !commonClass.equals(eclass)) { - // if both are numbers... - if (isNumber && Number.class.isAssignableFrom(eclass)) { - commonClass = Number.class; - } else { - commonClass = Object.class; + for (int u = 0; u < size && !Object.class.equals(commonClass); ++u) { + if (untyped[u] != null) { + Class<?> eclass = untyped[u].getClass(); + // base common class on first non-null entry + if (commonClass == null) { + commonClass = eclass; + isNumber &= Number.class.isAssignableFrom(commonClass); + } else if (!commonClass.equals(eclass)) { + // if both are numbers... + if (isNumber && Number.class.isAssignableFrom(eclass)) { + commonClass = Number.class; + } else { + // attempt to find valid superclass + do { + eclass = eclass.getSuperclass(); + if (eclass == null) { + commonClass = Object.class; + break; + } + } while(!commonClass.isAssignableFrom(eclass)); + } } + } else { + isNumber = false; } } // convert array to the common class if not Object.class - if (!Object.class.equals(commonClass)) { + if (commonClass != null && !Object.class.equals(commonClass)) { // if the commonClass has an equivalent primitive type, get it if (isNumber) { try { Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/ArrayLiteralTest.java URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/ArrayLiteralTest.java?rev=984516&r1=984515&r2=984516&view=diff ============================================================================== --- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/ArrayLiteralTest.java (original) +++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/ArrayLiteralTest.java Wed Aug 11 18:26:09 2010 @@ -49,6 +49,31 @@ public class ArrayLiteralTest extends Je Object o = e.evaluate( jc ); Object[] check = { new Float(5), new Integer(10) }; assertTrue( Arrays.equals(check, (Object[])o) ); + assertTrue (o.getClass().isArray() && o.getClass().getComponentType().equals(Number.class)); + } + + public void testLiteralWithNulls() throws Exception { + String []exprs = { + "[ null , 10 ]", + "[ 10 , null ]", + "[ 10 , null , 10]", + "[ '10' , null ]", + "[ null, '10' , null ]" + }; + Object [][]checks = { + {null, new Integer(10)}, + {new Integer(10), null}, + {new Integer(10), null, new Integer(10)}, + { "10", null }, + { null, "10", null } + }; + JexlContext jc = new MapContext(); + for(int t = 0; t < exprs.length; ++t) { + Expression e = JEXL.createExpression( exprs[t] ); + Object o = e.evaluate( jc ); + assertTrue(exprs[t], Arrays.equals(checks[t], (Object[])o) ); + } + } public void testLiteralWithIntegers() throws Exception {