Commits

Anonymous committed df2bcf8

OK, this is fun:
* Fixed a test so it can run in an existing suite (it plays nice now)
* new hacked version of Ognl that lets the CompoundRoot finally trick Ognl in to thinking there really are many roots -- this fixes type conversion for good
* added a bunch of tests for type conversion and the compound root

git-svn-id: http://svn.opensymphony.com/svn/xwork/trunk@60e221344d-f017-0410-9bd5-d282ab1896d7

Comments (0)

Files changed (7)

lib/core/ognl-2.6.3.jar

Binary file modified.

src/java/com/opensymphony/xwork/util/CompoundRootAccessor.java

 package com.opensymphony.xwork.util;
 
 import ognl.*;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import java.beans.IntrospectionException;
-
 import java.util.Iterator;
 import java.util.Map;
 
 
                         //Ognl.getValue(OgnlUtil.compile((String) name), context, o);
                         if (value != null) {
-                            ognlContext.pushEvaluation(new Evaluation(ognlContext.getCurrentEvaluation().getNode(), o));
+                            Evaluation currentEvaluation = ognlContext.getCurrentEvaluation();
+                            SimpleNode node = currentEvaluation.getNode();
+                            currentEvaluation.setSource(o);
+                            ognlContext.pushEvaluation(new Evaluation(node, o));
 
                             return value;
                         }

src/java/com/opensymphony/xwork/util/OgnlValueStack.java

 
 import java.io.ObjectStreamException;
 import java.io.Serializable;
-
 import java.util.Map;
 
 

src/java/com/opensymphony/xwork/util/XWorkConverter.java

 
 import com.opensymphony.xwork.LocaleAware;
 import com.opensymphony.xwork.ValidationAware;
-
 import ognl.DefaultTypeConverter;
 import ognl.Evaluation;
 import ognl.OgnlContext;
 import ognl.TypeConverter;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import java.io.InputStream;
-
 import java.lang.reflect.Member;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
+import java.util.*;
 
 
 /**
                         property = (String) eval.getLastChild().getResult();
                     }
                 } else {
+                    // since we changed what the source was (tricked Ognl essentially)
                     clazz = eval.getLastChild().getSource().getClass();
-                    property = (String) eval.getFirstChild().getResult();
+
+                    // ugly hack getting the property, but it works
+                    property = eval.getNode().jjtGetChild(eval.getNode().jjtGetNumChildren() - 1).toString();
+                    if (property.startsWith("\"") && property.endsWith("\"")) {
+                        property = property.substring(1, property.length() - 1);
+                    }
                 }
             }
 
                             mapping.putAll(props);
 
                             for (Iterator iterator = mapping.entrySet().iterator();
-                                    iterator.hasNext();) {
+                                 iterator.hasNext();) {
                                 Map.Entry entry = (Map.Entry) iterator.next();
                                 entry.setValue(createTypeConverter((String) entry.getValue()));
                             }
         props.load(is);
 
         for (Iterator iterator = props.entrySet().iterator();
-                iterator.hasNext();) {
+             iterator.hasNext();) {
             Map.Entry entry = (Map.Entry) iterator.next();
             String key = (String) entry.getKey();
 

src/test/com/opensymphony/xwork/util/Foo.java

     boolean useful;
     int number;
     long aLong;
+    Foo child;
+    Foo[] relatives;
 
     //~ Methods ////////////////////////////////////////////////////////////////
 
     public void setaLong(long aLong) {
         this.aLong = aLong;
     }
+
+    public void setChild(Foo child) {
+        this.child = child;
+    }
+
+    public Foo getChild() {
+        return child;
+    }
+
+    public Foo[] getRelatives() {
+        return relatives;
+    }
+
+    public void setRelatives(Foo[] relatives) {
+        this.relatives = relatives;
+    }
 }

src/test/com/opensymphony/xwork/util/OgnlValueStackTest.java

         OgnlValueStack vs = new OgnlValueStack();
         vs.push(foo);
 
-        Map context = vs.getContext();
-
-        HashMap props = new HashMap();
-        props.put("bar", "bar:123");
-
-        OgnlUtil.setProperties(props, foo, context);
+        vs.setValue("bar", "bar:123");
 
         assertEquals("bar", foo.getBar().getTitle());
         assertEquals(123, foo.getBar().getSomethingElse());
     }
 
+    public void testSetDeepBarAsString() {
+        Foo foo = new Foo();
+        Foo foo2 = new Foo();
+        foo.setChild(foo2);
+
+        OgnlValueStack vs = new OgnlValueStack();
+        vs.push(foo);
+
+        vs.setValue("child.bar", "bar:123");
+
+        assertEquals("bar", foo.getChild().getBar().getTitle());
+        assertEquals(123, foo.getChild().getBar().getSomethingElse());
+    }
+
+    public void testSetReallyDeepBarAsString() {
+        Foo foo = new Foo();
+        Foo foo2 = new Foo();
+        foo.setChild(foo2);
+        Foo foo3 = new Foo();
+        foo2.setChild(foo3);
+
+        OgnlValueStack vs = new OgnlValueStack();
+        vs.push(foo);
+
+        vs.setValue("child.child.bar", "bar:123");
+
+        assertEquals("bar", foo.getChild().getChild().getBar().getTitle());
+        assertEquals(123, foo.getChild().getChild().getBar().getSomethingElse());
+    }
+
+    public void testGetBarAsString() {
+        Foo foo = new Foo();
+        Bar bar = new Bar();
+        bar.setTitle("bar");
+        bar.setSomethingElse(123);
+        foo.setBar(bar);
+
+        OgnlValueStack vs = new OgnlValueStack();
+        vs.push(foo);
+
+        String output = (String) vs.findValue("bar", String.class);
+        assertEquals("bar:123", output);
+    }
+
+    public void testGetComplexBarAsString() {
+        // children foo->foo->foo
+        Foo foo = new Foo();
+        Foo foo2 = new Foo();
+        foo.setChild(foo2);
+        Foo foo3 = new Foo();
+        foo2.setChild(foo3);
+
+        // relatives
+        Foo fooA = new Foo();
+        foo.setRelatives(new Foo[]{fooA});
+        Foo fooB = new Foo();
+        foo2.setRelatives(new Foo[]{fooB});
+        Foo fooC = new Foo();
+        foo3.setRelatives(new Foo[]{fooC});
+
+        // the bar
+        Bar bar = new Bar();
+        bar.setTitle("bar");
+        bar.setSomethingElse(123);
+
+        // now place the bar all over
+        foo.setBar(bar);
+        foo2.setBar(bar);
+        foo3.setBar(bar);
+        fooA.setBar(bar);
+        fooB.setBar(bar);
+        fooC.setBar(bar);
+
+        OgnlValueStack vs = new OgnlValueStack();
+        vs.push(foo);
+
+        assertEquals("bar:123", vs.findValue("bar", String.class));
+        assertEquals("bar:123", vs.findValue("child.bar", String.class));
+        assertEquals("bar:123", vs.findValue("child.child.bar", String.class));
+        assertEquals("bar:123", vs.findValue("relatives[0].bar", String.class));
+        assertEquals("bar:123", vs.findValue("child.relatives[0].bar", String.class));
+        assertEquals("bar:123", vs.findValue("child.child.relatives[0].bar", String.class));
+    }
+
     public void testMapEntriesAvailableByKey() {
         Foo foo = new Foo();
         String title = "a title";
         Map map = new HashMap();
         String a_key = "a";
         String a_value = "A";
-        map.put(a_key,a_value);
+        map.put(a_key, a_value);
         String b_key = "b";
         String b_value = "B";
-        map.put(b_key,b_value);
+        map.put(b_key, b_value);
 
         vs.push(map);
 

src/test/com/opensymphony/xwork/validator/ModelDrivenValidationTest.java

 package com.opensymphony.xwork.validator;
 
-import com.opensymphony.xwork.Action;
-import com.opensymphony.xwork.ActionProxy;
-import com.opensymphony.xwork.ActionProxyFactory;
-import com.opensymphony.xwork.ModelDrivenAction;
-import com.opensymphony.xwork.ActionContext;
+import com.opensymphony.xwork.*;
+import com.opensymphony.xwork.config.ConfigurationManager;
 import junit.framework.TestCase;
 
 import java.util.HashMap;
-import java.util.Map;
 import java.util.List;
+import java.util.Map;
 
 /**
  * ModelDrivenValidationTest
 
     public void testModelDrivenValidation() throws Exception {
         Map params = new HashMap();
-        params.put("count",new String[]{"11"});
+        params.put("count", new String[]{"11"});
         Map context = new HashMap();
         context.put(ActionContext.PARAMETERS, params);
-        ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(null,"TestModelDrivenValidation",context);
+        ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(null, "TestModelDrivenValidation", context);
         assertEquals(Action.SUCCESS, proxy.execute());
         ModelDrivenAction action = (ModelDrivenAction) proxy.getAction();
         assertTrue(action.hasFieldErrors());
         assertTrue(action.getFieldErrors().containsKey("count"));
-        assertEquals("count must be between 1 and 10, current value is 11.", ((List)action.getFieldErrors().get("count")).get(0));
+        assertEquals("count must be between 1 and 10, current value is 11.", ((List) action.getFieldErrors().get("count")).get(0));
     }
 
     protected void setUp() throws Exception {
+        ConfigurationManager.destroyConfiguration();
     }
 
     protected void tearDown() throws Exception {