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 {


Reply via email to