Commits

Anonymous committed 09adc23

Pulling out ValueStack interface for OgnlValueStack and giving it factory creation
XW-418

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

Comments (0)

Files changed (60)

src/java/com/opensymphony/xwork2/ActionChainResult.java

 package com.opensymphony.xwork2;
 
 import com.opensymphony.xwork2.config.Configuration;
-import com.opensymphony.xwork2.util.OgnlValueStack;
 import com.opensymphony.xwork2.util.TextParseUtil;
+import com.opensymphony.xwork2.util.ValueStack;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
             this.namespace = invocation.getProxy().getNamespace();
         }
 
-        OgnlValueStack stack = ActionContext.getContext().getValueStack();
+        ValueStack stack = ActionContext.getContext().getValueStack();
         String finalNamespace = TextParseUtil.translateVariables(namespace, stack);
         String finalActionName = TextParseUtil.translateVariables(actionName, stack);
         String finalMethodName = this.methodName != null 

src/java/com/opensymphony/xwork2/ActionContext.java

  */
 package com.opensymphony.xwork2;
 
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
 
 import java.io.Serializable;
 import java.util.HashMap;
     public static final String ACTION_NAME = "com.opensymphony.xwork2.ActionContext.name";
 
     /**
-     * Constant for the {@link com.opensymphony.xwork2.util.OgnlValueStack OGNL value stack}.
+     * Constant for the {@link com.opensymphony.xwork2.util.ValueStack OGNL value stack}.
      */
-    public static final String VALUE_STACK = OgnlValueStack.VALUE_STACK;
+    public static final String VALUE_STACK = ValueStack.VALUE_STACK;
 
     /**
      * Constant for the action's session.
         ActionContext context = (ActionContext) actionContext.get();
 
         if (context == null) {
-            OgnlValueStack vs = new OgnlValueStack();
+            ValueStack vs = ValueStackFactory.getFactory().createValueStack();
             context = new ActionContext(vs.getContext());
             setContext(context);
         }
      *
      * @param stack the OGNL value stack.
      */
-    public void setValueStack(OgnlValueStack stack) {
+    public void setValueStack(ValueStack stack) {
         put(VALUE_STACK, stack);
     }
 
      *
      * @return the OGNL value stack.
      */
-    public OgnlValueStack getValueStack() {
-        return (OgnlValueStack) get(VALUE_STACK);
+    public ValueStack getValueStack() {
+        return (ValueStack) get(VALUE_STACK);
     }
 
     /**
 
     private static class ActionContextThreadLocal extends ThreadLocal {
         protected Object initialValue() {
-            OgnlValueStack vs = new OgnlValueStack();
+            ValueStack vs = ValueStackFactory.getFactory().createValueStack();
 
             return new ActionContext(vs.getContext());
         }

src/java/com/opensymphony/xwork2/ActionInvocation.java

 package com.opensymphony.xwork2;
 
 import com.opensymphony.xwork2.interceptor.PreResultListener;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
 
 import java.io.Serializable;
 
     /**
      * @return the ValueStack associated with this ActionInvocation
      */
-    OgnlValueStack getStack();
+    ValueStack getStack();
 
     /**
      * Register a com.opensymphony.xwork2.interceptor.PreResultListener to be notified after the Action is executed and

src/java/com/opensymphony/xwork2/ActionSupport.java

  */
 package com.opensymphony.xwork2;
 
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
         return textProvider.getText(key, defaultValue, args);
     }
 
-    public String getText(String key, String defaultValue, List args, OgnlValueStack stack) {
+    public String getText(String key, String defaultValue, List args, ValueStack stack) {
         return textProvider.getText(key, defaultValue, args, stack);
     }
 
-    public String getText(String key, String defaultValue, String[] args, OgnlValueStack stack) {
+    public String getText(String key, String defaultValue, String[] args, ValueStack stack) {
         return textProvider.getText(key, defaultValue, args, stack);
     }
 

src/java/com/opensymphony/xwork2/DefaultActionInvocation.java

 import com.opensymphony.xwork2.config.entities.InterceptorMapping;
 import com.opensymphony.xwork2.config.entities.ResultConfig;
 import com.opensymphony.xwork2.interceptor.PreResultListener;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
 import com.opensymphony.xwork2.util.XWorkContinuationConfig;
 import com.uwyn.rife.continuations.ContinuableObject;
 import com.uwyn.rife.continuations.ContinuationConfig;
     protected Map extraContext;
     protected ActionContext invocationContext;
     protected Iterator interceptors;
-    protected OgnlValueStack stack;
+    protected ValueStack stack;
     protected Result result;
     protected String resultCode;
     protected boolean executed = false;
     }
 
 
-    public OgnlValueStack getStack() {
+    public ValueStack getStack() {
         return stack;
     }
 
 
         if ((extraContext != null) && (extraContext.containsKey(ActionContext.VALUE_STACK))) {
             // In case the ValueStack was passed in
-            stack = (OgnlValueStack) extraContext.get(ActionContext.VALUE_STACK);
+            stack = (ValueStack) extraContext.get(ActionContext.VALUE_STACK);
 
             if (stack == null) {
                 throw new IllegalStateException("There was a null Stack set into the extra params.");
         } else {
             // create the value stack
             // this also adds the ValueStack to its context
-            stack = new OgnlValueStack();
+            stack = ValueStackFactory.getFactory().createValueStack();
 
             // create the action context
             contextMap = stack.getContext();
             }
         }
         
-        public void prepareContinuation(Object action, OgnlValueStack stack) {
+        public void prepareContinuation(Object action, ValueStack stack) {
             if (action instanceof ContinuableObject) {
                 ContinuationContext ctx = ContinuationContext.createInstance((ContinuableObject) action);
                 if (action instanceof NonCloningContinuableObject) {
 
         }
         
-        public String handleException(Throwable t, OgnlValueStack stack) {
+        public String handleException(Throwable t, ValueStack stack) {
             if (t instanceof PauseException) {
                 // continuations in effect!
                 PauseException pe = ((PauseException) t);

src/java/com/opensymphony/xwork2/DefaultTextProvider.java

 package com.opensymphony.xwork2;
 
 import com.opensymphony.xwork2.util.LocalizedTextUtil;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
 
 import java.io.ObjectStreamException;
 import java.io.Serializable;
         return getText(key, defaultValue, args);
     }
 
-    public String getText(String key, String defaultValue, List args, OgnlValueStack stack) {
+    public String getText(String key, String defaultValue, List args, ValueStack stack) {
         //we're not using the value stack here
         return getText(key, defaultValue, args);
     }
 
-    public String getText(String key, String defaultValue, String[] args, OgnlValueStack stack) {
+    public String getText(String key, String defaultValue, String[] args, ValueStack stack) {
         //we're not using the value stack here
         return getText(key, defaultValue, Arrays.asList(args));
     }

src/java/com/opensymphony/xwork2/TextProvider.java

  */
 package com.opensymphony.xwork2;
 
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
 
 import java.util.List;
 import java.util.ResourceBundle;
      * @param stack        the value stack to use for finding the text
      * @return the message as found in the resource bundle, or defaultValue if none is found
      */
-    String getText(String key, String defaultValue, List args, OgnlValueStack stack);
+    String getText(String key, String defaultValue, List args, ValueStack stack);
 
     /**
      * Gets a message based on a key using the supplied args, as defined in
      * @param stack        the value stack to use for finding the text
      * @return the message as found in the resource bundle, or defaultValue if none is found
      */
-    String getText(String key, String defaultValue, String[] args, OgnlValueStack stack);
+    String getText(String key, String defaultValue, String[] args, ValueStack stack);
 
     /**
      * Get the named bundle, such as "com/acme/Foo".

src/java/com/opensymphony/xwork2/TextProviderSupport.java

 package com.opensymphony.xwork2;
 
 import com.opensymphony.xwork2.util.LocalizedTextUtil;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
 
 import java.util.*;
 
      * @param stack        the value stack to use for finding the text
      * @return the message as found in the resource bundle, or defaultValue if none is found
      */
-    public String getText(String key, String defaultValue, List args, OgnlValueStack stack) {
+    public String getText(String key, String defaultValue, List args, ValueStack stack) {
         Object[] argsArray = ((args != null) ? args.toArray() : null);
         Locale locale = (Locale) stack.getContext().get(ActionContext.LOCALE);
         if (locale == null) {
      * @param stack        the value stack to use for finding the text
      * @return the message as found in the resource bundle, or defaultValue if none is found
      */
-    public String getText(String key, String defaultValue, String[] args, OgnlValueStack stack) {
+    public String getText(String key, String defaultValue, String[] args, ValueStack stack) {
         Locale locale = (Locale) stack.getContext().get(ActionContext.LOCALE);
         if (locale == null) {
             locale = getLocale();

src/java/com/opensymphony/xwork2/XWorkTestCase.java

 import com.opensymphony.xwork2.config.ConfigurationManager;
 import com.opensymphony.xwork2.util.LocalizedTextUtil;
 import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
 import com.opensymphony.xwork2.util.XWorkConverter;
 import junit.framework.TestCase;
 
     
     protected void setUp() throws Exception {
         // Reset the value stack
-        OgnlValueStack stack = new OgnlValueStack();
+        ValueStack stack = new OgnlValueStack();
         ActionContext.setContext(new ActionContext(stack.getContext()));
 
         //  clear out configuration

src/java/com/opensymphony/xwork2/interceptor/AliasInterceptor.java

 import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.config.entities.ActionConfig;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
         if (parameters.containsKey(aliasesKey)) {
 
             String aliasExpression = (String) parameters.get(aliasesKey);
-            OgnlValueStack stack = ac.getValueStack();
+            ValueStack stack = ac.getValueStack();
             Object obj = stack.findValue(aliasExpression);
 
             if (obj != null && obj instanceof Map) {

src/java/com/opensymphony/xwork2/interceptor/ChainingInterceptor.java

 import com.opensymphony.xwork2.Unchainable;
 import com.opensymphony.xwork2.util.CompoundRoot;
 import com.opensymphony.xwork2.util.OgnlUtil;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
 
 import java.util.*;
 
     Collection includes;
 
     public String intercept(ActionInvocation invocation) throws Exception {
-        OgnlValueStack stack = invocation.getStack();
+        ValueStack stack = invocation.getStack();
         CompoundRoot root = stack.getRoot();
 
         if (root.size() > 1) {

src/java/com/opensymphony/xwork2/interceptor/ConversionErrorInterceptor.java

 import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.ValidationAware;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
 import com.opensymphony.xwork2.util.XWorkConverter;
 
 import java.util.HashMap;
 
         ActionContext invocationContext = invocation.getInvocationContext();
         Map conversionErrors = invocationContext.getConversionErrors();
-        OgnlValueStack stack = invocationContext.getValueStack();
+        ValueStack stack = invocationContext.getValueStack();
 
         HashMap fakie = null;
 

src/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptor.java

 
 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.ModelDriven;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
 
 
 /**
 
         if (action instanceof ModelDriven) {
             ModelDriven modelDriven = (ModelDriven) action;
-            OgnlValueStack stack = invocation.getStack();
+            ValueStack stack = invocation.getStack();
             if (modelDriven.getModel() !=  null) {
             	stack.push(modelDriven.getModel());
             }

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

  * This interceptor sets all parameters on the value stack.
  * <p/>
  * This interceptor gets all parameters from {@link ActionContext#getParameters()} and sets them on the value stack by
- * calling {@link OgnlValueStack#setValue(String, Object)}, typically resulting in the values submitted in a form
+ * calling {@link ValueStack#setValue(String, Object)}, typically resulting in the values submitted in a form
  * request being applied to an action in the value stack. Note that the parameter map must contain a String key and
  * often containers a String[] for the value.
  * 
                 	OgnlContextState.setDenyMethodExecution(contextMap, true);
                 	OgnlContextState.setReportingConversionErrors(contextMap, true);
 
-                    OgnlValueStack stack = ac.getValueStack();
+                    ValueStack stack = ac.getValueStack();
                     setParameters(action, stack, parameters);
                 } finally {
                 	OgnlContextState.setCreatingNullObjects(contextMap, false);
         return invocation.invoke();
     }
 
-    protected void setParameters(Object action, OgnlValueStack stack, final Map parameters) {
+    protected void setParameters(Object action, ValueStack stack, final Map parameters) {
         ParameterNameAware parameterNameAware = (action instanceof ParameterNameAware)
                 ? (ParameterNameAware) action : null;
 

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

 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.config.entities.ActionConfig;
 import com.opensymphony.xwork2.config.entities.Parameterizable;
-import com.opensymphony.xwork2.util.OgnlValueStack;
 import com.opensymphony.xwork2.util.TextParseUtil;
+import com.opensymphony.xwork2.util.ValueStack;
 
 import java.util.Iterator;
 import java.util.Map;
         }
 
         if (parameters != null) {
-            final OgnlValueStack stack = ActionContext.getContext().getValueStack();
+            final ValueStack stack = ActionContext.getContext().getValueStack();
 
             for (Iterator iterator = parameters.entrySet().iterator();
                  iterator.hasNext();) {

src/java/com/opensymphony/xwork2/mock/MockActionInvocation.java

 import com.opensymphony.xwork2.ActionProxy;
 import com.opensymphony.xwork2.Result;
 import com.opensymphony.xwork2.interceptor.PreResultListener;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
 
 /**
  * Mock for an {@link ActionInvocation}.
     private ActionProxy proxy;
     private Result result;
     private String resultCode;
-    private OgnlValueStack stack;
+    private ValueStack stack;
     
     private List preResultListeners = new ArrayList();
 
         this.resultCode = resultCode;
     }
 
-    public OgnlValueStack getStack() {
+    public ValueStack getStack() {
         return stack;
     }
 
-    public void setStack(OgnlValueStack stack) {
+    public void setStack(ValueStack stack) {
         this.stack = stack;
     }
 

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

             }
         }
 
-        Boolean reportError = (Boolean) context.get(OgnlValueStack.REPORT_ERRORS_ON_NO_PROP);
+        Boolean reportError = (Boolean) context.get(ValueStack.REPORT_ERRORS_ON_NO_PROP);
 
         final String msg = "No object in the CompoundRoot has a publicly accessible property named '" + name + "' (no setter could be found).";
 

src/java/com/opensymphony/xwork2/util/LocalizedTextUtil.java

      * @return the localized text, or null if none can be found and no defaultMessage is provided
      */
     public static String findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args) {
-        OgnlValueStack valueStack = ActionContext.getContext().getValueStack();
+        ValueStack valueStack = ActionContext.getContext().getValueStack();
         return findText(aClass, aTextName, locale, defaultMessage, args, valueStack);
 
     }
      *                       one in the ActionContext ThreadLocal
      * @return the localized text, or null if none can be found and no defaultMessage is provided
      */
-    public static String findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args, OgnlValueStack valueStack) {
+    public static String findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args, ValueStack valueStack) {
         String indexedTextName = null;
         if (aTextName == null) {
             LOG.warn("Trying to find text with null key!");
      * @param args       arguments for the message formatter.
      */
     public static String findText(ResourceBundle bundle, String aTextName, Locale locale, String defaultMessage, Object[] args) {
-        OgnlValueStack valueStack = ActionContext.getContext().getValueStack();
+        ValueStack valueStack = ActionContext.getContext().getValueStack();
         return findText(bundle, aTextName, locale, defaultMessage, args, valueStack);
     }
 
      * @param args       arguments for the message formatter.
      * @param valueStack the OGNL value stack.
      */
-    public static String findText(ResourceBundle bundle, String aTextName, Locale locale, String defaultMessage, Object[] args, OgnlValueStack valueStack) {
+    public static String findText(ResourceBundle bundle, String aTextName, Locale locale, String defaultMessage, Object[] args, ValueStack valueStack) {
         try {
             reloadBundles();
 
     /**
      * Gets the default message.
      */
-    private static GetDefaultMessageReturnArg getDefaultMessage(String key, Locale locale, OgnlValueStack valueStack, Object[] args, String defaultMessage) {
+    private static GetDefaultMessageReturnArg getDefaultMessage(String key, Locale locale, ValueStack valueStack, Object[] args, String defaultMessage) {
         GetDefaultMessageReturnArg result = null;
     	boolean found = true;
     	
     /**
      * Gets the message from the named resource bundle.
      */
-    private static String getMessage(String bundleName, Locale locale, String key, OgnlValueStack valueStack, Object[] args) {
+    private static String getMessage(String bundleName, Locale locale, String key, ValueStack valueStack, Object[] args) {
         ResourceBundle bundle = findResourceBundle(bundleName, locale);
         if (bundle == null) {
             return null;
      * Traverse up class hierarchy looking for message.  Looks at class, then implemented interface,
      * before going up hierarchy.
      */
-    private static String findMessage(Class clazz, String key, String indexedKey, Locale locale, Object[] args, Set checked, OgnlValueStack valueStack) {
+    private static String findMessage(Class clazz, String key, String indexedKey, Locale locale, Object[] args, Set checked, ValueStack valueStack) {
         if (checked == null) {
             checked = new TreeSet();
         } else if (checked.contains(clazz.getName())) {

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

 
 import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.DefaultTextProvider;
-import ognl.*;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-
+import ognl.*;
 import java.io.Serializable;
 import java.util.*;
 
 /**
- * OgnlValueStack allows multiple beans to be pushed in and dynamic Ognl expressions to be evaluated against it. When
+ * Ognl implementation of a value stack that allows for dynamic Ognl expressions to be evaluated against it. When
  * evaluating an expression, the stack will be searched down the stack, from the latest objects pushed in to the
  * earliest, looking for a bean with a getter or setter for the given property or a method of the given name (depending
  * on the expression being evaluated).
  * 
  * @version $Date$ $Id$
  */
-public class OgnlValueStack implements Serializable {
+public class OgnlValueStack implements Serializable, ValueStack {
 	
 	private static final long serialVersionUID = 370737852934925530L;
 	
-	public static final String VALUE_STACK = "com.opensymphony.xwork2.util.OgnlValueStack.ValueStack";
-    public static final String REPORT_ERRORS_ON_NO_PROP = "com.opensymphony.xwork2.util.OgnlValueStack.ReportErrorsOnNoProp";
-    private static CompoundRootAccessor accessor;
+	private static CompoundRootAccessor accessor;
     private static Log LOG = LogFactory.getLog(OgnlValueStack.class);
 
     static {
         push(DefaultTextProvider.INSTANCE);
     }
 
-    public OgnlValueStack(OgnlValueStack vs) {
+    public OgnlValueStack(ValueStack vs) {
         setRoot(new CompoundRoot(vs.getRoot()));
     }
 
         return accessor;
     }
 
+    /* (non-Javadoc)
+     * @see com.opensymphony.xwork2.util.ValueStack#getContext()
+     */
     public Map getContext() {
         return context;
     }
 
-    /**
-     * Sets the default type to convert to if no type is provided when getting a value.
-     *
-     * @param defaultType
+    /* (non-Javadoc)
+     * @see com.opensymphony.xwork2.util.ValueStack#setDefaultType(java.lang.Class)
      */
     public void setDefaultType(Class defaultType) {
         this.defaultType = defaultType;
     }
 
+    /* (non-Javadoc)
+     * @see com.opensymphony.xwork2.util.ValueStack#setExprOverrides(java.util.Map)
+     */
     public void setExprOverrides(Map overrides) {
     	if (this.overrides == null) {
     		this.overrides = overrides;
     	}
     }
     
+    /* (non-Javadoc)
+     * @see com.opensymphony.xwork2.util.ValueStack#getExprOverrides()
+     */
     public Map getExprOverrides() {
     	return this.overrides;
     }
 
-    /**
-     * Get the CompoundRoot which holds the objects pushed onto the stack
+    /* (non-Javadoc)
+     * @see com.opensymphony.xwork2.util.ValueStack#getRoot()
      */
     public CompoundRoot getRoot() {
         return root;
     }
 
-    /**
-     * Determine whether devMode is enabled.
-     *
-     * @return true if devMode was enabled, false otherwise.
+    /* (non-Javadoc)
+     * @see com.opensymphony.xwork2.util.ValueStack#isDevModeEnabled()
      */
     public boolean isDevModeEnabled() {
         Boolean devMode = (Boolean) context.get(ActionContext.DEV_MODE);
         }
     }
 
-    /**
-     * Attempts to set a property on a bean in the stack with the given expression using the default search order.
-     *
-     * @param expr  the expression defining the path to the property to be set.
-     * @param value the value to be set into the neamed property
+    /* (non-Javadoc)
+     * @see com.opensymphony.xwork2.util.ValueStack#setValue(java.lang.String, java.lang.Object)
      */
     public void setValue(String expr, Object value) {
         setValue(expr, value, isDevModeEnabled());
     }
 
-    /**
-     * Attempts to set a property on a bean in the stack with the given expression using the default search order.
-     *
-     * @param expr                    the expression defining the path to the property to be set.
-     * @param value                   the value to be set into the neamed property
-     * @param throwExceptionOnFailure a flag to tell whether an exception should be thrown if there is no property with
-     *                                the given name.
+    /* (non-Javadoc)
+     * @see com.opensymphony.xwork2.util.ValueStack#setValue(java.lang.String, java.lang.Object, boolean)
      */
     public void setValue(String expr, Object value, boolean throwExceptionOnFailure) {
         Map context = getContext();
         }
     }
 
+    /* (non-Javadoc)
+     * @see com.opensymphony.xwork2.util.ValueStack#findString(java.lang.String)
+     */
     public String findString(String expr) {
         return (String) findValue(expr, String.class);
     }
 
-    /**
-     * Find a value by evaluating the given expression against the stack in the default search order.
-     *
-     * @param expr the expression giving the path of properties to navigate to find the property value to return
-     * @return the result of evaluating the expression
+    /* (non-Javadoc)
+     * @see com.opensymphony.xwork2.util.ValueStack#findValue(java.lang.String)
      */
     public Object findValue(String expr) {
         try {
         }
     }
 
-    /**
-     * Find a value by evaluating the given expression against the stack in the default search order.
-     *
-     * @param expr   the expression giving the path of properties to navigate to find the property value to return
-     * @param asType the type to convert the return value to
-     * @return the result of evaluating the expression
+    /* (non-Javadoc)
+     * @see com.opensymphony.xwork2.util.ValueStack#findValue(java.lang.String, java.lang.Class)
      */
     public Object findValue(String expr, Class asType) {
         try {
         }
     }
 
-    /**
-     * Get the object on the top of the stack without changing the stack.
-     *
-     * @see CompoundRoot#peek()
+    /* (non-Javadoc)
+     * @see com.opensymphony.xwork2.util.ValueStack#peek()
      */
     public Object peek() {
         return root.peek();
     }
 
-    /**
-     * Get the object on the top of the stack and remove it from the stack.
-     *
-     * @return the object on the top of the stack
-     * @see CompoundRoot#pop()
+    /* (non-Javadoc)
+     * @see com.opensymphony.xwork2.util.ValueStack#pop()
      */
     public Object pop() {
         return root.pop();
     }
 
-    /**
-     * Put this object onto the top of the stack
-     *
-     * @param o the object to be pushed onto the stack
-     * @see CompoundRoot#push(Object)
+    /* (non-Javadoc)
+     * @see com.opensymphony.xwork2.util.ValueStack#push(java.lang.Object)
      */
     public void push(Object o) {
         root.push(o);
     }
-    /**
-     * Sets an object on the stack with the given key
-     * so it is retrievable by findValue(key,...)
-     * @param key
-     * @param o
+    /* (non-Javadoc)
+     * @see com.opensymphony.xwork2.util.ValueStack#set(java.lang.String, java.lang.Object)
      */
     public void set(String key, Object o) {
     	//set basically is backed by a Map
     
     private static final String MAP_IDENTIFIER_KEY="com.opensymphony.xwork2.util.OgnlValueStack.MAP_IDENTIFIER_KEY";
     
-    /**
-     * Get the number of objects in the stack
-     * s
-     *
-     * @return the number of objects in the stack
+    /* (non-Javadoc)
+     * @see com.opensymphony.xwork2.util.ValueStack#size()
      */
     public int size() {
         return root.size();

src/java/com/opensymphony/xwork2/util/OgnlValueStackFactory.java

+/*
+ * Copyright (c) 2002-2006 by OpenSymphony
+ * All rights reserved.
+ */
+package com.opensymphony.xwork2.util;
+
+/**
+ * Creates an Ognl value stack
+ */
+public class OgnlValueStackFactory extends ValueStackFactory {
+
+    @Override
+    public ValueStack createValueStack() {
+        return new OgnlValueStack();
+    }
+
+    @Override
+    public ValueStack createValueStack(ValueStack stack) {
+        return new OgnlValueStack(stack);
+    }
+
+}

src/java/com/opensymphony/xwork2/util/TextParseUtil.java

 
     /**
      * Converts all instances of ${...} in <code>expression</code> to the value returned
-     * by a call to {@link OgnlValueStack#findValue(java.lang.String)}. If an item cannot
+     * by a call to {@link ValueStack#findValue(java.lang.String)}. If an item cannot
      * be found on the stack (null is returned), then the entire variable ${...} is not
      * displayed, just as if the item was on the stack but returned an empty string.
      *
      * @param expression an expression that hasn't yet been translated
      * @return the parsed expression
      */
-    public static String translateVariables(String expression, OgnlValueStack stack) {
+    public static String translateVariables(String expression, ValueStack stack) {
         return translateVariables('$', expression, stack, String.class, null).toString();
     }
     
     
     /**
-     * Function similarly as {@link #translateVariables(char, String, OgnlValueStack)} 
+     * Function similarly as {@link #translateVariables(char, String, ValueStack)} 
      * except for the introduction of an additional <code>evaluator</code> that allows
      * the parsed value to be evaluated by the <code>evaluator</code>. The <code>evaluator</code>
      * could be null, if it is it will just be skipped as if it is just calling 
-     * {@link #translateVariables(char, String, OgnlValueStack)}.
+     * {@link #translateVariables(char, String, ValueStack)}.
      * 
      * <p/>
      * 
      * @param evaluator The parsed Value evaluator (could be null).
      * @return the parsed (and possibly evaluated) variable String.
      */
-    public static String translateVariables(String expression, OgnlValueStack stack, ParsedValueEvaluator evaluator) {
+    public static String translateVariables(String expression, ValueStack stack, ParsedValueEvaluator evaluator) {
     	return translateVariables('$', expression, stack, String.class, evaluator).toString();
     }
 
     /**
      * Converts all instances of ${...} in <code>expression</code> to the value returned
-     * by a call to {@link OgnlValueStack#findValue(java.lang.String)}. If an item cannot
+     * by a call to {@link ValueStack#findValue(java.lang.String)}. If an item cannot
      * be found on the stack (null is returned), then the entire variable ${...} is not
      * displayed, just as if the item was on the stack but returned an empty string.
      *
      * @param stack
      * @return Translated variable String
      */
-    public static String translateVariables(char open, String expression, OgnlValueStack stack) {
+    public static String translateVariables(char open, String expression, ValueStack stack) {
         return translateVariables(open, expression, stack, String.class, null).toString();
     }
 
      * @param asType
      * @return Converted object from variable translation.
      */
-    public static Object translateVariables(char open, String expression, OgnlValueStack stack, Class asType) {
+    public static Object translateVariables(char open, String expression, ValueStack stack, Class asType) {
     	return translateVariables(open, expression, stack, asType, null);
     }
     
      * @param evaluator
      * @return Converted object from variable translation.
      */
-    public static Object translateVariables(char open, String expression, OgnlValueStack stack, Class asType, ParsedValueEvaluator evaluator) {
+    public static Object translateVariables(char open, String expression, ValueStack stack, Class asType, ParsedValueEvaluator evaluator) {
         // deal with the "pure" expressions first!
         //expression = expression.trim();
         Object result = expression;
     
     /**
      * A parsed value evaluator for {@link TextParseUtil}. It could be supplied by 
-     * calling {@link TextParseUtil#translateVariables(char, String, OgnlValueStack, Class, ParsedValueEvaluator)}.
+     * calling {@link TextParseUtil#translateVariables(char, String, ValueStack, Class, ParsedValueEvaluator)}.
      * 
      * <p/>
      * 

src/java/com/opensymphony/xwork2/util/ValueStack.java

+/*
+ * Copyright (c) 2002-2006 by OpenSymphony
+ * All rights reserved.
+ */
+package com.opensymphony.xwork2.util;
+
+import java.util.Map;
+
+/**
+ * ValueStack allows multiple beans to be pushed in and dynamic EL expressions to be evaluated against it. When
+ * evaluating an expression, the stack will be searched down the stack, from the latest objects pushed in to the
+ * earliest, looking for a bean with a getter or setter for the given property or a method of the given name (depending
+ * on the expression being evaluated).
+ */
+public interface ValueStack {
+
+    public static final String VALUE_STACK = "com.opensymphony.xwork2.util.ValueStack.ValueStack";
+
+    public static final String REPORT_ERRORS_ON_NO_PROP = "com.opensymphony.xwork2.util.ValueStack.ReportErrorsOnNoProp";
+
+    public abstract Map getContext();
+
+    /**
+     * Sets the default type to convert to if no type is provided when getting a value.
+     *
+     * @param defaultType
+     */
+    public abstract void setDefaultType(Class defaultType);
+
+    public abstract void setExprOverrides(Map overrides);
+
+    public abstract Map getExprOverrides();
+
+    /**
+     * Get the CompoundRoot which holds the objects pushed onto the stack
+     */
+    public abstract CompoundRoot getRoot();
+
+    /**
+     * Determine whether devMode is enabled.
+     *
+     * @return true if devMode was enabled, false otherwise.
+     */
+    public abstract boolean isDevModeEnabled();
+
+    /**
+     * Attempts to set a property on a bean in the stack with the given expression using the default search order.
+     *
+     * @param expr  the expression defining the path to the property to be set.
+     * @param value the value to be set into the neamed property
+     */
+    public abstract void setValue(String expr, Object value);
+
+    /**
+     * Attempts to set a property on a bean in the stack with the given expression using the default search order.
+     *
+     * @param expr                    the expression defining the path to the property to be set.
+     * @param value                   the value to be set into the neamed property
+     * @param throwExceptionOnFailure a flag to tell whether an exception should be thrown if there is no property with
+     *                                the given name.
+     */
+    public abstract void setValue(String expr, Object value,
+            boolean throwExceptionOnFailure);
+
+    public abstract String findString(String expr);
+
+    /**
+     * Find a value by evaluating the given expression against the stack in the default search order.
+     *
+     * @param expr the expression giving the path of properties to navigate to find the property value to return
+     * @return the result of evaluating the expression
+     */
+    public abstract Object findValue(String expr);
+
+    /**
+     * Find a value by evaluating the given expression against the stack in the default search order.
+     *
+     * @param expr   the expression giving the path of properties to navigate to find the property value to return
+     * @param asType the type to convert the return value to
+     * @return the result of evaluating the expression
+     */
+    public abstract Object findValue(String expr, Class asType);
+
+    /**
+     * Get the object on the top of the stack without changing the stack.
+     *
+     * @see CompoundRoot#peek()
+     */
+    public abstract Object peek();
+
+    /**
+     * Get the object on the top of the stack and remove it from the stack.
+     *
+     * @return the object on the top of the stack
+     * @see CompoundRoot#pop()
+     */
+    public abstract Object pop();
+
+    /**
+     * Put this object onto the top of the stack
+     *
+     * @param o the object to be pushed onto the stack
+     * @see CompoundRoot#push(Object)
+     */
+    public abstract void push(Object o);
+
+    /**
+     * Sets an object on the stack with the given key
+     * so it is retrievable by findValue(key,...)
+     * @param key
+     * @param o
+     */
+    public abstract void set(String key, Object o);
+
+    /**
+     * Get the number of objects in the stack
+     * s
+     *
+     * @return the number of objects in the stack
+     */
+    public abstract int size();
+
+}

src/java/com/opensymphony/xwork2/util/ValueStackFactory.java

+/*
+ * Copyright (c) 2002-2006 by OpenSymphony
+ * All rights reserved.
+ */
+package com.opensymphony.xwork2.util;
+
+/**
+ * Factory that creates a value stack, defaulting to the OgnlValueStackFactory
+ */
+public abstract class ValueStackFactory {
+    private static ValueStackFactory factory = new OgnlValueStackFactory();
+    
+    public static void setFactory(ValueStackFactory factory) {
+        ValueStackFactory.factory = factory;
+    }
+    
+    public static ValueStackFactory getFactory() {
+        return factory;
+    }
+
+    public abstract ValueStack createValueStack();
+    
+    public abstract ValueStack createValueStack(ValueStack stack);
+    
+}

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

         }
     }
 
-    public static String getConversionErrorMessage(String propertyName, OgnlValueStack stack) {
+    public static String getConversionErrorMessage(String propertyName, ValueStack stack) {
         String defaultMessage = LocalizedTextUtil.findDefaultText(XWorkMessages.DEFAULT_INVALID_FIELDVALUE,
                 ActionContext.getContext().getLocale(),
                 new Object[]{

src/java/com/opensymphony/xwork2/validator/DelegatingValidatorContext.java

 package com.opensymphony.xwork2.validator;
 
 import com.opensymphony.xwork2.*;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
         return textProvider.getTexts(aBundleName);
     }
 
-    public String getText(String key, String defaultValue, List args, OgnlValueStack stack) {
+    public String getText(String key, String defaultValue, List args, ValueStack stack) {
         return textProvider.getText(key,defaultValue,args,stack);
     }
 
-    public String getText(String key, String defaultValue, String[] args, OgnlValueStack stack) {
+    public String getText(String key, String defaultValue, String[] args, ValueStack stack) {
         return textProvider.getText(key,defaultValue,args,stack);
     }
 

src/java/com/opensymphony/xwork2/validator/validators/RepopulateConversionErrorFieldValidatorSupport.java

 import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.interceptor.PreResultListener;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
 import com.opensymphony.xwork2.validator.ValidationException;
 
 /**
 		if (doExprOverride) {
 			invocation.addPreResultListener(new PreResultListener() {
 				public void beforeResult(ActionInvocation invocation, String resultCode) {
-					OgnlValueStack stack = ActionContext.getContext().getValueStack();
+					ValueStack stack = ActionContext.getContext().getValueStack();
 					stack.setExprOverrides(fakeParams);
 				}
 			});

src/java/com/opensymphony/xwork2/validator/validators/ValidatorSupport.java

 package com.opensymphony.xwork2.validator.validators;
 
 import com.opensymphony.xwork2.ActionContext;
-import com.opensymphony.xwork2.util.OgnlValueStack;
 import com.opensymphony.xwork2.util.TextParseUtil;
+import com.opensymphony.xwork2.util.ValueStack;
 import com.opensymphony.xwork2.validator.*;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
     public String getMessage(Object object) {
         String message;
-        OgnlValueStack stack = ActionContext.getContext().getValueStack();
+        ValueStack stack = ActionContext.getContext().getValueStack();
         boolean pop = false;
 
         if (!stack.getRoot().contains(object)) {
     }
 
     protected Object getFieldValue(String name, Object object) throws ValidationException {
-        OgnlValueStack stack = ActionContext.getContext().getValueStack();
+        ValueStack stack = ActionContext.getContext().getValueStack();
 
         boolean pop = false;
 

src/java/com/opensymphony/xwork2/validator/validators/VisitorFieldValidator.java

 package com.opensymphony.xwork2.validator.validators;
 
 import com.opensymphony.xwork2.ActionContext;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
 import com.opensymphony.xwork2.validator.*;
 
 import java.util.Collection;
         	log.warn("The visited object is null, VisitorValidator will not be able to handle validation properly. Please make sure the visited object is not null for VisitorValidator to function properly");
             return;
         }
-        OgnlValueStack stack = ActionContext.getContext().getValueStack();
+        ValueStack stack = ActionContext.getContext().getValueStack();
 
         stack.push(object);
 
     }
 
     private void validateObject(String fieldName, Object o, String visitorContext) throws ValidationException {
-        OgnlValueStack stack = ActionContext.getContext().getValueStack();
+        ValueStack stack = ActionContext.getContext().getValueStack();
         stack.push(o);
 
         ValidatorContext validatorContext;

src/test/com/opensymphony/xwork2/ActionContextTest.java

  */
 package com.opensymphony.xwork2;
 
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
+
 import junit.framework.TestCase;
 
 import java.util.HashMap;
     private ActionContext context;
 
     public void setUp() {
-        OgnlValueStack valueStack = new OgnlValueStack();
+        ValueStack valueStack = ValueStackFactory.getFactory().createValueStack();
         Map extraContext = valueStack.getContext();
         Map application = new HashMap();
         application.put(APPLICATION_KEY, APPLICATION_KEY);
     }
 
     public void testNewActionContextCanFindDefaultTexts() {
-        OgnlValueStack valueStack = context.getValueStack();
+        ValueStack valueStack = context.getValueStack();
         String actionErrorMessage = (String) valueStack.findValue("getText('xwork.error.action.execution')");
         assertNotNull(actionErrorMessage);
         assertEquals("Error during Action invocation", actionErrorMessage);

src/test/com/opensymphony/xwork2/ActionNestingTest.java

 import com.opensymphony.xwork2.config.ConfigurationProvider;
 import com.opensymphony.xwork2.config.entities.ActionConfig;
 import com.opensymphony.xwork2.config.entities.PackageConfig;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
 
 import java.util.HashMap;
 import java.util.Map;
         configurationManager.getConfiguration().reload(
                 configurationManager.getConfigurationProviders());
 
-        OgnlValueStack stack = new OgnlValueStack();
+        ValueStack stack = ValueStackFactory.getFactory().createValueStack();
 
         // create the action context
         Map contextMap = stack.getContext();
     }
 
     public void testNestedNoValueStack() throws Exception {
-        OgnlValueStack stack = ActionContext.getContext().getValueStack();
+        ValueStack stack = ActionContext.getContext().getValueStack();
         assertEquals(VALUE, stack.findValue(KEY));
 
         ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(
     }
 
     public void testNestedValueStack() throws Exception {
-        OgnlValueStack stack = ActionContext.getContext().getValueStack();
+        ValueStack stack = ActionContext.getContext().getValueStack();
         assertEquals(VALUE, stack.findValue(KEY));
 
         HashMap extraContext = new HashMap();

src/test/com/opensymphony/xwork2/ActionSupportTest.java

 import java.util.Locale;
 import java.util.ArrayList;
 
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
 
 /**
  * Unit test for {@link ActionSupport}.
         ActionContext.getContext().setLocale(new Locale("da"));
         MyActionSupport mas = new MyActionSupport();
 
-        OgnlValueStack stack = new OgnlValueStack();
+        ValueStack stack = ValueStackFactory.getFactory().createValueStack();
 
         List args = new ArrayList();
         args.add("Santa");
         ActionContext.getContext().setLocale(new Locale("da"));
         MyActionSupport mas = new MyActionSupport();
 
-        OgnlValueStack stack = new OgnlValueStack();
+        ValueStack stack = ValueStackFactory.getFactory().createValueStack();
 
         String[] args = { "Santa", "loud" };
         assertEquals("Hello World", mas.getText("hello", "this is default", args, stack)); // no args in bundle

src/test/com/opensymphony/xwork2/ChainResultTest.java

 import com.mockobjects.dynamic.Mock;
 import com.opensymphony.xwork2.config.Configuration;
 import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
+
 import junit.framework.TestCase;
 
 import java.util.HashMap;
         values.put("actionName", expectedActionName);
         values.put("namespace", expectedNamespace);
 
-        OgnlValueStack stack = new OgnlValueStack();
+        ValueStack stack = ValueStackFactory.getFactory().createValueStack();
         stack.push(values);
 
         Mock actionProxyMock = new Mock(ActionProxy.class);

src/test/com/opensymphony/xwork2/DefaultTextProviderTest.java

 import java.util.ResourceBundle;
 
 import com.opensymphony.xwork2.util.LocalizedTextUtil;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
 
 /**
  * Unit test for {@link DefaultTextProvider}.
     }
 
     public void testGetTextsWithListAndStack() throws Exception {
-        OgnlValueStack stack = new OgnlValueStack();
+        ValueStack stack = ValueStackFactory.getFactory().createValueStack();
 
         List args = new ArrayList();
         args.add("Santa");
     }
 
     public void testGetTextsWithArrayAndStack() throws Exception {
-        OgnlValueStack stack = new OgnlValueStack();
+        ValueStack stack = ValueStackFactory.getFactory().createValueStack();
 
         String[] args = { "Santa", "loud" };
         assertEquals("Hello World", tp.getText("hello", "this is default", args, stack)); // no args in bundle

src/test/com/opensymphony/xwork2/LocaleAwareTest.java

 
 import com.opensymphony.xwork2.config.Configuration;
 import com.opensymphony.xwork2.config.providers.MockConfigurationProvider;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
+
 import junit.framework.TestCase;
 
 import java.util.Locale;
         configurationManager.getConfiguration().reload(
                 configurationManager.getConfigurationProviders());
 
-        OgnlValueStack stack = new OgnlValueStack();
+        ValueStack stack = ValueStackFactory.getFactory().createValueStack();
         ActionContext.setContext(new ActionContext(stack.getContext()));
     }
 }

src/test/com/opensymphony/xwork2/NestedAction.java

  */
 package com.opensymphony.xwork2;
 
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+
 import junit.framework.Assert;
 
 
     }
 
     public String noStack() {
-        OgnlValueStack stack = ActionContext.getContext().getValueStack();
+        ValueStack stack = ActionContext.getContext().getValueStack();
         // Action + DefaultTextProvider on the stack
         Assert.assertEquals(2, stack.size());
         Assert.assertNull(stack.findValue(ActionNestingTest.KEY));
     }
 
     public String stack() {
-        OgnlValueStack stack = ActionContext.getContext().getValueStack();
+        ValueStack stack = ActionContext.getContext().getValueStack();
         //DefaultTextProvider, NestedActionTest pushed on by the test, and the NestedAction
         Assert.assertEquals(3, stack.size());
         Assert.assertNotNull(stack.findValue(ActionNestingTest.KEY));

src/test/com/opensymphony/xwork2/interceptor/ChainingInterceptorTest.java

 
 import com.mockobjects.dynamic.Mock;
 import com.opensymphony.xwork2.*;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
+
 import junit.framework.TestCase;
 
 import java.util.Date;
     ActionInvocation invocation;
     ChainingInterceptor interceptor;
     Mock mockInvocation;
-    OgnlValueStack stack;
+    ValueStack stack;
 
 
     public void testActionErrorsCanBeAddedAfterChain() throws Exception {
 
     protected void setUp() throws Exception {
         super.setUp();
-        stack = new OgnlValueStack();
+        stack = ValueStackFactory.getFactory().createValueStack();
         mockInvocation = new Mock(ActionInvocation.class);
         mockInvocation.expectAndReturn("getStack", stack);
         mockInvocation.expectAndReturn("invoke", Action.SUCCESS);

src/test/com/opensymphony/xwork2/interceptor/ConversionErrorInterceptorTest.java

 import com.mockobjects.dynamic.C;
 import com.mockobjects.dynamic.Mock;
 import com.opensymphony.xwork2.*;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
 import com.opensymphony.xwork2.mock.MockActionInvocation;
 
 import java.util.HashMap;
     protected ConversionErrorInterceptor interceptor;
     protected Map conversionErrors;
     protected Mock mockInvocation;
-    protected OgnlValueStack stack;
+    protected ValueStack stack;
 
 
     public void testFieldErrorAdded() throws Exception {
         interceptor = new ConversionErrorInterceptor();
         mockInvocation = new Mock(ActionInvocation.class);
         invocation = (ActionInvocation) mockInvocation.proxy();
-        stack = new OgnlValueStack();
+        stack = ValueStackFactory.getFactory().createValueStack();
         context = new ActionContext(stack.getContext());
         conversionErrors = new HashMap();
         context.setConversionErrors(conversionErrors);

src/test/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptorTest.java

 import com.opensymphony.xwork2.*;
 import com.opensymphony.xwork2.config.entities.ActionConfig;
 import com.opensymphony.xwork2.config.entities.ExceptionMappingConfig;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
 import com.opensymphony.xwork2.validator.ValidationException;
 import junit.framework.TestCase;
 
     ActionInvocation invocation;
     ExceptionMappingInterceptor interceptor;
     Mock mockInvocation;
-    OgnlValueStack stack;
+    ValueStack stack;
 
 
     public void testThrownExceptionMatching() throws Exception {
 
     protected void setUp() throws Exception {
         super.setUp();
-        stack = new OgnlValueStack();
+        stack = ValueStackFactory.getFactory().createValueStack();
         mockInvocation = new Mock(ActionInvocation.class);
         mockInvocation.expectAndReturn("getStack", stack);
         mockInvocation.expectAndReturn("getInvocationContext", new ActionContext(new HashMap()));

src/test/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptorTest.java

 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.ActionSupport;
 import com.opensymphony.xwork2.ModelDriven;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
+
 import junit.framework.TestCase;
 
 import java.util.Date;
 
 
     public void testModelDrivenGetsPushedOntoStack() throws Exception {
-        OgnlValueStack stack = new OgnlValueStack();
+        ValueStack stack = ValueStackFactory.getFactory().createValueStack();
         action = new ModelDrivenAction();
         mockActionInvocation.expectAndReturn("getAction", action);
         mockActionInvocation.expectAndReturn("getStack", stack);

src/test/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptorTest.java

 import com.opensymphony.xwork2.ActionContext;
 import com.opensymphony.xwork2.ActionInvocation;
 import com.opensymphony.xwork2.SimpleAction;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
 
 import junit.framework.TestCase;
 
     ActionInvocation invocation;
     ParameterFilterInterceptor interceptor;
     Mock mockInvocation;
-    OgnlValueStack stack;
+    ValueStack stack;
     Map contextMap;
 
     protected void setUp() throws Exception {
         super.setUp();
         contextMap=new HashMap();
-        stack = new OgnlValueStack();
+        stack = ValueStackFactory.getFactory().createValueStack();
         mockInvocation = new Mock(ActionInvocation.class);
         mockInvocation.expectAndReturn("getStack", stack);
         mockInvocation.expectAndReturn("invoke", Action.SUCCESS);

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

 import com.opensymphony.xwork2.config.providers.MockConfigurationProvider;
 import com.opensymphony.xwork2.mock.MockActionInvocation;
 import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
+
 import junit.framework.TestCase;
 
 import java.util.HashMap;
     public void testParameterNameAware() {
         ParametersInterceptor pi = new ParametersInterceptor();
         final Map actual = new HashMap();
-        OgnlValueStack stack = new OgnlValueStack() {
+        ValueStack stack = new OgnlValueStack() {
             public void setValue(String expr, Object value) {
                 actual.put(expr, value);
             }
 
         ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(
                 configurationManager.getConfiguration(), "", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, extraContext);
-        OgnlValueStack stack = proxy.getInvocation().getStack();
+        ValueStack stack = proxy.getInvocation().getStack();
         HashMap session = new HashMap();
         stack.getContext().put("session", session);
         proxy.execute();

src/test/com/opensymphony/xwork2/spring/interceptor/TestActionInvocation.java

 import com.opensymphony.xwork2.ActionProxy;
 import com.opensymphony.xwork2.Result;
 import com.opensymphony.xwork2.interceptor.PreResultListener;
-import com.opensymphony.xwork2.util.OgnlValueStack;
+import com.opensymphony.xwork2.util.ValueStack;
 
 import java.lang.reflect.Method;
 
 
     }
 
-    public OgnlValueStack getStack() {
+    public ValueStack getStack() {
         return null;
     }
 

src/test/com/opensymphony/xwork2/util/GetPropertiesTest.java

     }
     
     public void doGetCollectionPropertiesTest(Collection c) {
-        OgnlValueStack vs = new OgnlValueStack();
+        ValueStack vs = ValueStackFactory.getFactory().createValueStack();
         Foo foo = new Foo();
         foo.setBarCollection(c);
         vs.push(foo);

src/test/com/opensymphony/xwork2/util/LocalizedTextUtilTest.java

 public class LocalizedTextUtilTest extends XWorkTestCase {
 
 	public void testNpeWhenClassIsPrimitive() throws Exception {
-		OgnlValueStack stack = new OgnlValueStack();
+		ValueStack stack = ValueStackFactory.getFactory().createValueStack();
 		stack.push(new MyObject());
 		String result = LocalizedTextUtil.findText(MyObject.class, "someObj.someI18nKey", Locale.ENGLISH, "default message", null, stack);
 		System.out.println(result);
         configurationManager.reload();
 
 
-        OgnlValueStack stack = new OgnlValueStack();
+        ValueStack stack = ValueStackFactory.getFactory().createValueStack();
         ActionContext.setContext(new ActionContext(stack.getContext()));
         ActionContext.getContext().setLocale(Locale.US);
     }

src/test/com/opensymphony/xwork2/util/OgnlUtilTest.java

      * Test that type conversion is performed on indexed collection properties.
      */
     public void testSetIndexedValue() {
-        OgnlValueStack stack = new OgnlValueStack();
+        ValueStack stack = ValueStackFactory.getFactory().createValueStack();
         Map stackContext = stack.getContext();
         stackContext.put(InstantiatingNullHandler.CREATE_NULL_OBJECTS, Boolean.TRUE);
         stackContext.put(XWorkMethodAccessor.DENY_METHOD_EXECUTION, Boolean.TRUE);
 
         Ognl.getValue(expression, context, "aksdj");
 
-        final OgnlValueStack stack = ActionContext.getContext().getValueStack();
+        final ValueStack stack = ActionContext.getContext().getValueStack();
 
         Object result = Ognl.getValue(OgnlUtil.compile("{\"foo\",'ruby','b','tom'}"), context, foo);
         foo.setIncludes((Collection) result);
 	 * XW-281
 	 */
     public void testSetBigIndexedValue() {
-        OgnlValueStack stack = new OgnlValueStack();
+        ValueStack stack = ValueStackFactory.getFactory().createValueStack();
         Map stackContext = stack.getContext();
         stackContext.put(InstantiatingNullHandler.CREATE_NULL_OBJECTS, Boolean.FALSE);
         stackContext.put(XWorkMethodAccessor.DENY_METHOD_EXECUTION, Boolean.TRUE);

src/test/com/opensymphony/xwork2/util/SetPropertiesTest.java

 
     public void testSetCollectionByConverterFromArray() {
         Foo foo = new Foo();
-        OgnlValueStack vs = new OgnlValueStack();
+        ValueStack vs = ValueStackFactory.getFactory().createValueStack();
         vs.getContext().put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
 
         XWorkConverter c = (XWorkConverter) Ognl.getTypeConverter(vs.getContext());
 
     public void testSetCollectionByConverterFromCollection() {
         Foo foo = new Foo();
-        OgnlValueStack vs = new OgnlValueStack();
+        ValueStack vs = ValueStackFactory.getFactory().createValueStack();
         vs.getContext().put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
 
         XWorkConverter c = (XWorkConverter) Ognl.getTypeConverter(vs.getContext());
 
     public void testValueStackSetValueEmptyStringAsLong() {
         Bar bar = new Bar();
-        OgnlValueStack vs = new OgnlValueStack();
+        ValueStack vs = ValueStackFactory.getFactory().createValueStack();
         vs.getContext().put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
         vs.push(bar);
 
         Foo foo = new Foo();
         foo.setMoreCats(new ArrayList());
         String spielname = "Spielen";
-        OgnlValueStack vs = new OgnlValueStack();
+        ValueStack vs = ValueStackFactory.getFactory().createValueStack();
         vs.getContext().put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
         vs.getContext().put(InstantiatingNullHandler.CREATE_NULL_OBJECTS, Boolean.TRUE);
         vs.push(foo);
         Foo foo = new Foo();
         foo.setAnotherCatMap(new HashMap());
         String spielname = "Spielen";
-        OgnlValueStack vs = new OgnlValueStack();
+        ValueStack vs = ValueStackFactory.getFactory().createValueStack();
         vs.getContext().put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
         vs.getContext().put(InstantiatingNullHandler.CREATE_NULL_OBJECTS, Boolean.TRUE);
         vs.push(foo);
     public void doTestAddingAndModifyingCollectionWithObjects(Collection barColl) {
 
         XWorkConverter.getInstance().setObjectTypeDeterminer(new DefaultObjectTypeDeterminer());
-        OgnlValueStack vs = new OgnlValueStack();
+        ValueStack vs = ValueStackFactory.getFactory().createValueStack();
         Foo foo = new Foo();
 
         foo.setBarCollection(barColl);
 
         Collection barColl=new HashSet();
 
-        OgnlValueStack vs = new OgnlValueStack();
+        ValueStack vs = ValueStackFactory.getFactory().createValueStack();
         OgnlContextState.setCreatingNullObjects(vs.getContext(), true);
         OgnlContextState.setReportingConversionErrors(vs.getContext(), true);
         Foo foo = new Foo();

src/test/com/opensymphony/xwork2/util/TextParseUtilTest.java

 	
 	
 	public void testTranslateVariablesWithEvaluator() throws Exception {
-		OgnlValueStack stack = new OgnlValueStack();
+		ValueStack stack = ValueStackFactory.getFactory().createValueStack();
 		stack.push(new Object() {
 			public String getMyVariable() {
 				return "My Variable ";
 	}
 
     public void testTranslateVariables() {
-        OgnlValueStack stack = new OgnlValueStack();
+        ValueStack stack = ValueStackFactory.getFactory().createValueStack();
 
         Object s = TextParseUtil.translateVariables("foo: ${{1, 2, 3}}, bar: ${1}", stack);
         assertEquals("foo: [1, 2, 3], bar: 1", s);
     public void testTranslateVariablesOpenChar() {
         // just a quick test to see if the open char works
         // most test are done the methods above
-        OgnlValueStack stack = new OgnlValueStack();
+        ValueStack stack = ValueStackFactory.getFactory().createValueStack();
 
         Object s = TextParseUtil.translateVariables('$', "foo: ${{1, 2, 3}}, bar: ${1}", stack);
         assertEquals("foo: [1, 2, 3], bar: 1", s);
     }
 
     public void testTranslateNoVariables() {
-        OgnlValueStack stack = new OgnlValueStack();
+        ValueStack stack = ValueStackFactory.getFactory().createValueStack();
 
         Object s = TextParseUtil.translateVariables('$', "foo: ${}", stack);
         assertEquals("foo: ", s);