rename classes, add more tests
git-svn-id: https://svn.apache.org/repos/asf/struts/sandbox/trunk@833776 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UELReflectionContextFactory.java b/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UELReflectionContextFactory.java
new file mode 100644
index 0000000..0bdaad4
--- /dev/null
+++ b/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UELReflectionContextFactory.java
@@ -0,0 +1,15 @@
+package org.apache.struts2.uelplugin;
+
+import com.opensymphony.xwork2.util.reflection.ReflectionContextFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * ReflectionContextFactory for Unified EL.
+ */
+public class UELReflectionContextFactory implements ReflectionContextFactory {
+ public Map createDefaultContext(Object root) {
+ return new HashMap();
+ }
+}
diff --git a/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UELServletContextListener.java b/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UELServletContextListener.java
new file mode 100644
index 0000000..a48fcd7
--- /dev/null
+++ b/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UELServletContextListener.java
@@ -0,0 +1,33 @@
+package org.apache.struts2.uelplugin;
+
+import de.odysseus.el.ExpressionFactoryImpl;
+import de.odysseus.el.tree.TreeBuilder;
+
+import javax.el.ExpressionFactory;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import java.util.Properties;
+
+import org.apache.struts2.uelplugin.ExpressionFactoryHolder;
+
+/**
+ * Responsible for creating the ExpressionFactory that will be used by the
+ * UelValueStack
+ */
+public class UELServletContextListener implements ServletContextListener {
+ public void contextInitialized(ServletContextEvent contextEvent) {
+ Properties juelProperties = new Properties();
+ juelProperties.setProperty("javax.el.methodInvocations", "true");
+
+ //custom parser
+ juelProperties.setProperty(TreeBuilder.class.getName(), JUELExtensionBuilder.class.getName());
+
+ ExpressionFactory factory = new ExpressionFactoryImpl(juelProperties);
+
+ ExpressionFactoryHolder.setExpressionFactory(factory);
+ }
+
+ public void contextDestroyed(ServletContextEvent contextEvent) {
+ }
+}
diff --git a/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UELValueStack.java b/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UELValueStack.java
new file mode 100644
index 0000000..cf63a79
--- /dev/null
+++ b/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UELValueStack.java
@@ -0,0 +1,229 @@
+package org.apache.struts2.uelplugin;
+
+import com.opensymphony.xwork2.XWorkException;
+import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
+import com.opensymphony.xwork2.inject.Container;
+import com.opensymphony.xwork2.inject.Inject;
+import com.opensymphony.xwork2.util.ClearableValueStack;
+import com.opensymphony.xwork2.util.CompoundRoot;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.logging.Logger;
+import com.opensymphony.xwork2.util.logging.LoggerFactory;
+import org.apache.struts2.uelplugin.elresolvers.AccessorsContextKey;
+
+import javax.el.ELContext;
+import javax.el.ExpressionFactory;
+import javax.el.PropertyNotFoundException;
+import javax.el.ValueExpression;
+import java.util.Map;
+import java.util.TreeMap;
+import java.io.Serializable;
+
+/**
+ * A ValueStack that uses Unified EL as the underlying Expression Language.
+ */
+public class UELValueStack implements ValueStack, ClearableValueStack, Serializable {
+ private static final Logger LOG = LoggerFactory.getLogger(UELValueStack.class);
+
+ private CompoundRoot root = new CompoundRoot();
+ private transient Map context;
+ private Class defaultType;
+ private Map overrides;
+
+ private ELContext elContext;
+ private Container container;
+ private XWorkConverter xworkConverter;
+
+ private boolean logMissingProperties;
+ private boolean devMode;
+
+ public UELValueStack(Container container) {
+ this(container, new CompoundRoot());
+ }
+
+ public UELValueStack(Container container, ValueStack vs) {
+ this(container, new CompoundRoot(vs.getRoot()));
+ }
+
+ public UELValueStack(Container container, CompoundRoot root) {
+ this.container = container;
+ this.xworkConverter = container.getInstance(XWorkConverter.class);
+ setRoot(new CompoundRoot(root));
+ }
+
+ @Inject("devMode")
+ public void setDevMode(String mode) {
+ devMode = "true".equalsIgnoreCase(mode);
+ }
+
+ @Inject(value = "logMissingProperties", required = false)
+ public void setLogMissingProperties(String logMissingProperties) {
+ this.logMissingProperties = "true".equalsIgnoreCase(logMissingProperties);
+ }
+
+ public String findString(String expr, boolean throwException) {
+ return (String) findValue(expr, String.class);
+ }
+
+ public String findString(String expr) {
+ return findString(expr, false);
+ }
+
+ public Object findValue(String expr) {
+ return findValue(expr, Object.class, false);
+ }
+
+ public Object findValue(String expr, boolean throwException) {
+ return findValue(expr, Object.class, throwException);
+ }
+
+ public Object findValue(String expr, Class asType) {
+ return findValue(expr, asType, false);
+ }
+
+ public Object findValue(String expr, Class asType, boolean throwException) {
+ String originalExpression = expr;
+ try {
+ if ((overrides != null) && overrides.containsKey(expr)) {
+ expr = (String) overrides.get(expr);
+ }
+ if (expr != null && expr.startsWith("%{")) {
+ // replace %{ with ${
+ expr = "#" + expr.substring(1);
+ }
+ if (expr != null && !expr.startsWith("${") && !expr.startsWith("#{")) {
+ expr = "#{" + expr + "}";
+ }
+
+ elContext.putContext(AccessorsContextKey.class, context);
+ elContext.putContext(XWorkConverter.class, xworkConverter);
+ elContext.putContext(CompoundRoot.class, root);
+
+ // parse our expression
+ ExpressionFactory factory = getExpressionFactory();
+ ValueExpression valueExpr = factory.createValueExpression(elContext, expr, Object.class);
+ Object retVal = valueExpr.getValue(elContext);
+ if (!Object.class.equals(asType)) {
+ retVal = xworkConverter.convertValue(context, root, null, null, retVal, asType);
+ }
+ return retVal;
+ } catch (Exception e) {
+ return handleException(e, originalExpression, throwException);
+ }
+ }
+
+ private Object handleException(Exception exception, String expression, boolean throwException) {
+ Object ret = context.get(expression);
+
+ if (ret != null)
+ return ret;
+ else {
+ if (exception instanceof PropertyNotFoundException && devMode && logMissingProperties)
+ LOG.warn(exception.getMessage());
+
+ if (throwException)
+ throw new XWorkException(exception);
+ else
+ return null;
+ }
+
+ }
+
+ protected ExpressionFactory getExpressionFactory() {
+ ExpressionFactory factory = ExpressionFactoryHolder.getExpressionFactory();
+ if (factory == null) {
+ String message = "********** FATAL ERROR STARTING UP STRUTS-UEL INTEGRATION **********\n" +
+ "Looks like the UEL listener was not configured for your web app! \n" +
+ "Nothing will work until UELServletContextListener is added as a listener in web.xml.\n" +
+ "You might need to add the following to web.xml: \n" +
+ " <listener>\n" +
+ " <listener-class>org.apache.struts2.uelplugin.UELServletContextListener</listener-class>\n" +
+ " </listener>";
+ LOG.fatal(message);
+ throw new IllegalStateException("Unable to find ExpressionFactory instance. Make sure that 'UELServletContextListener' " +
+ "is configured in web.xml as a listener");
+ } else
+ return factory;
+ }
+
+ public Map getContext() {
+ return context;
+ }
+
+ public Map getExprOverrides() {
+ return overrides;
+ }
+
+ public CompoundRoot getRoot() {
+ return root;
+ }
+
+ public Object peek() {
+ return root.peek();
+ }
+
+ public Object pop() {
+ return root.pop();
+ }
+
+ public void push(Object o) {
+ root.push(o);
+ }
+
+ public void setDefaultType(Class defaultType) {
+ this.defaultType = defaultType;
+ }
+
+ public void setExprOverrides(Map overrides) {
+ if (this.overrides == null) {
+ this.overrides = overrides;
+ } else {
+ this.overrides.putAll(overrides);
+ }
+ }
+
+ public void set(String key, Object o) {
+ overrides.put(key, o);
+ }
+
+ public void setValue(String expr, Object value) {
+ setValue(expr, value, false);
+ }
+
+ public void setValue(String expr, Object value, boolean throwExceptionOnFailure) {
+ try {
+ if (expr != null && !expr.startsWith("${") && !expr.startsWith("#{")) {
+ expr = "#{" + expr + "}";
+ }
+ elContext.putContext(AccessorsContextKey.class, context);
+ elContext.putContext(XWorkConverter.class, xworkConverter);
+ elContext.putContext(CompoundRoot.class, root);
+
+ // parse our expression
+ ExpressionFactory factory = getExpressionFactory();
+ ValueExpression valueExpr = factory.createValueExpression(elContext, expr, Object.class);
+ valueExpr.setValue(elContext, value);
+ } catch (Exception e) {
+ if (e instanceof PropertyNotFoundException && devMode && logMissingProperties)
+ LOG.warn("Could not find property [" + ((PropertyNotFoundException) e).getMessage() + "]");
+
+ if (throwExceptionOnFailure)
+ throw new XWorkException(e);
+ }
+ }
+
+ public int size() {
+ return root.size();
+ }
+
+ protected void setRoot(CompoundRoot root) {
+ this.context = new TreeMap();
+ context.put(VALUE_STACK, this);
+ this.root = root;
+ elContext = new CompoundRootELContext(container);
+ }
+
+ public void clearContextValues() {
+ getContext().clear();
+ }
+}
diff --git a/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UELValueStackFactory.java b/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UELValueStackFactory.java
new file mode 100644
index 0000000..7272694
--- /dev/null
+++ b/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/UELValueStackFactory.java
@@ -0,0 +1,45 @@
+package org.apache.struts2.uelplugin;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
+import com.opensymphony.xwork2.inject.Container;
+import com.opensymphony.xwork2.inject.Inject;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
+
+import javax.el.ExpressionFactory;
+
+/**
+ * Creates UelValueStacks.
+ */
+public class UELValueStackFactory implements ValueStackFactory {
+ private ExpressionFactory factory;
+
+ private XWorkConverter xworkConverter;
+
+ private Container container;
+
+ @Inject
+ public void setXWorkConverter(XWorkConverter conv) {
+ this.xworkConverter = conv;
+ }
+
+ @Inject
+ public void setContainer(Container container) throws ClassNotFoundException {
+ this.container = container;
+ }
+
+
+ public ValueStack createValueStack() {
+ ValueStack results = new UELValueStack(container);
+ results.getContext().put(ActionContext.CONTAINER, container);
+ return results;
+ }
+
+ public ValueStack createValueStack(ValueStack stack) {
+ ValueStack results = new UELValueStack(container, stack);
+ container.inject(results);
+ results.getContext().put(ActionContext.CONTAINER, container);
+ return results;
+ }
+}
diff --git a/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/CompoundRootELResolver.java b/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/CompoundRootELResolver.java
index 032eb6a..0e9c3e2 100644
--- a/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/CompoundRootELResolver.java
+++ b/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/CompoundRootELResolver.java
@@ -1,7 +1,6 @@
package org.apache.struts2.uelplugin.elresolvers;
import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
-import com.opensymphony.xwork2.conversion.NullHandler;
import com.opensymphony.xwork2.util.CompoundRoot;
import com.opensymphony.xwork2.util.reflection.ReflectionContextState;
import com.opensymphony.xwork2.inject.Container;
@@ -10,14 +9,7 @@
import org.apache.commons.lang.xwork.StringUtils;
import javax.el.ELContext;
-import javax.el.ELResolver;
-import java.beans.BeanInfo;
-import java.beans.FeatureDescriptor;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Iterator;
import java.util.Map;
/**
@@ -31,8 +23,8 @@
}
@Override
- public Object getValue(ELContext context, Object base, Object property) {
- if (context == null) {
+ public Object getValue(ELContext elContext, Object base, Object property) {
+ if (elContext == null) {
throw new IllegalArgumentException("ElContext cannot be null");
}
@@ -46,16 +38,17 @@
return null;
}
- CompoundRoot root = (CompoundRoot) context.getContext(CompoundRoot.class);
+ CompoundRoot root = (CompoundRoot) elContext.getContext(CompoundRoot.class);
if (root == null) {
return null;
}
if ("top".equals(propertyName) && root.size() > 0) {
+ elContext.setPropertyResolved(true);
return root.get(0);
}
- Map<String, Object> reflectionContext = (Map) context.getContext(AccessorsContextKey.class);
+ Map<String, Object> reflectionContext = (Map) elContext.getContext(AccessorsContextKey.class);
Object bean = findObjectForProperty(root, propertyName);
if (bean != null) {
@@ -70,10 +63,10 @@
reflectionProvider.setValue(propertyName, reflectionContext, bean, retVal);
}
- context.setPropertyResolved(true);
+ elContext.setPropertyResolved(true);
return retVal;
}
-
+
return null;
}
@@ -93,15 +86,20 @@
}
CompoundRoot root = (CompoundRoot) context.getContext(CompoundRoot.class);
+ Map<String, Object> reflectionContext = (Map) context.getContext(AccessorsContextKey.class);
String propertyName = (String) property;
try {
if (base == null && property != null && root != null) {
Object bean = findObjectForProperty(root, propertyName);
if (bean != null) {
+ reflectionContext.put(XWorkConverter.LAST_BEAN_CLASS_ACCESSED, bean.getClass());
+ reflectionContext.put(XWorkConverter.LAST_BEAN_PROPERTY_ACCESSED, propertyName);
+
+
XWorkConverter converter = (XWorkConverter) context.getContext(XWorkConverter.class);
if (converter != null && root != null) {
Class propType = determineType(bean, propertyName);
- value = converter.convertValue(null, value, propType);
+ value = converter.convertValue(reflectionContext, bean, null, propertyName, value, propType);
}
BeanUtils.setProperty(bean, propertyName, value);
context.setPropertyResolved(true);
diff --git a/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/XWorkBeanELResolver.java b/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/XWorkBeanELResolver.java
index daedd79..ef0409e 100644
--- a/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/XWorkBeanELResolver.java
+++ b/struts2-uel-plugin/src/main/java/org/apache/struts2/uelplugin/elresolvers/XWorkBeanELResolver.java
@@ -18,14 +18,15 @@
if (target != null && property != null) {
Map<String, Object> reflectionContext = (Map<String, Object>) elContext.getContext(AccessorsContextKey.class);
String propertyName = property.toString();
+ Class targetType = target.getClass();
//only handle this if there is such a property
if (PropertyUtils.isReadable(target, propertyName)) {
try {
Object obj = reflectionProvider.getValue(propertyName, reflectionContext, target);
- reflectionContext.put(XWorkConverter.LAST_BEAN_CLASS_ACCESSED, target.getClass());
- reflectionContext.put(XWorkConverter.LAST_BEAN_PROPERTY_ACCESSED, property.toString());
+ reflectionContext.put(XWorkConverter.LAST_BEAN_CLASS_ACCESSED, targetType);
+ reflectionContext.put(XWorkConverter.LAST_BEAN_PROPERTY_ACCESSED, propertyName);
//if object is null, and create objects is enabled, lets do it
if (obj == null && ReflectionContextState.isCreatingNullObjects(reflectionContext)) {
diff --git a/struts2-uel-plugin/src/main/resources/struts-plugin.xml b/struts2-uel-plugin/src/main/resources/struts-plugin.xml
index 89314f6..b684e5c 100644
--- a/struts2-uel-plugin/src/main/resources/struts-plugin.xml
+++ b/struts2-uel-plugin/src/main/resources/struts-plugin.xml
@@ -6,11 +6,11 @@
<struts>
<bean type="com.opensymphony.xwork2.util.ValueStackFactory" name="uel"
- class="org.apache.struts2.uelplugin.UelValueStackFactory"/>
+ class="org.apache.struts2.uelplugin.UELValueStackFactory"/>
<bean type="com.opensymphony.xwork2.util.reflection.ReflectionProvider" name="uel"
class="org.apache.struts2.uelplugin.reflection.GenericReflectionProvider"/>
<bean type="com.opensymphony.xwork2.util.reflection.ReflectionContextFactory" name="uel"
- class="org.apache.struts2.uelplugin.UelReflectionContextFactory"/>
+ class="org.apache.struts2.uelplugin.UELReflectionContextFactory"/>
<constant name="struts.valueStackFactory" value="uel"/>
<constant name="struts.reflectionProvider" value="uel"/>
diff --git a/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/AbstractUelBaseTest.java b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/AbstractUELTest.java
similarity index 79%
rename from struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/AbstractUelBaseTest.java
rename to struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/AbstractUELTest.java
index 185803c..6b98b38 100644
--- a/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/AbstractUelBaseTest.java
+++ b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/AbstractUELTest.java
@@ -2,19 +2,12 @@
import com.opensymphony.xwork2.XWorkTestCase;
import com.opensymphony.xwork2.ActionContext;
-import com.opensymphony.xwork2.ActionProxyFactory;
import com.opensymphony.xwork2.inject.ContainerBuilder;
-import com.opensymphony.xwork2.inject.Factory;
-import com.opensymphony.xwork2.inject.Context;
-import com.opensymphony.xwork2.inject.Scope;
import com.opensymphony.xwork2.test.StubConfigurationProvider;
-import com.opensymphony.xwork2.config.ConfigurationManager;
-import com.opensymphony.xwork2.config.Configuration;
import com.opensymphony.xwork2.config.ConfigurationException;
import com.opensymphony.xwork2.util.CompoundRoot;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.util.ValueStackFactory;
-import com.opensymphony.xwork2.util.LocalizedTextUtil;
import com.opensymphony.xwork2.util.location.LocatableProperties;
import com.opensymphony.xwork2.util.reflection.ReflectionProvider;
import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
@@ -22,7 +15,6 @@
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.uelplugin.reflection.GenericReflectionProvider;
import org.apache.struts2.util.StrutsTypeConverter;
-import org.apache.commons.beanutils.converters.DateConverter;
import javax.servlet.ServletContextEvent;
import javax.el.ExpressionFactory;
@@ -31,11 +23,11 @@
import java.text.DateFormat;
-public abstract class AbstractUelBaseTest extends XWorkTestCase {
+public abstract class AbstractUELTest extends XWorkTestCase {
private ExpressionFactory factory = ExpressionFactory.newInstance();
protected XWorkConverter converter;
protected CompoundRoot root;
- protected UelValueStack stack;
+ protected UELValueStack stack;
protected DateFormat format = DateFormat.getDateInstance();
protected ReflectionProvider reflectionProvider;
@@ -63,8 +55,8 @@
loadConfigurationProviders(new StubConfigurationProvider() {
public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException {
- builder.factory(ValueStack.class, UelValueStack.class);
- builder.factory(ValueStackFactory.class, UelValueStackFactory.class);
+ builder.factory(ValueStack.class, UELValueStack.class);
+ builder.factory(ValueStackFactory.class, UELValueStackFactory.class);
builder.factory(ReflectionProvider.class, GenericReflectionProvider.class);
//builder.factory(StrutsTypeConverter)
}
@@ -74,7 +66,7 @@
reflectionProvider = container.getInstance(ReflectionProvider.class);
converter.registerConverter("java.util.Date", new DateConverter());
this.root = new CompoundRoot();
- this.stack = new UelValueStack(container);
+ this.stack = new UELValueStack(container);
stack.setRoot(root);
stack.getContext().put(ActionContext.CONTAINER, container);
@@ -84,7 +76,7 @@
ServletActionContext.setServletContext(servletContext);
//simulate start up
- UelServletContextListener listener = new UelServletContextListener();
+ UELServletContextListener listener = new UELServletContextListener();
listener.contextInitialized(new ServletContextEvent(servletContext));
}
}
diff --git a/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/BuiltinFunctionsTest.java b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/BuiltinFunctionsTest.java
index 9be211f..c48ecf4 100644
--- a/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/BuiltinFunctionsTest.java
+++ b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/BuiltinFunctionsTest.java
@@ -1,21 +1,11 @@
package org.apache.struts2.uelplugin;
-import com.opensymphony.xwork2.XWorkTestCase;
-import com.opensymphony.xwork2.ActionContext;
-import com.opensymphony.xwork2.util.CompoundRoot;
-import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
-
import java.lang.reflect.InvocationTargetException;
-import org.springframework.mock.web.MockServletContext;
-import org.apache.struts2.ServletActionContext;
import org.apache.struts2.views.util.ContextUtil;
-import org.apache.struts2.uelplugin.UelServletContextListener;
-
-import javax.servlet.ServletContextEvent;
-public class BuiltinFunctionsTest extends AbstractUelBaseTest {
+public class BuiltinFunctionsTest extends AbstractUELTest {
public void testGetText() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
TestAction action = new TestAction();
stack.push(action);
diff --git a/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/ChildTestAction.java b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/ChildTestAction.java
new file mode 100644
index 0000000..ca55152
--- /dev/null
+++ b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/ChildTestAction.java
@@ -0,0 +1,4 @@
+package org.apache.struts2.uelplugin;
+
+public class ChildTestAction extends TestAction {
+}
diff --git a/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/ParametersTest.java b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/ParametersTest.java
deleted file mode 100644
index 1868ce7..0000000
--- a/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/ParametersTest.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package org.apache.struts2.uelplugin;
-
-import com.opensymphony.xwork2.interceptor.ParametersInterceptor;
-import com.opensymphony.xwork2.ActionProxy;
-import com.opensymphony.xwork2.Action;
-import com.opensymphony.xwork2.util.reflection.ReflectionContextState;
-
-import java.util.Map;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.lang.reflect.InvocationTargetException;
-
-
-public class ParametersTest extends AbstractUelBaseTest {
- public void testWriteList() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
- //not null
- List list = new ArrayList();
- TestObject obj = new TestObject();
- obj.setList(list);
- assertNotNull(obj.getList());
- root.push(obj);
-
- stack.setValue("list[0]", "val");
- assertEquals(1, list.size());
- assertEquals("val", list.get(0));
-
- //null list
- obj.setList(null);
- assertNull(obj.getList());
- stack.setValue("list[0]", "val");
- assertNotNull(obj.getList());
- assertEquals("val", stack.findValue("list[0]"));
-
- //test out of index
- obj.setList(null);
- stack.setValue("list[3]", "val");
- assertEquals(4, obj.getList().size());
- assertEquals("val", obj.getList().get(3));
-
- //test type determiner
- obj.setTypedList(null);
- stack.setValue("typedList[1].value", "val");
- assertEquals(2, obj.getTypedList().size());
- assertEquals("val", obj.getTypedList().get(1).getValue());
- }
-
- public void testWriteArray() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
- //not null
- Object[] array = new Object[2];
- TestObject obj = new TestObject();
- //obj.setObjectArray(array);
- //assertNotNull(obj.getObjectArray());
- root.push(obj);
-
- stack.setValue("objectArray[0].value", "val");
- assertEquals("val", ((TestObject)array[0]).getValue());
- }
-
- public void testWriteMap() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
- //not null
- Map map = new HashMap();
- TestObject obj = new TestObject();
- obj.setMap(map);
- assertNotNull(obj.getMap());
- root.push(obj);
-
- stack.setValue("map['str']", "val");
- assertEquals(1, map.size());
- assertEquals("val", map.get("str"));
-
- //null list
- obj.setMap(null);
- assertNull(obj.getMap());
- stack.setValue("map['str']", "val");
- assertNotNull(obj.getMap());
- assertEquals("val", stack.findValue("map['str']"));
-
- //test type determiner
- obj.setTypedMap(null);
- stack.setValue("typedMap[1].value", "val");
- assertEquals(1, obj.getTypedMap().size());
- assertEquals("val", obj.getTypedMap().get(1).getValue());
- }
-
- public void testSetPropertiesOnNestedNullObject() {
- TestObject obj = new TestObject();
- assertNull(obj.getInner());
- root.push(obj);
-
- //inner is null, it will be catched bye the CompoundRoolELResolver
- stack.setValue("inner.value", "val");
- assertNotNull(obj.getInner());
- assertEquals("val", obj.getInner().getValue());
-
-
- //second nested property null
- stack.setValue("inner.inner.value", "val");
- assertNotNull(obj.getInner().getInner());
- assertEquals("val", obj.getInner().getInner().getValue());
- }
-
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- Map context = stack.getContext();
-
- ReflectionContextState.setCreatingNullObjects(context, true);
- ReflectionContextState.setDenyMethodExecution(context, true);
- ReflectionContextState.setReportingConversionErrors(context, true);
- }
-}
diff --git a/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/TestAction.java b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/TestAction.java
index 03b06de..3e3f493 100644
--- a/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/TestAction.java
+++ b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/TestAction.java
@@ -8,10 +8,18 @@
@Conversion
public class TestAction extends ActionSupport {
private TestObject object;
+ private int bar;
+
+ public int getBar() {
+ return bar;
+ }
+
+ public void setBar(int bar) {
+ this.bar = bar;
+ }
private String converted;
- @TypeConversion(type = ConversionType.APPLICATION, converter = "org.apache.struts2.uelplugin.DummyTypeConverter")
public String getConverted() {
return converted;
}
diff --git a/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/TestObject.java b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/TestObject.java
index 9d31e45..d87b8b8 100644
--- a/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/TestObject.java
+++ b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/TestObject.java
@@ -18,9 +18,32 @@
private Map map;
private Map<Integer, TestObject> typedMap;
private Object[] objectArray;
- private Integer[] typedArray;
+ private int[] typedArray;
+ private TestObject[] typedArray2;
private Set set;
+ private ChildTestAction childTestAction;
+
+ public ChildTestAction getChildTestAction() {
+ return childTestAction;
+ }
+
+ public void setChildTestAction(ChildTestAction childTestAction) {
+ this.childTestAction = childTestAction;
+ }
+
+ public Object getFail() {
+ throw new RuntimeException("kaboom");
+ }
+
+ public TestObject[] getTypedArray2() {
+ return typedArray2;
+ }
+
+ public void setTypedArray2(TestObject[] typedArray2) {
+ this.typedArray2 = typedArray2;
+ }
+
public Set getSet() {
return set;
}
@@ -37,11 +60,11 @@
this.objectArray = objectArray;
}
- public Integer[] getTypedArray() {
+ public int[] getTypedArray() {
return typedArray;
}
- public void setTypedArray(Integer[] typedArray) {
+ public void setTypedArray(int[] typedArray) {
this.typedArray = typedArray;
}
diff --git a/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/JuelMethodInvocationTest.java b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UELMethodInvocationTest.java
similarity index 65%
rename from struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/JuelMethodInvocationTest.java
rename to struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UELMethodInvocationTest.java
index 9ed8fb0..3026b3d 100644
--- a/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/JuelMethodInvocationTest.java
+++ b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UELMethodInvocationTest.java
@@ -1,19 +1,9 @@
package org.apache.struts2.uelplugin;
-import com.opensymphony.xwork2.ActionContext;
-import com.opensymphony.xwork2.XWorkTestCase;
-import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
-import com.opensymphony.xwork2.util.CompoundRoot;
-import org.apache.struts2.ServletActionContext;
-import org.apache.struts2.uelplugin.UelServletContextListener;
-import org.springframework.mock.web.MockServletContext;
-
-import javax.servlet.ServletContextEvent;
import java.lang.reflect.InvocationTargetException;
-import java.util.HashMap;
-public class JuelMethodInvocationTest extends AbstractUelBaseTest {
+public class UELMethodInvocationTest extends AbstractUELTest {
public void testBasicMethods() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
assertEquals("text", stack.findValue("${' text '.trim()}"));
assertEquals(3, stack.findValue("${'123'.length()}"));
@@ -29,4 +19,14 @@
stack.getContext().put("s1", "Luthor");
assertEquals("Lex Luthor", stack.findValue("${#s0.concat(' ').concat(#s1)}"));
}
+
+ public void testCallMethodsOnCompundRoot() {
+ //this shuld not fail as the property is defined on a parent class
+ TestObject obj = new TestObject();
+ root.push(obj);
+ ChildTestAction childTestAction = new ChildTestAction();
+ obj.setChildTestAction(childTestAction);
+
+ assertSame(childTestAction, stack.findValue("top.getChildTestAction()", true));
+ }
}
diff --git a/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UelTest.java b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UELStackReadValueTest.java
similarity index 67%
rename from struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UelTest.java
rename to struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UELStackReadValueTest.java
index 2394bf1..9e1bcc7 100644
--- a/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UelTest.java
+++ b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UELStackReadValueTest.java
@@ -1,36 +1,21 @@
package org.apache.struts2.uelplugin;
-import com.opensymphony.xwork2.ActionContext;
-import com.opensymphony.xwork2.XWorkTestCase;
-import com.opensymphony.xwork2.ActionProxyFactory;
-import com.opensymphony.xwork2.ognl.OgnlReflectionProvider;
-import com.opensymphony.xwork2.inject.Container;
-import com.opensymphony.xwork2.inject.ContainerBuilder;
-import com.opensymphony.xwork2.inject.Scope;
-import com.opensymphony.xwork2.config.ConfigurationManager;
-import com.opensymphony.xwork2.config.Configuration;
-import com.opensymphony.xwork2.config.ConfigurationProvider;
-import com.opensymphony.xwork2.config.ConfigurationException;
-import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
-import com.opensymphony.xwork2.util.reflection.ReflectionProvider;
-import com.opensymphony.xwork2.util.location.LocatableProperties;
-import com.opensymphony.xwork2.util.ValueStack;
-import com.opensymphony.xwork2.util.ValueStackFactory;
-import com.opensymphony.xwork2.util.LocalizedTextUtil;
-import com.opensymphony.xwork2.util.CompoundRoot;
-import org.apache.struts2.ServletActionContext;
-import org.apache.struts2.uelplugin.UelServletContextListener;
-import org.apache.struts2.util.StrutsTypeConverter;
-import org.springframework.mock.web.MockServletContext;
-
-import javax.el.ExpressionFactory;
-import javax.servlet.ServletContextEvent;
import java.lang.reflect.InvocationTargetException;
-import java.text.DateFormat;
-import java.text.ParseException;
import java.util.*;
-public class UelTest extends AbstractUelBaseTest {
+public class UELStackReadValueTest extends AbstractUELTest {
+
+ public void testTop() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+ TestObject obj = new TestObject();
+ obj.setValue("0");
+ root.push(obj);
+
+ obj = new TestObject();
+ obj.setValue("1");
+ root.push(obj);
+
+ assertEquals("1", stack.findValue("top.value"));
+ }
public void testReadList() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
TestObject obj = new TestObject();
@@ -45,7 +30,7 @@
public void testReadArray() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
TestObject obj = new TestObject();
- Integer[] ints = {10, 20};
+ int[] ints = {10, 20};
obj.setTypedArray(ints);
root.push(obj);
@@ -54,7 +39,7 @@
}
- public void testMap() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+ public void testReadMap() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
HashMap map = new HashMap();
map.put("nameValue", "Lex");
TestObject obj = new TestObject();
@@ -183,18 +168,6 @@
assertEquals(100, stack.findValue("${inner.age}"));
}
- public void testSetStringArray() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
- TestObject obj = new TestObject();
- root.add(obj);
-
- stack.setValue("${value}", new String[]{"Hello World"});
- String value = stack.findString("${value}");
- assertEquals("Hello World", value);
-
- stack.setValue("${age}", new String[]{"67"});
- assertEquals(new Integer(67), stack.findValue("${age}"));
- }
-
public void testDeferredFind() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
TestObject obj = new TestObject();
root.add(obj);
@@ -211,35 +184,6 @@
assertEquals(stack.findString("#{date}"), format.format(obj.getDate()));
}
- public void test2LevelSet() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
- TestObject obj = new TestObject();
- TestObject nestedObj = new TestObject();
- obj.setInner(nestedObj);
- root.add(obj);
-
- stack.setValue("${inner.age}", "66");
- assertEquals(66, obj.getInner().getAge());
- }
-
- public void testTypeConversion() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
- TestObject obj = new TestObject();
- TestObject inner = new TestObject();
- obj.setInner(inner);
- root.add(obj);
-
- stack.setValue("${age}", "22");
- assertEquals(stack.findValue("${age}"), obj.getAge());
-
- stack.setValue("${inner.value}", "George");
- assertEquals(stack.findValue("${inner.value}"), obj.getInner().getValue());
-
- stack.setValue("${inner.age}", "44");
- assertEquals(stack.findValue("${inner.age}"), obj.getInner().getAge());
-
- stack.setValue("${date}", new Date());
- assertEquals(stack.findString("${date}"), format.format(obj.getDate()));
- }
-
public void testNotFound() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
TestObject obj = new TestObject();
root.add(obj);
diff --git a/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UELStackSetValueTest.java b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UELStackSetValueTest.java
new file mode 100644
index 0000000..a0e43e6
--- /dev/null
+++ b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UELStackSetValueTest.java
@@ -0,0 +1,159 @@
+package org.apache.struts2.uelplugin;
+
+import com.opensymphony.xwork2.util.reflection.ReflectionContextState;
+
+import java.util.*;
+import java.lang.reflect.InvocationTargetException;
+
+
+public class UELStackSetValueTest extends AbstractUELTest {
+ public void testSuperNested() {
+ TestObject obj = new TestObject();
+ root.push(obj);
+
+ stack.setValue("inner.typedMap[10].inner.typedList[2].typedMap[1].value", "whoa");
+ assertEquals("whoa", obj.getInner().getTypedMap().get(10).getInner().getTypedList().get(2).getTypedMap().get(1).getValue());
+ }
+
+
+ public void testWriteList() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+ //not null
+ List list = new ArrayList();
+ TestObject obj = new TestObject();
+ obj.setList(list);
+ assertNotNull(obj.getList());
+ root.push(obj);
+
+ stack.setValue("list[0]", "val");
+ assertEquals(1, list.size());
+ assertEquals("val", list.get(0));
+
+ //null list
+ obj.setList(null);
+ assertNull(obj.getList());
+ stack.setValue("list[0]", "val");
+ assertNotNull(obj.getList());
+ assertEquals("val", stack.findValue("list[0]"));
+
+ //test out of index
+ obj.setList(null);
+ stack.setValue("list[3]", "val");
+ assertEquals(4, obj.getList().size());
+ assertEquals("val", obj.getList().get(3));
+
+ //test type determiner
+ obj.setTypedList(null);
+ stack.setValue("typedList[1].value", "val");
+ assertEquals(2, obj.getTypedList().size());
+ assertEquals("val", obj.getTypedList().get(1).getValue());
+ }
+
+ public void testWriteArray() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+ //not null
+ TestObject[] array = new TestObject[2];
+ TestObject obj = new TestObject();
+ obj.setTypedArray2(array);
+ assertNotNull(obj.getTypedArray2());
+ root.push(obj);
+
+ stack.setValue("typedArray2[0].value", "val");
+ assertNotNull(array[0]);
+ assertEquals("val", ((TestObject) array[0]).getValue());
+ }
+
+ public void testWriteMap() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+ //not null
+ Map map = new HashMap();
+ TestObject obj = new TestObject();
+ obj.setMap(map);
+ assertNotNull(obj.getMap());
+ root.push(obj);
+
+ stack.setValue("map['str']", "val");
+ assertEquals(1, map.size());
+ assertEquals("val", map.get("str"));
+
+ //null list
+ obj.setMap(null);
+ assertNull(obj.getMap());
+ stack.setValue("map['str']", "val");
+ assertNotNull(obj.getMap());
+ assertEquals("val", stack.findValue("map['str']"));
+
+ //test type determiner
+ obj.setTypedMap(null);
+ stack.setValue("typedMap[1].value", "val");
+ assertEquals(1, obj.getTypedMap().size());
+ assertEquals("val", obj.getTypedMap().get(1).getValue());
+ }
+
+ public void testSetPropertiesOnNestedNullObject() {
+ TestObject obj = new TestObject();
+ assertNull(obj.getInner());
+ root.push(obj);
+
+ //inner is null, it will be catched bye the CompoundRoolELResolver
+ stack.setValue("inner.value", "val");
+ assertNotNull(obj.getInner());
+ assertEquals("val", obj.getInner().getValue());
+
+
+ //second nested property null
+ stack.setValue("inner.inner.value", "val");
+ assertNotNull(obj.getInner().getInner());
+ assertEquals("val", obj.getInner().getInner().getValue());
+ }
+
+ public void testSetStringArray() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+ TestObject obj = new TestObject();
+ root.add(obj);
+
+ stack.setValue("${value}", new String[]{"Hello World"});
+ String value = stack.findString("${value}");
+ assertEquals("Hello World", value);
+
+ stack.setValue("${age}", new String[]{"67"});
+ assertEquals(new Integer(67), stack.findValue("${age}"));
+ }
+
+ public void test2LevelSet() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+ TestObject obj = new TestObject();
+ TestObject nestedObj = new TestObject();
+ obj.setInner(nestedObj);
+ root.add(obj);
+
+ stack.setValue("${inner.age}", "66");
+ assertEquals(66, obj.getInner().getAge());
+ }
+
+ public void testTypeConversion() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+ TestObject obj = new TestObject();
+ TestObject inner = new TestObject();
+ obj.setInner(inner);
+ root.add(obj);
+
+ stack.setValue("${age}", "22");
+ assertEquals(stack.findValue("${age}"), obj.getAge());
+
+ stack.setValue("${inner.value}", "George");
+ assertEquals(stack.findValue("${inner.value}"), obj.getInner().getValue());
+
+ stack.setValue("${inner.age}", "44");
+ assertEquals(stack.findValue("${inner.age}"), obj.getInner().getAge());
+
+ stack.setValue("${date}", new Date());
+ assertEquals(stack.findString("${date}"), format.format(obj.getDate()));
+ }
+
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ Map context = stack.getContext();
+
+ ReflectionContextState.setCreatingNullObjects(context, true);
+ ReflectionContextState.setDenyMethodExecution(context, true);
+ ReflectionContextState.setReportingConversionErrors(context, true);
+ }
+}
diff --git a/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UELValueStackOtherTests.java b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UELValueStackOtherTests.java
new file mode 100644
index 0000000..a4af15d
--- /dev/null
+++ b/struts2-uel-plugin/src/test/java/org/apache/struts2/uelplugin/UELValueStackOtherTests.java
@@ -0,0 +1,159 @@
+package org.apache.struts2.uelplugin;
+
+import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
+import com.opensymphony.xwork2.ActionContext;
+
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+
+public class UELValueStackOtherTests extends AbstractUELTest {
+
+ public void testExpOverridesCanStackExpUp() throws Exception {
+ Map expr1 = new LinkedHashMap();
+ expr1.put("expr1", "'expr1value'");
+
+ stack.setExprOverrides(expr1);
+
+ assertEquals(stack.findValue("expr1"), "expr1value");
+
+ Map expr2 = new LinkedHashMap();
+ expr2.put("expr2", "'expr2value'");
+ expr2.put("expr3", "'expr3value'");
+ stack.setExprOverrides(expr2);
+
+ assertEquals(stack.findValue("expr2"), "expr2value");
+ assertEquals(stack.findValue("expr3"), "expr3value");
+ }
+
+ public void testArrayAsString() {
+ TestObject obj = new TestObject();
+ obj.setTypedArray(new int[]{1, 2});
+ root.push(obj);
+
+ assertEquals("1, 2", stack.findValue("typedArray", String.class));
+ }
+
+ public void testFailsOnExceptionWithThrowException() {
+ TestObject obj = new TestObject();
+ root.push(obj);
+ try {
+ stack.findValue("fail", true);
+ fail("Failed to throw exception on EL error");
+ } catch (Exception ex) {
+ //ok
+ }
+ }
+
+ public void testFailsOnMissingPropertyWithThrowException() {
+ TestObject obj = new TestObject();
+ root.push(obj);
+ try {
+ stack.findValue("someprop12", true);
+ fail("Failed to throw exception on EL error");
+ } catch (Exception ex) {
+ //ok
+ }
+ }
+
+ public void testFailsOnMissingNestedPropertyWithThrowException() {
+ TestObject obj = new TestObject();
+ root.push(obj);
+ try {
+ stack.findValue("top.someprop12", true);
+ fail("Failed to throw exception on EL error");
+ } catch (Exception ex) {
+ //ok
+ }
+ }
+
+ public void testFailsOnMissingMethodWithThrowException() {
+ TestObject obj = new TestObject();
+ root.push(obj);
+ try {
+ stack.findValue("top.somethingweird()", true);
+ fail("Failed to throw exception on EL error");
+ } catch (Exception ex) {
+ //ok
+ }
+ }
+
+ public void testDoesNotFailOnExceptionWithoutThrowException() {
+ TestObject obj = new TestObject();
+ root.push(obj);
+ stack.findValue("fail", false);
+ stack.findValue("fail");
+ }
+
+ public void testDoesNotFailOnInheritedPropertiesWithThrowException() {
+ //this shuld not fail as the property is defined on a parent class
+ TestObject obj = new TestObject();
+ root.push(obj);
+ ChildTestAction childTestAction = new ChildTestAction();
+ obj.setChildTestAction(childTestAction);
+
+ assertNull(childTestAction.getConverted());
+ stack.findValue("childTestAction.converted", true);
+ }
+
+ public void testDoesNotFailOnInheritedMethodsWithThrowException() {
+ //this shuld not fail as the property is defined on a parent class
+ TestObject obj = new TestObject();
+ root.push(obj);
+ ChildTestAction childTestAction = new ChildTestAction();
+ obj.setChildTestAction(childTestAction);
+
+ assertNull(childTestAction.getConverted());
+ stack.findValue("top.getChildTestAction().converted", true);
+ }
+
+ public void testFailsOnInheritedMethodsWithThrowException() {
+ //this shuld not fail as the property is defined on a parent class
+ TestObject obj = new TestObject();
+ root.push(obj);
+ ChildTestAction childTestAction = new ChildTestAction();
+ obj.setChildTestAction(childTestAction);
+
+ assertNull(childTestAction.getConverted());
+
+ try {
+ stack.findValue("top.getChildTestAction().converted2", true);
+ fail("should have failed because of missing property");
+ } catch (Exception e) {
+ }
+ }
+
+ public void testPrimitiveSettingWithInvalidValueAddsFieldErrorInNonDevMode() {
+ TestAction action = new TestAction();
+ stack.getContext().put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+ stack.setDevMode("false");
+ stack.push(action);
+ stack.setValue("bar", "3x");
+
+ Map conversionErrors = (Map) stack.getContext().get(ActionContext.CONVERSION_ERRORS);
+ assertTrue(conversionErrors.containsKey("bar"));
+ }
+
+ public void testPrimitiveSettingWithInvalidValueAddsFieldErrorInDevMode() {
+ TestAction action = new TestAction();
+ stack.getContext().put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+ stack.setDevMode("true");
+ stack.push(action);
+ stack.setValue("bar", "3x");
+
+ Map conversionErrors = (Map) stack.getContext().get(ActionContext.CONVERSION_ERRORS);
+ assertTrue(conversionErrors.containsKey("bar"));
+ }
+
+ public void testObjectSettingWithInvalidValueDoesNotCauseSetCalledWithNull() {
+ TestObject obj = new TestObject();
+ root.push(obj);
+ ChildTestAction obj2 = new ChildTestAction();
+ obj.setChildTestAction(obj2);
+
+ stack.setValue("childTestAction", "whoa");
+ assertNotNull(obj.getChildTestAction());
+ assertSame(obj2, obj.getChildTestAction());
+ }
+
+}