Commits

Anonymous committed d24a4b4

Fixes OGNL-54. OgnlRuntime method finders and getChildSource weren't properly handling properties that should only be referencing root expressions (if any)..Such as method parameters / etc..Added logic to correctly set the context type/object state up for each of these.

Comments (0)

Files changed (14)

src/java/ognl/ASTChain.java

                         
                         if (indexNode.isIndexedAccess()) {
                             Object index = indexNode.getProperty(context, result);
-                            
+
                             if (index instanceof DynamicSubscript) {
                                 if (indexType == OgnlRuntime.INDEXED_PROPERTY_INT) {
                                     Object array = propertyNode.getValue(context, result);

src/java/ognl/ASTMethod.java

 
                     Class prevType = context.getCurrentType();
 
+                    context.setCurrentObject(context.getRoot());
+                    context.setCurrentType(context.getRoot() != null ? context.getRoot().getClass() : null);
+                    context.setCurrentAccessor(null);
+                    context.setPreviousType(null);
+
                     Object value = _children[i].getValue(context, context.getRoot());
                     String parmString = _children[i].toGetSourceString(context, context.getRoot());
-
+                    
                     if (parmString == null || parmString.trim().length() < 1)
                         parmString = "null";
                     
                         
                         context.setCurrentType(prevType);
                     }
-                    
+
                     parmString = ExpressionCompiler.getRootExpression(_children[i], context.getRoot(), context) + parmString;
 
                     String cast = "";
         if (m == null) {
             return "";
         }
-        
+
         String post = "";
         String result = "." + m.getName() + "(";
         
                     Class prevType = context.getCurrentType();
 
                     Object value = _children[i].getValue(context, context.getRoot());
-                    String parmString = _children[i].toGetSourceString(context, context.getRoot());
+                    String parmString = _children[i].toSetSourceString(context, context.getRoot());
 
-                    if (parmString == null || parmString.trim().length() < 1)
+                    if (parmString == null || parmString.trim().length() < 1) {
+
+                        if (ASTProperty.class.isInstance(_children[i]) || ASTMethod.class.isInstance(_children[i])
+                                || ASTStaticMethod.class.isInstance(_children[i]) || ASTChain.class.isInstance(_children[i]))
+                            throw new UnsupportedCompilationException("ASTMethod setter child returned null from a sub property expression.");
+                        
                         parmString = "null";
+                    }
 
                     // to undo type setting of constants when used as method parameters
                     if (ASTConst.class.isInstance(_children[i])) {
                     }
 
                     parmString = ExpressionCompiler.getRootExpression(_children[i], context.getRoot(), context) + parmString;
-                    
+
                     String cast = "";
                     if (ExpressionCompiler.shouldCast(_children[i])) {
 
                         cast = "";
                     
                     parmString = cast + parmString;
-                    
+
                     Class valueClass = value != null ? value.getClass() : null;
                     if (NodeType.class.isAssignableFrom(_children[i].getClass()))
                         valueClass = ((NodeType)_children[i]).getGetterClass();

src/java/ognl/ASTProperty.java

         Object result = null;
         Object property = null;
         result = property = getProperty(context, source);
-        
+
         result = OgnlRuntime.getProperty(context, source, property);
-        
+
         if (result == null) {
             
             result = OgnlRuntime.getNullHandler(OgnlRuntime.getTargetClass(source)).nullPropertyValue(context, source, property);
         Method m = null;
         
         try {
-           // System.out.println("astproperty is indexed? : " + isIndexedAccess() + " child: " + _children[0].getClass().getName()
+           //System.out.println("astproperty is indexed? : " + isIndexedAccess() + " child: " + _children[0].getClass().getName()
              //      + " target: " + target.getClass().getName() + " current object: " + context.getCurrentObject().getClass().getName());
             
             if (isIndexedAccess()) {
                 }
             } else {
 
-                /*
-                System.out.println("astproperty trying to get " + name + " on object target: " + context.getCurrentObject().getClass().getName()
+/*
+                 System.out.println("astproperty trying to get " + name + " on object target: " + context.getCurrentObject().getClass().getName()
                         + " current type " + context.getCurrentType() + " current accessor " + context.getCurrentAccessor()
-                    + " prev type " + context.getPreviousType() + " prev accessor " + context.getPreviousAccessor());
-               */
+                    + " prev type " + context.getPreviousType() + " prev accessor " + context.getPreviousAccessor()); */
+               
                 
                 PropertyAccessor pa = OgnlRuntime.getPropertyAccessor(context.getCurrentObject().getClass());
 
                             srcString = "\"" + srcString + "\"";
                         }
 
+
                         context.setCurrentObject(currObj);
                         context.setCurrentType(currType);
                         context.setPreviousType(prevType);
                         result = pa.getSourceAccessor(context, context.getCurrentObject(), srcString);
 
                         _getterClass = context.getCurrentType();
-
                     }
                 }
                 

src/java/ognl/ASTTest.java

             throw new UnsupportedCompilationException("Can only compile test expressions with two children." + _children.length);
 
         String result = "";
-        //String result = (_parent == null || NumericExpression.class.isAssignableFrom(_parent.getClass())) ? "" : "(";
         
         try {
 

src/java/ognl/OgnlRuntime.java

             Class currAccessor = context.getCurrentAccessor();
             Object cast = context.get(ExpressionCompiler.PRE_CAST);
 
+            context.setCurrentObject(context.getRoot());
+            context.setCurrentType(context.getRoot() != null ? context.getRoot().getClass() : null);
+            context.setCurrentAccessor(null);
+            context.setPreviousType(null);
+
             for (int i=0; i < children.length; i++) {
 
-                children[i].toGetSourceString(context, context.getCurrentObject());
+                children[i].toGetSourceString(context, context.getRoot());
                 parms[i] = context.getCurrentType();
             }
 
             pre = "";
 
         try {
-
             child.getValue(context, target);
         } catch (NullPointerException e) {
-            // e.printStackTrace();
+            // ignore
         }
-
+        
         String source = child.toGetSourceString(context, target);
 
         // handle root / method expressions that may not have proper root java source access
 
-        source = pre + source;
+        if (!ASTConst.class.isInstance(child) && (target == null || context.getRoot() != target)) {
+            source = pre + source;
+        }
 
         if (context.getRoot() != null) {
             
             source = ExpressionCompiler.getRootExpression(child, context.getRoot(), context) + source;
             context.setCurrentAccessor(context.getRoot().getClass());
         }
-        
+
         if (ASTChain.class.isInstance(child)) {
             
             String cast = (String) context.remove(ExpressionCompiler.PRE_CAST);

src/java/ognl/enhance/ExpressionCompiler.java

             return body;
 
 /*
-        System.out.println("castExpression() with expression " + expression + " currentType is: " + context.getCurrentType()
+        System.out.println("castExpression() with expression " + expression + " expr class: " + expression.getClass() + " currentType is: " + context.getCurrentType()
                 + " previousType: " + context.getPreviousType()
                 + "\n current Accessor: " + context.getCurrentAccessor()
                 + " previous Accessor: " + context.getPreviousAccessor()
 
         body = body.replaceAll("\\.\\.", ".");
 
-        // System.out.println("Getter Body: ===================================\n" + body);
+        //System.out.println("Getter Body: ===================================\n" + body);
         valueGetter.setBody(body);
 
         newClass.addMethod(valueGetter);
             
             body = body.replaceAll("\\.\\.", ".");
             
-            // System.out.println("adding method " + ref.getName() + " with body:\n" + body + " and return type: " + ref.getType());
+            //System.out.println("adding method " + ref.getName() + " with body:\n" + body + " and return type: " + ref.getType());
             
             CtMethod method = new CtMethod(pool.get(ref.getType().getName()), ref.getName(), params, clazz);
             method.setBody(body);
 
         body = body.replaceAll("\\.\\.", ".");
 
-        // System.out.println("Setter Body: ===================================\n" + body);
+        //System.out.println("Setter Body: ===================================\n" + body);
 
         valueSetter.setBody(body);
 

src/test/java/org/ognl/test/InterfaceInheritanceTest.java

 import java.util.List;
 
 public class InterfaceInheritanceTest extends OgnlTestCase {
+    
     private static Root ROOT = new Root();
 
     static {
             {ROOT, "map.comp.form.clientId", "form1"},
             {ROOT, "map.comp.getCount(genericIndex)", Integer.valueOf(0)},
             {ROOT, "map.customList.total", Integer.valueOf(1)},
-            {ROOT, "myTest.theMap['key']", "value" }
+            {ROOT, "myTest.theMap['key']", "value" },
+            {ROOT, "contentProvider.hasChildren(property)", Boolean.TRUE}
     };
 
     /*

src/test/java/org/ognl/test/PropertyTest.java

 package org.ognl.test;
 
 import junit.framework.TestSuite;
+import org.ognl.test.objects.BaseBean;
 import org.ognl.test.objects.Bean2;
+import org.ognl.test.objects.FirstBean;
 import org.ognl.test.objects.Root;
 
 import java.text.SimpleDateFormat;
     
     private static Root ROOT = new Root();
 
+    private static BaseBean BEAN = new FirstBean();
+
     /* { ROOT, "map.(array[2] + size()).doubleValue()", new Double(ROOT.getArray()[2] + ROOT.getMap().size()) }, */
 
     private static Object[][]       TESTS = {
             { ROOT, "@org.ognl.test.PropertyTest@formatValue(property.millis, true, true)", formatValue((int)((Bean2)ROOT.getProperty()).getMillis(), true, true) },
             { ROOT, "nullObject || !readonly", Boolean.TRUE },
             { ROOT, "testDate == null ? '-' : @org.ognl.test.PropertyTest@DATETIME_FORMAT.format(testDate)", DATETIME_FORMAT.format(ROOT.getTestDate()) },
-            { ROOT, "disabled ? 'disabled' : 'othernot'", "disabled" }
+            { ROOT, "disabled ? 'disabled' : 'othernot'", "disabled" },
+            { BEAN, "two.getMessage(active ? 'ACT' : 'INA')", "[ACT]"} 
     };
 
     public static String formatValue(int millis, boolean b1, boolean b2)

src/test/java/org/ognl/test/objects/BaseBean.java

 /**
- * 
+ *
  */
 package org.ognl.test.objects;
 
 /**
  * Base class used to test inheritance class casting.
  */
-public abstract class BaseBean
-{
-    
-    public abstract String getName();   
+public abstract class BaseBean {
+
+    public abstract String getName();
+
+    public boolean getActive()
+    {
+        return true;
+    }
+
+    public boolean isActive2()
+    {
+        return true;
+    }
+
+    public Two getTwo()
+    {
+        return new Two();
+    }
+
+    public String getMessage(String mes)
+    {
+        return "[" + mes + "]";
+    }
 }

src/test/java/org/ognl/test/objects/IContentProvider.java

+package org.ognl.test.objects;
+
+import java.util.List;
+
+/**
+ *
+ */
+public interface IContentProvider {
+
+    public List getElements();
+}

src/test/java/org/ognl/test/objects/ITreeContentProvider.java

+package org.ognl.test.objects;
+
+import java.util.Collection;
+
+/**
+ *
+ */
+public interface ITreeContentProvider extends IContentProvider {
+
+    public Collection getChildren(Object parentElement);
+
+    public boolean hasChildren(Object parentElement);
+}

src/test/java/org/ognl/test/objects/Root.java

     private Object _genericObjIndex = new Integer(2);
     private Date _date = new Date();
 
+    private ITreeContentProvider _contentProvider = new TreeContentProvider();
+
     /*===================================================================
 		Public static methods
 	  ===================================================================*/
     {
         return new TestImpl();
     }
+
+    public ITreeContentProvider getContentProvider()
+    {
+        return _contentProvider;
+    }
 }

src/test/java/org/ognl/test/objects/TreeContentProvider.java

+package org.ognl.test.objects;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ */
+public class TreeContentProvider implements ITreeContentProvider {
+
+
+
+    public Collection getChildren(Object parentElement)
+    {
+        return Collections.EMPTY_LIST;
+    }
+
+    public boolean hasChildren(Object parentElement)
+    {
+        return true;
+    }
+
+    public List getElements()
+    {
+        return Collections.EMPTY_LIST;
+    }
+}

src/test/java/org/ognl/test/objects/Two.java

+package org.ognl.test.objects;
+
+/**
+ *
+ */
+public class Two {
+
+    public String getMessage(String mes)
+    {
+        return "[" + mes + "]";
+    }
+}