Commits

Anonymous committed 0d3a305

Allow easy overriding of "excludeMethods" and "includeMethods" of ValidationInterceptor
Issue number: WW-1187
Obtained from:
Submitted by:
Reviewed by:

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

Comments (0)

Files changed (12)

src/java/com/opensymphony/xwork/DefaultActionInvocation.java

 
 import com.opensymphony.xwork.config.entities.ActionConfig;
 import com.opensymphony.xwork.config.entities.ResultConfig;
+import com.opensymphony.xwork.config.entities.InterceptorMapping;
 import com.opensymphony.xwork.interceptor.Interceptor;
 import com.opensymphony.xwork.interceptor.PreResultListener;
 import com.opensymphony.xwork.util.OgnlValueStack;
 
         ResultConfig resultConfig = null;
 
-        System.out.println("results: " + results);
         synchronized (config) {
             try {
                 resultConfig = (ResultConfig) results.get(resultCode);
         }
 
         if (interceptors.hasNext()) {
-            Interceptor interceptor = (Interceptor) interceptors.next();
-            resultCode = interceptor.intercept(this);
+            InterceptorMapping interceptor = (InterceptorMapping) interceptors.next();
+            resultCode = interceptor.getInterceptor().intercept(this);
         } else {
             resultCode = invokeActionOnly();
         }

src/java/com/opensymphony/xwork/config/entities/ActionConfig.java

  * <li>typeConverter - the Ognl TypeConverter to use when getting/setting properties</li>
  * </ul>
  *
- * @author $Author$
+ * @author Mike
+ * @author Rainer Hermanns
  * @version $Revision$
  */
 public class ActionConfig implements InterceptorListHolder, Parameterizable, Serializable {
         getExceptionMappings().addAll(exceptionMappings);
     }
 
-    public void addInterceptor(Interceptor interceptor) {
+    public void addInterceptor(InterceptorMapping interceptor) {
         getInterceptors().add(interceptor);
     }
 

src/java/com/opensymphony/xwork/config/entities/InterceptorListHolder.java

  */
 public interface InterceptorListHolder {
 
-    void addInterceptor(Interceptor interceptor);
+    void addInterceptor(InterceptorMapping interceptor);
 
     void addInterceptors(List interceptors);
 }

src/java/com/opensymphony/xwork/config/entities/InterceptorMapping.java

+/*
+ * Copyright (c) 2002-2006 by OpenSymphony
+ * All rights reserved.
+ */
+
+package com.opensymphony.xwork.config.entities;
+
+import com.opensymphony.xwork.interceptor.Interceptor;
+
+import java.io.Serializable;
+
+/**
+ * <code>InterceptorMapping</code>
+ *
+ * @author <a href="mailto:hermanns@aixcept.de">Rainer Hermanns</a>
+ * @version $Id$
+ */
+public class InterceptorMapping implements Serializable {
+
+    private String name;
+    private Interceptor interceptor;
+
+    public InterceptorMapping() {
+    }
+
+    public InterceptorMapping(String name, Interceptor interceptor) {
+        this.name = name;
+        this.interceptor = interceptor;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Interceptor getInterceptor() {
+        return interceptor;
+    }
+
+    public void setInterceptor(Interceptor interceptor) {
+        this.interceptor = interceptor;
+    }
+
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        final InterceptorMapping that = (InterceptorMapping) o;
+
+        if (name != null ? !name.equals(that.name) : that.name != null) return false;
+
+        return true;
+    }
+
+    public int hashCode() {
+        int result;
+        result = (name != null ? name.hashCode() : 0);
+        return result;
+    }
+}

src/java/com/opensymphony/xwork/config/entities/InterceptorStackConfig.java

  * In the xml configuration file this is defined as the <code>interceptor-stack</code> tag.
  *
  * @author Mike
+ * @author Rainer Hermanns
  */
 public class InterceptorStackConfig implements InterceptorListHolder, Serializable {
 
         return name;
     }
 
-    public void addInterceptor(Interceptor interceptor) {
+    public void addInterceptor(InterceptorMapping interceptor) {
         this.interceptors.add(interceptor);
     }
 

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

 package com.opensymphony.xwork.config.providers;
 
 import com.opensymphony.xwork.ObjectFactory;
+import com.opensymphony.xwork.interceptor.Interceptor;
 import com.opensymphony.xwork.config.ConfigurationException;
 import com.opensymphony.xwork.config.entities.InterceptorConfig;
 import com.opensymphony.xwork.config.entities.InterceptorStackConfig;
 import com.opensymphony.xwork.config.entities.PackageConfig;
+import com.opensymphony.xwork.config.entities.InterceptorMapping;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 
 /**
  * Builds a list of interceptors referenced by the refName in the supplied PackageConfig.
  * 
  * @author Mike
+ * @author Rainer Hermanns
  */
 public class InterceptorBuilder {
 
             LOG.error("Unable to find interceptor class referenced by ref-name " + refName);
         } else {
             if (referencedConfig instanceof InterceptorConfig) {
-                result.add(ObjectFactory.getObjectFactory().buildInterceptor((InterceptorConfig) referencedConfig, refParams));
+                result.add(new InterceptorMapping(refName, ObjectFactory.getObjectFactory().buildInterceptor((InterceptorConfig) referencedConfig, refParams)));
             } else if (referencedConfig instanceof InterceptorStackConfig) {
                 InterceptorStackConfig stackConfig = (InterceptorStackConfig) referencedConfig;
 
                 if ((refParams != null) && (refParams.size() > 0)) {
-                    LOG.warn("Interceptor-ref params are being ignored because they are applied to an Interceptor-Stack reference. Ref name = " + refName + ", params = " + refParams);
+                    result = constructParameterizedInterceptorReferences(packageConfig, stackConfig, refParams);
+                } else {
+                    result.addAll(stackConfig.getInterceptors());
                 }
 
-                result.addAll(stackConfig.getInterceptors());
             } else {
                 LOG.error("Got unexpected type for interceptor " + refName + ". Got " + referencedConfig);
             }
 
         return result;
     }
+
+    /**
+     * Builds a list of interceptors referenced by the refName in the supplied PackageConfig overriding the properties
+     * of the referenced interceptor with refParams.
+     * 
+     * @param packageConfig
+     * @param stackConfig
+     * @param refParams The overridden interceptor properies
+     * @return list of interceptors referenced by the refName in the supplied PackageConfig overridden with refParams.
+     */
+    private static List constructParameterizedInterceptorReferences(PackageConfig packageConfig, InterceptorStackConfig stackConfig, Map refParams) {
+        List result;
+        Map params = new HashMap();
+
+        for ( Iterator iter = refParams.keySet().iterator(); iter.hasNext();) {
+            String key = (String) iter.next();
+            String value = (String) refParams.get(key);
+
+            try {
+                String name = key.substring(0, key.indexOf('.'));
+                key = key.substring(key.indexOf('.')  + 1);
+
+                Map map;
+                if ( params.containsKey(name)) {
+                    map = (Map) params.get(name);
+                } else {
+                    map = new HashMap();
+                }
+
+                map.put(key, value);
+                params.put(name, map);
+
+            } catch (Exception e) {
+                LOG.warn("No interceptor found for name = " + key);
+            }
+        }
+
+        result = (ArrayList) stackConfig.getInterceptors();
+
+        for ( Iterator iter = params.keySet().iterator(); iter.hasNext();) {
+
+            String key = (String) iter.next();
+            Map map = (Map) params.get(key);
+
+            InterceptorConfig cfg = (InterceptorConfig) packageConfig.getAllInterceptorConfigs().get(key);
+            Interceptor interceptor = ObjectFactory.getObjectFactory().buildInterceptor(cfg, map);
+
+            InterceptorMapping mapping = new InterceptorMapping(key, interceptor);
+            if ( result != null && result.contains(mapping)) {
+                int index = result.indexOf(mapping);
+                result.set(index, mapping);
+            } else {
+                result.add(mapping);
+            }
+        }
+
+        return result;
+    }
 }

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

 import com.opensymphony.xwork.mock.MockInterceptor;
 import com.opensymphony.xwork.config.providers.MockConfigurationProvider;
 import com.opensymphony.xwork.config.providers.XmlConfigurationProvider;
+import com.opensymphony.xwork.config.entities.InterceptorMapping;
 
 import java.util.HashMap;
 
             ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy("/foo/bar", "TestInterceptorParamInehritanceOverride", null);
             assertEquals(1, proxy.getConfig().getInterceptors().size());
 
-            MockInterceptor testInterceptor = (MockInterceptor) proxy.getConfig().getInterceptors().get(0);
+            MockInterceptor testInterceptor = (MockInterceptor) ((InterceptorMapping) proxy.getConfig().getInterceptors().get(0)).getInterceptor();
             assertEquals("foo123", testInterceptor.getExpectedFoo());
             proxy.execute();
             assertTrue(testInterceptor.isExecuted());
             ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy("/foo/bar", "TestInterceptorParamInheritance", null);
             assertEquals(1, proxy.getConfig().getInterceptors().size());
 
-            MockInterceptor testInterceptor = (MockInterceptor) proxy.getConfig().getInterceptors().get(0);
+            MockInterceptor testInterceptor = (MockInterceptor) ((InterceptorMapping) proxy.getConfig().getInterceptors().get(0)).getInterceptor();
             assertEquals("expectedFoo", testInterceptor.getExpectedFoo());
             proxy.execute();
             assertTrue(testInterceptor.isExecuted());
             ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy("", "TestInterceptorParamOverride", null);
             assertEquals(1, proxy.getConfig().getInterceptors().size());
 
-            MockInterceptor testInterceptor = (MockInterceptor) proxy.getConfig().getInterceptors().get(0);
+            MockInterceptor testInterceptor = (MockInterceptor) ((InterceptorMapping) proxy.getConfig().getInterceptors().get(0)).getInterceptor();
             assertEquals("foo123", testInterceptor.getExpectedFoo());
             proxy.execute();
             assertTrue(testInterceptor.isExecuted());
             ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy("", "TestInterceptorParam", null);
             assertEquals(1, proxy.getConfig().getInterceptors().size());
 
-            MockInterceptor testInterceptor = (MockInterceptor) proxy.getConfig().getInterceptors().get(0);
+            MockInterceptor testInterceptor = (MockInterceptor) ((InterceptorMapping) proxy.getConfig().getInterceptors().get(0)).getInterceptor();
             assertEquals("expectedFoo", testInterceptor.getExpectedFoo());
             proxy.execute();
             assertTrue(testInterceptor.isExecuted());

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

 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.config.entities.InterceptorMapping;
 import com.opensymphony.xwork.interceptor.ModelDrivenInterceptor;
 import com.opensymphony.xwork.interceptor.ParametersInterceptor;
 import com.opensymphony.xwork.interceptor.StaticParametersInterceptor;
         results.put("success", new ResultConfig("success", ActionChainResult.class, successParams));
 
         List interceptors = new ArrayList();
-        interceptors.add(new ParametersInterceptor());
+        interceptors.add(new InterceptorMapping("params", new ParametersInterceptor()));
 
         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());
+        interceptors.add(new InterceptorMapping("model", new ModelDrivenInterceptor()));
+        interceptors.add(new InterceptorMapping("params", new ParametersInterceptor()));
 
         ActionConfig modelParamActionConfig = new ActionConfig(null, ModelDrivenAction.class, null, null, interceptors);
         defaultPackageContext.addActionConfig(MODEL_DRIVEN_PARAM_TEST, modelParamActionConfig);
         results.put("success", new ResultConfig("success", ActionChainResult.class, successParams));
 
         interceptors = new ArrayList();
-        interceptors.add(new StaticParametersInterceptor());
-        interceptors.add(new ModelDrivenInterceptor());
-        interceptors.add(new ParametersInterceptor());
-        interceptors.add(new ValidationInterceptor());
+        interceptors.add(new InterceptorMapping("static-params", new StaticParametersInterceptor()));
+        interceptors.add(new InterceptorMapping("model", new ModelDrivenInterceptor()));
+        interceptors.add(new InterceptorMapping("params", new ParametersInterceptor()));
+        interceptors.add(new InterceptorMapping("validation", new ValidationInterceptor()));
 
         //Explicitly set an out-of-range date for DateRangeValidatorTest
         params = new HashMap();

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

         results.put("success", new ResultConfig("success", MockResult.class, new HashMap()));
 
         InterceptorConfig timerInterceptorConfig = new InterceptorConfig("timer", TimerInterceptor.class, new HashMap());
-        interceptors.add(objectFactory.buildInterceptor(timerInterceptorConfig, new HashMap()));
+        interceptors.add(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptorConfig, new HashMap())));
 
         ActionConfig fooAction = new ActionConfig(null, SimpleAction.class, params, results, interceptors);
 
         interceptorParams.put("expectedFoo", "expectedFooValue");
         interceptorParams.put("foo", MockInterceptor.DEFAULT_FOO_VALUE);
 
-        InterceptorConfig mockInterceptorConfig = new InterceptorConfig("mock", MockInterceptor.class, new HashMap());
+        InterceptorConfig mockInterceptorConfig = new InterceptorConfig("test", MockInterceptor.class, new HashMap());
         interceptors = new ArrayList();
-        interceptors.add(objectFactory.buildInterceptor(mockInterceptorConfig, interceptorParams));
+        interceptors.add(new InterceptorMapping("test", objectFactory.buildInterceptor(mockInterceptorConfig, interceptorParams)));
 
         ActionConfig intAction = new ActionConfig(null, SimpleAction.class, new HashMap(), new HashMap(), interceptors);
 
         interceptorParams.put("expectedFoo", "expectedFooValue");
         interceptorParams.put("foo", "foo123");
         interceptors = new ArrayList();
-        interceptors.add(objectFactory.buildInterceptor(mockInterceptorConfig, interceptorParams));
+        interceptors.add(new InterceptorMapping("test", objectFactory.buildInterceptor(mockInterceptorConfig, interceptorParams)));
 
         ActionConfig intOverAction = new ActionConfig(null, SimpleAction.class, new HashMap(), new HashMap(), interceptors);
 

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

 import com.opensymphony.xwork.config.ConfigurationManager;
 import com.opensymphony.xwork.config.ConfigurationProvider;
 import com.opensymphony.xwork.config.RuntimeConfiguration;
-import com.opensymphony.xwork.config.entities.ActionConfig;
-import com.opensymphony.xwork.config.entities.InterceptorConfig;
-import com.opensymphony.xwork.config.entities.InterceptorStackConfig;
-import com.opensymphony.xwork.config.entities.PackageConfig;
+import com.opensymphony.xwork.config.entities.*;
 import com.opensymphony.xwork.interceptor.LoggingInterceptor;
 import com.opensymphony.xwork.interceptor.TimerInterceptor;
 
 
         // the default interceptor stack
         InterceptorStackConfig defaultStack = new InterceptorStackConfig("defaultStack");
-        defaultStack.addInterceptor(objectFactory.buildInterceptor(timerInterceptor, new HashMap()));
-        defaultStack.addInterceptor(objectFactory.buildInterceptor(mockInterceptor, params));
+        defaultStack.addInterceptor(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptor, new HashMap())));
+        defaultStack.addInterceptor(new InterceptorMapping("test", objectFactory.buildInterceptor(mockInterceptor, params)));
 
         // the derivative interceptor stack
         InterceptorStackConfig derivativeStack = new InterceptorStackConfig("derivativeStack");
-        derivativeStack.addInterceptor(objectFactory.buildInterceptor(timerInterceptor, new HashMap()));
-        derivativeStack.addInterceptor(objectFactory.buildInterceptor(mockInterceptor, params));
-        derivativeStack.addInterceptor(objectFactory.buildInterceptor(loggingInterceptor, new HashMap()));
+        derivativeStack.addInterceptor(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptor, new HashMap())));
+        derivativeStack.addInterceptor(new InterceptorMapping("test", objectFactory.buildInterceptor(mockInterceptor, params)));
+        derivativeStack.addInterceptor(new InterceptorMapping("logging", objectFactory.buildInterceptor(loggingInterceptor, new HashMap())));
 
         // execute the configuration
         provider.init(configuration);
         // expectations - the inherited interceptor stack
         // default package
         ArrayList interceptors = new ArrayList();
-        interceptors.add(objectFactory.buildInterceptor(loggingInterceptor, new HashMap()));
+        interceptors.add(new InterceptorMapping("logging", objectFactory.buildInterceptor(loggingInterceptor, new HashMap())));
 
         ActionConfig actionWithOwnRef = new ActionConfig(null, SimpleAction.class, new HashMap(), new HashMap(), interceptors);
 
         interceptors = new ArrayList();
-        interceptors.add(objectFactory.buildInterceptor(timerInterceptor, new HashMap()));
+        interceptors.add(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptor, new HashMap())));
 
         ActionConfig actionWithDefaultRef = new ActionConfig(null, SimpleAction.class, new HashMap(), new HashMap(), interceptors);
 
         ActionConfig actionWithNoRef = new ActionConfig(null, SimpleAction.class, new HashMap(), new HashMap(), interceptors);
 
         interceptors = new ArrayList();
-        interceptors.add(objectFactory.buildInterceptor(loggingInterceptor, new HashMap()));
+        interceptors.add(new InterceptorMapping("logging", objectFactory.buildInterceptor(loggingInterceptor, new HashMap())));
 
         ActionConfig anotherActionWithOwnRef = new ActionConfig(null, SimpleAction.class, new HashMap(), new HashMap(), interceptors);
 
 
         // expectations - the inherited interceptor stack
         InterceptorStackConfig inheritedStack = new InterceptorStackConfig("subDefaultStack");
-        inheritedStack.addInterceptor(objectFactory.buildInterceptor(timerInterceptor, new HashMap()));
+        inheritedStack.addInterceptor(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptor, new HashMap())));
 
         provider.init(configuration);
 
 
         // expectations - the inherited interceptor stack
         inheritedStack = new InterceptorStackConfig("subSubDefaultStack");
-        inheritedStack.addInterceptor(objectFactory.buildInterceptor(timerInterceptor, new HashMap()));
-        inheritedStack.addInterceptor(objectFactory.buildInterceptor(timerInterceptor, new HashMap()));
+        inheritedStack.addInterceptor(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptor, new HashMap())));
+        inheritedStack.addInterceptor(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptor, new HashMap())));
 
         PackageConfig subSubPkg = configuration.getPackageConfig("subSubPackage");
         assertEquals(1, subSubPkg.getInterceptorConfigs().size());
         assertEquals(inheritedStack, subSubPkg.getInterceptorConfigs().get("subSubDefaultStack"));
     }
 
+
+    public void testInterceptorParamOverriding() throws Exception {
+
+        XmlConfigurationProvider provider = new XmlConfigurationProvider("com/opensymphony/xwork/config/providers/xwork-test-interceptor-params.xml");
+
+        Map params = new HashMap();
+        params.put("foo", "expectedFoo");
+        params.put("expectedFoo", "expectedFooValue");
+
+        InterceptorStackConfig defaultStack = new InterceptorStackConfig("defaultStack");
+        defaultStack.addInterceptor(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptor, new HashMap())));
+        defaultStack.addInterceptor(new InterceptorMapping("test", objectFactory.buildInterceptor(mockInterceptor, params)));
+
+        ArrayList interceptors = new ArrayList();
+        interceptors.addAll(defaultStack.getInterceptors());
+
+        ActionConfig intAction = new ActionConfig(null, SimpleAction.class, new HashMap(), new HashMap(), interceptors);
+
+        // TestInterceptorParamOverride action tests that an interceptor with a param override worked
+        HashMap interceptorParams = new HashMap();
+        interceptorParams.put("expectedFoo", "expectedFooValue2");
+        interceptorParams.put("foo", "foo123");
+        interceptors = new ArrayList();
+
+        InterceptorStackConfig defaultStack2 = new InterceptorStackConfig("defaultStack");
+        defaultStack2.addInterceptor(new InterceptorMapping("timer", objectFactory.buildInterceptor(timerInterceptor, new HashMap())));
+        defaultStack2.addInterceptor(new InterceptorMapping("test", objectFactory.buildInterceptor(mockInterceptor, interceptorParams)));
+
+        interceptors = new ArrayList();
+
+        interceptors.addAll(defaultStack2.getInterceptors());
+
+        ActionConfig intOverAction = new ActionConfig(null, SimpleAction.class, new HashMap(), new HashMap(), interceptors);
+
+        // execute the configuration
+        provider.init(configuration);
+
+        PackageConfig pkg = configuration.getPackageConfig("default");
+        Map actionConfigs = pkg.getActionConfigs();
+
+        // assertions
+        assertEquals(2, actionConfigs.size());
+        assertEquals(intAction, actionConfigs.get("TestInterceptorParam"));
+        assertEquals(intOverAction, actionConfigs.get("TestInterceptorParamOverride"));
+
+        ActionConfig ac = (ActionConfig) actionConfigs.get("TestInterceptorParamOverride");
+        assertEquals(defaultStack.getInterceptors(), ac.getInterceptors());
+
+        ActionConfig ac2 = (ActionConfig) actionConfigs.get("TestInterceptorParam");
+        assertEquals(defaultStack2.getInterceptors(), ac2.getInterceptors());
+
+    }
+
     protected void setUp() throws Exception {
         super.setUp();
 

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

 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.config.entities.InterceptorMapping;
 import com.opensymphony.xwork.interceptor.ParametersInterceptor;
 import junit.framework.Assert;
 
         assertNotNull(actionConfig);
         assertNotNull(actionConfig.getInterceptors());
         assertEquals(2, actionConfig.getInterceptors().size());
-        assertEquals(ParametersInterceptor.class, actionConfig.getInterceptors().get(0).getClass());
+        assertEquals(ParametersInterceptor.class, ((InterceptorMapping) actionConfig.getInterceptors().get(0)).getInterceptor().getClass());
         assertNotNull(actionConfig.getResults());
         assertEquals(1, actionConfig.getResults().size());
         assertTrue(actionConfig.getResults().containsKey("success"));

src/test/com/opensymphony/xwork/config/providers/xwork-test-interceptor-params.xml

+<!DOCTYPE xwork PUBLIC
+        "-//OpenSymphony Group//XWork 1.1.1//EN"
+        "http://www.opensymphony.com/xwork/xwork-1.1.1.dtd"
+        >
+
+<xwork>
+    <package name="default">
+        <interceptors>
+            <interceptor name="timer" class="com.opensymphony.xwork.interceptor.TimerInterceptor"/>
+            <interceptor name="test" class="com.opensymphony.xwork.mock.MockInterceptor">
+                <param name="foo">fooDefault</param>
+            </interceptor>
+
+            <interceptor-stack name="defaultStack">
+                <interceptor-ref name="timer"/>
+                <interceptor-ref name="test"/>
+            </interceptor-stack>
+        </interceptors>
+
+        <default-interceptor-ref name="defaultStack" />
+
+        <action name="TestInterceptorParam" class="com.opensymphony.xwork.SimpleAction">
+            <interceptor-ref name="defaultStack">
+                <param name="test.expectedFoo">expectedFooValue</param>
+            </interceptor-ref>
+        </action>
+
+        <action name="TestInterceptorParamOverride" class="com.opensymphony.xwork.SimpleAction">
+            <interceptor-ref name="defaultStack">
+                <param name="test.foo">foo123</param>
+                <param name="test.expectedFoo">expectedFooValue2</param>
+            </interceptor-ref>
+        </action>
+    </package>
+
+</xwork>