Commits

Anonymous committed ffa506a

XW-64: Made ParametersInterceptor and StaticParametersInterceptor use the ValueStack to set properties so that properties on Model and Action will both be set.

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

Comments (0)

Files changed (8)

src/java/com/opensymphony/xwork/config/providers/XmlConfigurationProvider.java

                     // if <result ...>something</result> then we add a parameter of 'something' as this is the most used result param
                     if ((resultElement.getChildNodes().getLength() == 1) && (resultElement.getChildNodes().item(0).getNodeType() == Node.TEXT_NODE)) {
                         params = new HashMap();
+
                         try {
                             String paramName = (String) resultClass.getField("DEFAULT_PARAM").get(null);
                             params.put(paramName, resultElement.getChildNodes().item(0).getNodeValue());

src/java/com/opensymphony/xwork/interceptor/ParametersInterceptor.java

  */
 package com.opensymphony.xwork.interceptor;
 
-import com.opensymphony.xwork.Action;
 import com.opensymphony.xwork.ActionContext;
 import com.opensymphony.xwork.ActionInvocation;
-import com.opensymphony.xwork.ModelDriven;
-import com.opensymphony.xwork.util.OgnlUtil;
+import com.opensymphony.xwork.util.OgnlValueStack;
+
+import java.util.Iterator;
+import java.util.Map;
 
 
 /**
     }
 
     protected void before(ActionInvocation invocation) throws Exception {
-        Action action = invocation.getAction();
+        final Map parameters = ActionContext.getContext().getParameters();
 
         if (log.isDebugEnabled()) {
-            log.debug("Setting params " + ActionContext.getContext().getParameters());
+            log.debug("Setting params " + parameters);
         }
 
-        // populate model bean's fields if action is ModelDriven, otherwise populate action's fields
-        if (action instanceof ModelDriven) {
-            OgnlUtil.setProperties(ActionContext.getContext().getParameters(), ((ModelDriven) action).getModel(), ActionContext.getContext().getContextMap());
-        } else {
-            OgnlUtil.setProperties(ActionContext.getContext().getParameters(), action, ActionContext.getContext().getContextMap());
+        if (parameters != null) {
+            final OgnlValueStack stack = ActionContext.getContext().getValueStack();
+
+            for (Iterator iterator = parameters.entrySet().iterator();
+                    iterator.hasNext();) {
+                Map.Entry entry = (Map.Entry) iterator.next();
+                stack.setValue(entry.getKey().toString(), entry.getValue());
+            }
         }
     }
 }

src/java/com/opensymphony/xwork/interceptor/StaticParametersInterceptor.java

 import com.opensymphony.xwork.Action;
 import com.opensymphony.xwork.ActionContext;
 import com.opensymphony.xwork.ActionInvocation;
-import com.opensymphony.xwork.ModelDriven;
 import com.opensymphony.xwork.config.entities.ActionConfig;
 import com.opensymphony.xwork.config.entities.Parameterizable;
-import com.opensymphony.xwork.util.OgnlUtil;
+import com.opensymphony.xwork.util.OgnlValueStack;
+
+import java.util.Iterator;
+import java.util.Map;
 
 
 /**
         ActionConfig config = invocation.getProxy().getConfig();
         Action action = invocation.getAction();
 
+        final Map parameters = config.getParams();
+
         if (log.isDebugEnabled()) {
-            log.debug("Setting static params " + config.getParams());
+            log.debug("Setting static parameters " + parameters);
         }
 
-        // for actions marked as Parameterizable, pass the static params directly
+        // for actions marked as Parameterizable, pass the static parameters directly
         if (action instanceof Parameterizable) {
-            ((Parameterizable) action).setParams(config.getParams());
+            ((Parameterizable) action).setParams(parameters);
         }
 
-        // populate model bean's fields if action is ModelDriven, otherwise populate action's fields
-        if (action instanceof ModelDriven) {
-            OgnlUtil.setProperties(config.getParams(), ((ModelDriven) action).getModel(), ActionContext.getContext().getContextMap());
-        } else {
-            OgnlUtil.setProperties(config.getParams(), action, ActionContext.getContext().getContextMap());
+        if (parameters != null) {
+            final OgnlValueStack stack = ActionContext.getContext().getValueStack();
+
+            for (Iterator iterator = parameters.entrySet().iterator();
+                    iterator.hasNext();) {
+                Map.Entry entry = (Map.Entry) iterator.next();
+                stack.setValue(entry.getKey().toString(), entry.getValue());
+            }
         }
     }
 }

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

     //~ Methods ////////////////////////////////////////////////////////////////
 
     /**
-    * Sets the object's properties using the default type converter.
-    *
-    * @param props the properties being set
-    * @param o the object
-    * @param context the action context
-    */
+* Sets the object's properties using the default type converter.
+*
+* @param props the properties being set
+* @param o the object
+* @param context the action context
+*/
     public static void setProperties(Map props, Object o, Map context) {
         if (props == null) {
             return;
             Map.Entry entry = (Map.Entry) iterator.next();
             String expression = (String) entry.getKey();
 
-            try {
-                Ognl.setValue(compile(expression), context, o, entry.getValue());
-            } catch (OgnlException e) {
-                // ignore, this happens a lot
-            }
+            internalSetProperty(expression, entry.getValue(), o, context);
         }
 
         Ognl.setRoot(context, oldRoot);
     }
 
     /**
-    * Sets the properties on the object using the default context
-    * @param properties
-    * @param o
-    */
+* Sets the properties on the object using the default context
+* @param properties
+* @param o
+*/
     public static void setProperties(Map properties, Object o) {
         Map context = Ognl.createDefaultContext(o);
-        Ognl.setTypeConverter(context, XWorkConverter.getInstance());
         setProperties(properties, o, context);
     }
 
     /**
-    * Sets the named property to the supplied value on the Object
-    * @param name the name of the property to be set
-    * @param value the value to set into the named property
-    * @param o the object upon which to set the property
-    * @param context the context which may include the TypeConverter
-    */
+* Sets the named property to the supplied value on the Object
+* @param name the name of the property to be set
+* @param value the value to set into the named property
+* @param o the object upon which to set the property
+* @param context the context which may include the TypeConverter
+*/
     public static void setProperty(String name, Object value, Object o, Map context) {
         Ognl.setTypeConverter(context, XWorkConverter.getInstance());
 
         Object oldRoot = Ognl.getRoot(context);
         Ognl.setRoot(context, o);
 
-        try {
-            Ognl.setValue(compile(name), context, o, value);
-        } catch (OgnlException e) {
-            // ignore, this happens a lot
-        }
+        internalSetProperty(name, value, o, context);
 
         Ognl.setRoot(context, oldRoot);
     }
     }
 
     /**
-    * Copies the properties in the object "from" and sets them in the object "to"
-    * using specified type converter, or {@link com.opensymphony.xwork.util.XWorkConverter} if none is specified.
-    *
-    * @param from the source object
-    * @param to the target object
-    * @param context the action context we're running under
-    */
+* Copies the properties in the object "from" and sets them in the object "to"
+* using specified type converter, or {@link com.opensymphony.xwork.util.XWorkConverter} if none is specified.
+*
+* @param from the source object
+* @param to the target object
+* @param context the action context we're running under
+*/
     public static void copy(Object from, Object to, Map context) {
         Map contextFrom = Ognl.createDefaultContext(from);
         Ognl.setTypeConverter(contextFrom, XWorkConverter.getInstance());
             }
         }
     }
+
+    static void internalSetProperty(String name, Object value, Object o, Map context) {
+        try {
+            Ognl.setValue(compile(name), context, o, value);
+        } catch (OgnlException e) {
+            // ignore, this happens a lot
+        }
+    }
 }

src/test/com/opensymphony/xwork/ModelDrivenAction.java

  */
 package com.opensymphony.xwork;
 
-import java.util.Date;
-
 
 /**
  * ModelDrivenAction
 public class ModelDrivenAction extends ActionSupport implements ModelDriven {
     //~ Instance fields ////////////////////////////////////////////////////////
 
-    private Date date = new Date();
+    private String foo;
+    private TestBean model = new TestBean();
 
     //~ Methods ////////////////////////////////////////////////////////////////
 
-    public Date getDate() {
-        return date;
+    public void setFoo(String foo) {
+        this.foo = foo;
+    }
+
+    public String getFoo() {
+        return foo;
     }
 
     /**
-     * @return the model to be pushed onto the ValueStack instead of the Action itself
-     */
+ * @return the model to be pushed onto the ValueStack after the Action itself
+ */
     public Object getModel() {
-        return date;
+        return model;
     }
 }

src/test/com/opensymphony/xwork/config/TestConfigurationProvider.java

-/*
- * Copyright (c) 2002-2003 by OpenSymphony
- * All rights reserved.
- */
-package com.opensymphony.xwork.config;
-
-import com.opensymphony.xwork.Action;
-import com.opensymphony.xwork.ActionChainResult;
-import com.opensymphony.xwork.ModelDrivenAction;
-import com.opensymphony.xwork.SimpleAction;
-import com.opensymphony.xwork.config.entities.ActionConfig;
-import com.opensymphony.xwork.config.entities.PackageConfig;
-import com.opensymphony.xwork.config.entities.ResultConfig;
-import com.opensymphony.xwork.interceptor.ParametersInterceptor;
-import com.opensymphony.xwork.interceptor.StaticParametersInterceptor;
-import com.opensymphony.xwork.validator.ValidationInterceptor;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-
-/**
- * TestConfigurationProvider provides a simple configuration class without the need for xml files, etc. for simple testing.
- *
- * @author $author$
- * @version $Revision$
- */
-public class TestConfigurationProvider implements ConfigurationProvider {
-    //~ Static fields/initializers /////////////////////////////////////////////
-
-    public static final String FOO_ACTION_NAME = "foo";
-    public static final String MODEL_DRIVEN_ACTION_NAME = "model";
-    public static final String PARAM_INTERCEPTOR_ACTION_NAME = "parametersInterceptorTest";
-    public static final String VALIDATION_ACTION_NAME = "validationInterceptorTest";
-    public static final String VALIDATION_ALIAS_NAME = "validationAlias";
-
-    //~ Methods ////////////////////////////////////////////////////////////////
-
-    /**
-    * Allows the configuration to clean up any resources used
-    */
-    public void destroy() {
-    }
-
-    /**
-    * Initializes the configuration object.
-    */
-    public void init(Configuration configurationManager) {
-        PackageConfig defaultPackageConfig = new PackageConfig();
-
-        HashMap results = new HashMap();
-        HashMap successParams = new HashMap();
-        successParams.put("actionName", "bar");
-
-        ResultConfig resultConfig = new ResultConfig("chain", ActionChainResult.class, successParams);
-        results.put(Action.SUCCESS, resultConfig);
-
-        HashMap params = new HashMap();
-        params.put("bar", "5");
-
-        ActionConfig fooActionConfig = new ActionConfig(null, SimpleAction.class, params, results, null);
-        defaultPackageConfig.addActionConfig(FOO_ACTION_NAME, fooActionConfig);
-
-        results = new HashMap();
-        successParams = new HashMap();
-        successParams.put("actionName", "bar");
-        resultConfig = new ResultConfig("chain", ActionChainResult.class, successParams);
-        results.put(Action.SUCCESS, resultConfig);
-
-        List interceptors = new ArrayList();
-        interceptors.add(new ParametersInterceptor());
-
-        ActionConfig paramInterceptorActionConfig = new ActionConfig(null, SimpleAction.class, null, results, interceptors);
-        defaultPackageConfig.addActionConfig(PARAM_INTERCEPTOR_ACTION_NAME, paramInterceptorActionConfig);
-
-        results = new HashMap();
-        results.put(Action.SUCCESS, ActionChainResult.class);
-
-        results = new HashMap();
-        successParams = new HashMap();
-        successParams.put("actionName", "bar");
-        resultConfig = new ResultConfig("chain", ActionChainResult.class, successParams);
-        results.put(Action.SUCCESS, resultConfig);
-
-        interceptors = new ArrayList();
-        interceptors.add(new StaticParametersInterceptor());
-        interceptors.add(new ParametersInterceptor());
-        interceptors.add(new ValidationInterceptor());
-
-        ActionConfig validationActionConfig = new ActionConfig(null, SimpleAction.class, null, results, interceptors);
-        defaultPackageConfig.addActionConfig(VALIDATION_ACTION_NAME, validationActionConfig);
-        defaultPackageConfig.addActionConfig(VALIDATION_ALIAS_NAME, validationActionConfig);
-
-        ActionConfig modelActionConfig = new ActionConfig(null, ModelDrivenAction.class, null, null, null);
-        defaultPackageConfig.addActionConfig(MODEL_DRIVEN_ACTION_NAME, modelActionConfig);
-
-        // We need this actionconfig to be the final destination for action chaining
-        ActionConfig barActionConfig = new ActionConfig(null, SimpleAction.class, null, null, null);
-        defaultPackageConfig.addActionConfig("bar", barActionConfig);
-
-        configurationManager.addPackageConfig("defaultPackage", defaultPackageConfig);
-    }
-
-    /**
-     * Tells whether the ConfigurationProvider should reload its configuration
-     * @return
-     */
-    public boolean needsReload() {
-        return false;
-    }
-}

src/test/com/opensymphony/xwork/config/providers/MockConfigurationProvider.java

 package com.opensymphony.xwork.config.providers;
 
 import com.opensymphony.xwork.ActionChainResult;
+import com.opensymphony.xwork.ModelDrivenAction;
 import com.opensymphony.xwork.SimpleAction;
 import com.opensymphony.xwork.config.Configuration;
 import com.opensymphony.xwork.config.ConfigurationProvider;
     //~ Static fields/initializers /////////////////////////////////////////////
 
     public static final String FOO_ACTION_NAME = "foo";
-    public static final String MODEL_DRIVEN_ACTION_NAME = "model";
+    public static final String MODEL_DRIVEN_PARAM_TEST = "modelParamTest";
     public static final String PARAM_INTERCEPTOR_ACTION_NAME = "parametersInterceptorTest";
     public static final String VALIDATION_ACTION_NAME = "validationInterceptorTest";
     public static final String VALIDATION_ALIAS_NAME = "validationAlias";
         ActionConfig paramInterceptorActionConfig = new ActionConfig(null, SimpleAction.class, null, results, interceptors);
         defaultPackageContext.addActionConfig(PARAM_INTERCEPTOR_ACTION_NAME, paramInterceptorActionConfig);
 
+        interceptors = new ArrayList();
+        interceptors.add(new ModelDrivenInterceptor());
+        interceptors.add(new ParametersInterceptor());
+
+        ActionConfig modelParamActionConfig = new ActionConfig(null, ModelDrivenAction.class, null, null, interceptors);
+        defaultPackageContext.addActionConfig(MODEL_DRIVEN_PARAM_TEST, modelParamActionConfig);
+
         results = new HashMap();
         successParams = new HashMap();
         successParams.put("actionName", "bar");

src/test/com/opensymphony/xwork/interceptor/ParametersInterceptorTest.java

  */
 package com.opensymphony.xwork.interceptor;
 
+import com.opensymphony.xwork.Action;
 import com.opensymphony.xwork.ActionContext;
 import com.opensymphony.xwork.ActionProxy;
 import com.opensymphony.xwork.ActionProxyFactory;
+import com.opensymphony.xwork.ModelDrivenAction;
 import com.opensymphony.xwork.SimpleAction;
+import com.opensymphony.xwork.TestBean;
 import com.opensymphony.xwork.config.ConfigurationManager;
 import com.opensymphony.xwork.config.providers.MockConfigurationProvider;
 
 import junit.framework.TestCase;
 
 import java.util.HashMap;
+import java.util.Map;
 
 
 /**
 public class ParametersInterceptorTest extends TestCase {
     //~ Methods ////////////////////////////////////////////////////////////////
 
+    public void testModelDrivenParameters() {
+        Map params = new HashMap();
+        final String fooVal = "com.opensymphony.xwork.interceptor.ParametersInterceptorTest.foo";
+        params.put("foo", fooVal);
+
+        final String nameVal = "com.opensymphony.xwork.interceptor.ParametersInterceptorTest.name";
+        params.put("name", nameVal);
+        params.put("count", "15");
+
+        HashMap extraContext = new HashMap();
+        extraContext.put(ActionContext.PARAMETERS, params);
+
+        try {
+            ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy("", MockConfigurationProvider.MODEL_DRIVEN_PARAM_TEST, extraContext);
+            assertEquals(Action.SUCCESS, proxy.execute());
+
+            ModelDrivenAction action = (ModelDrivenAction) proxy.getAction();
+            TestBean model = (TestBean) action.getModel();
+            assertEquals(nameVal, model.getName());
+            assertEquals(15, model.getCount());
+            assertEquals(fooVal, action.getFoo());
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail();
+        }
+    }
+
     public void testParameters() {
-        HashMap params = new HashMap();
+        Map params = new HashMap();
         params.put("blah", "This is blah");
 
         HashMap extraContext = new HashMap();