You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2011/12/02 17:33:45 UTC
svn commit: r1209569 [43/50] - in /struts/struts2/branches/STRUTS_3_X:
apps/blank/src/main/java/example/ apps/blank/src/test/java/example/
apps/jboss-blank/src/main/java/example/
apps/jboss-blank/src/test/java/example/ apps/mailreader/src/main/java/mai...
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/AnnotationParameterFilterUnitTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/AnnotationParameterFilterUnitTest.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/AnnotationParameterFilterUnitTest.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/AnnotationParameterFilterUnitTest.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,173 @@
+package org.apache.struts2.xwork2.interceptor.annotations;
+
+import com.mockobjects.dynamic.Mock;
+import org.apache.struts2.xwork2.Action;
+import org.apache.struts2.xwork2.ActionContext;
+import org.apache.struts2.xwork2.ActionInvocation;
+import org.apache.struts2.xwork2.StubValueStack;
+import org.apache.struts2.xwork2.util.ValueStack;
+import junit.framework.TestCase;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author martin.gilday
+ * @author jafl
+ *
+ */
+public class AnnotationParameterFilterUnitTest extends TestCase {
+
+ ValueStack stack;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ stack = new StubValueStack();
+ }
+
+ /**
+ * Only "name" should remain in the parameter map. All others
+ * should be removed
+ * @throws Exception
+ */
+ public void testBlockingByDefault() throws Exception {
+
+ Map contextMap = new HashMap();
+ Map parameterMap = new HashMap();
+
+ parameterMap.put("job", "Baker");
+ parameterMap.put("name", "Martin");
+
+ contextMap.put(ActionContext.PARAMETERS, parameterMap);
+
+ Action action = new BlockingByDefaultAction();
+ stack.push(action);
+
+ Mock mockInvocation = new Mock(ActionInvocation.class);
+ mockInvocation.expectAndReturn("getInvocationContext", new ActionContext(contextMap));
+ mockInvocation.matchAndReturn("getAction", action);
+ mockInvocation.matchAndReturn("getStack", stack);
+ mockInvocation.expectAndReturn("invoke", Action.SUCCESS);
+
+ ActionInvocation invocation = (ActionInvocation) mockInvocation.proxy();
+
+ AnnotationParameterFilterIntereptor intereptor = new AnnotationParameterFilterIntereptor();
+ intereptor.intercept(invocation);
+
+ assertEquals("Paramter map should contain one entry", 1, parameterMap.size());
+ assertNull(parameterMap.get("job"));
+ assertNotNull(parameterMap.get("name"));
+
+ }
+
+ /**
+ * "name" should be removed from the map, as it is blocked.
+ * All other parameters should remain
+ * @throws Exception
+ */
+ public void testAllowingByDefault() throws Exception {
+
+ Map contextMap = new HashMap();
+ Map parameterMap = new HashMap();
+
+ parameterMap.put("job", "Baker");
+ parameterMap.put("name", "Martin");
+
+ contextMap.put(ActionContext.PARAMETERS, parameterMap);
+
+ Action action = new AllowingByDefaultAction();
+ stack.push(action);
+
+ Mock mockInvocation = new Mock(ActionInvocation.class);
+ mockInvocation.expectAndReturn("getInvocationContext", new ActionContext(contextMap));
+ mockInvocation.matchAndReturn("getAction", action);
+ mockInvocation.matchAndReturn("getStack", stack);
+ mockInvocation.expectAndReturn("invoke", Action.SUCCESS);
+
+ ActionInvocation invocation = (ActionInvocation) mockInvocation.proxy();
+
+ AnnotationParameterFilterIntereptor intereptor = new AnnotationParameterFilterIntereptor();
+ intereptor.intercept(invocation);
+
+ assertEquals("Paramter map should contain one entry", 1, parameterMap.size());
+ assertNotNull(parameterMap.get("job"));
+ assertNull(parameterMap.get("name"));
+
+ }
+
+ /**
+ * Only "name" should remain in the parameter map. All others
+ * should be removed
+ * @throws Exception
+ */
+ public void testBlockingByDefaultWithModel() throws Exception {
+
+ Map contextMap = new HashMap();
+ Map parameterMap = new HashMap();
+
+ parameterMap.put("job", "Baker");
+ parameterMap.put("name", "Martin");
+ parameterMap.put("m1", "s1");
+ parameterMap.put("m2", "s2");
+
+ contextMap.put(ActionContext.PARAMETERS, parameterMap);
+ stack.push(new BlockingByDefaultModel());
+
+ Mock mockInvocation = new Mock(ActionInvocation.class);
+ mockInvocation.expectAndReturn("getInvocationContext", new ActionContext(contextMap));
+ mockInvocation.matchAndReturn("getAction", new BlockingByDefaultAction());
+ mockInvocation.matchAndReturn("getStack", stack);
+ mockInvocation.expectAndReturn("invoke", Action.SUCCESS);
+
+ ActionInvocation invocation = (ActionInvocation) mockInvocation.proxy();
+
+ AnnotationParameterFilterIntereptor intereptor = new AnnotationParameterFilterIntereptor();
+ intereptor.intercept(invocation);
+
+ assertEquals("Paramter map should contain two entries", 2, parameterMap.size());
+ assertNull(parameterMap.get("job"));
+ assertNotNull(parameterMap.get("name"));
+ assertNotNull(parameterMap.get("m1"));
+ assertNull(parameterMap.get("m2"));
+
+ }
+
+ /**
+ * "name" should be removed from the map, as it is blocked.
+ * All other parameters should remain
+ * @throws Exception
+ */
+ public void testAllowingByDefaultWithModel() throws Exception {
+
+ Map contextMap = new HashMap();
+ Map parameterMap = new HashMap();
+
+ parameterMap.put("job", "Baker");
+ parameterMap.put("name", "Martin");
+ parameterMap.put("m1", "s1");
+ parameterMap.put("m2", "s2");
+
+ contextMap.put(ActionContext.PARAMETERS, parameterMap);
+ stack.push(new AllowingByDefaultModel());
+
+ Mock mockInvocation = new Mock(ActionInvocation.class);
+ mockInvocation.expectAndReturn("getInvocationContext", new ActionContext(contextMap));
+ mockInvocation.matchAndReturn("getAction", new AllowingByDefaultAction());
+ mockInvocation.matchAndReturn("getStack", stack);
+ mockInvocation.expectAndReturn("invoke", Action.SUCCESS);
+
+ ActionInvocation invocation = (ActionInvocation) mockInvocation.proxy();
+
+ AnnotationParameterFilterIntereptor intereptor = new AnnotationParameterFilterIntereptor();
+ intereptor.intercept(invocation);
+
+ assertEquals("Paramter map should contain two entries", 2, parameterMap.size());
+ assertNotNull(parameterMap.get("job"));
+ assertNull(parameterMap.get("name"));
+ assertNull(parameterMap.get("m1"));
+ assertNotNull(parameterMap.get("m2"));
+
+ }
+
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/AnnotationWorkflowInterceptorTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/AnnotationWorkflowInterceptorTest.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/AnnotationWorkflowInterceptorTest.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/AnnotationWorkflowInterceptorTest.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.interceptor.annotations;
+
+import org.apache.struts2.xwork2.config.Configuration;
+import org.apache.struts2.xwork2.config.ConfigurationException;
+import org.apache.struts2.xwork2.Action;
+import org.apache.struts2.xwork2.ActionProxy;
+import org.apache.struts2.xwork2.DefaultActionProxyFactory;
+import org.apache.struts2.xwork2.ObjectFactory;
+import org.apache.struts2.xwork2.config.ConfigurationProvider;
+import org.apache.struts2.xwork2.config.entities.ActionConfig;
+import org.apache.struts2.xwork2.ActionProxyFactory;
+import org.apache.struts2.xwork2.XWorkTestCase;
+import org.apache.struts2.xwork2.config.entities.InterceptorMapping;
+import org.apache.struts2.xwork2.config.entities.PackageConfig;
+import org.apache.struts2.xwork2.config.entities.ResultConfig;
+import org.apache.struts2.xwork2.config.providers.XmlConfigurationProvider;
+import org.apache.struts2.xwork2.inject.ContainerBuilder;
+import org.apache.struts2.xwork2.mock.MockResult;
+import org.apache.struts2.xwork2.util.location.LocatableProperties;
+
+import java.util.Arrays;
+
+/**
+ * @author Zsolt Szasz, zsolt at lorecraft dot com
+ * @author Rainer Hermanns
+ */
+public class AnnotationWorkflowInterceptorTest extends XWorkTestCase {
+ private static final String ANNOTATED_ACTION = "annotatedAction";
+ private static final String SHORTCIRCUITED_ACTION = "shortCircuitedAction";
+ private final AnnotationWorkflowInterceptor annotationWorkflow = new AnnotationWorkflowInterceptor();
+
+ @Override
+ public void setUp() {
+ loadConfigurationProviders(new XmlConfigurationProvider("xwork-default.xml"), new MockConfigurationProvider());
+ }
+
+ public void testInterceptsBeforeAndAfter() throws Exception {
+ ActionProxy proxy = actionProxyFactory.createActionProxy("", ANNOTATED_ACTION, null);
+ assertEquals(Action.SUCCESS, proxy.execute());
+ AnnotatedAction action = (AnnotatedAction)proxy.getInvocation().getAction();
+ assertEquals("baseBefore-before-execute-beforeResult-after", action.log);
+ }
+
+ public void testInterceptsShortcircuitedAction() throws Exception {
+ ActionProxy proxy = actionProxyFactory.createActionProxy("", SHORTCIRCUITED_ACTION, null);
+ assertEquals("shortcircuit", proxy.execute());
+ ShortcircuitedAction action = (ShortcircuitedAction)proxy.getInvocation().getAction();
+ assertEquals("baseBefore-before", action.log);
+ }
+
+ private class MockConfigurationProvider implements ConfigurationProvider {
+ private Configuration config;
+
+ public void init(Configuration configuration) throws ConfigurationException {
+ this.config = configuration;
+ }
+
+ public boolean needsReload() {
+ return false;
+ }
+
+ public void destroy() { }
+
+
+ public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException {
+ if (!builder.contains(ObjectFactory.class)) {
+ builder.factory(ObjectFactory.class);
+ }
+ if (!builder.contains(ActionProxyFactory.class)) {
+ builder.factory(ActionProxyFactory.class, DefaultActionProxyFactory.class);
+ }
+ }
+
+ public void loadPackages() throws ConfigurationException {
+ PackageConfig packageConfig = new PackageConfig.Builder("default")
+ .addActionConfig(ANNOTATED_ACTION, new ActionConfig.Builder("defaultPackage", ANNOTATED_ACTION, AnnotatedAction.class.getName())
+ .addInterceptors(Arrays.asList(new InterceptorMapping[]{ new InterceptorMapping("annotationWorkflow", annotationWorkflow) }))
+ .addResultConfig(new ResultConfig.Builder("success", MockResult.class.getName()).build())
+ .build())
+ .addActionConfig(SHORTCIRCUITED_ACTION, new ActionConfig.Builder("defaultPackage", SHORTCIRCUITED_ACTION, ShortcircuitedAction.class.getName())
+ .addInterceptors(Arrays.asList(new InterceptorMapping[]{ new InterceptorMapping("annotationWorkflow", annotationWorkflow) }))
+ .addResultConfig(new ResultConfig.Builder("shortcircuit", MockResult.class.getName()).build())
+ .build())
+ .build();
+ config.addPackageConfig("defaultPackage", packageConfig);
+ config.addPackageConfig("default", new PackageConfig.Builder(packageConfig).name("default").build());
+ }
+ }
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/BaseAnnotatedAction.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/BaseAnnotatedAction.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/BaseAnnotatedAction.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/BaseAnnotatedAction.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.interceptor.annotations;
+
+/**
+ * @author Zsolt Szasz, zsolt at lorecraft dot com
+ * @author Rainer Hermanns
+ */
+public class BaseAnnotatedAction {
+
+ protected String log = "";
+
+ @Before
+ public String baseBefore() {
+ log = log + "baseBefore-";
+ return null;
+ }
+
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/BlockingByDefaultAction.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/BlockingByDefaultAction.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/BlockingByDefaultAction.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/BlockingByDefaultAction.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,24 @@
+package org.apache.struts2.xwork2.interceptor.annotations;
+
+import org.apache.struts2.xwork2.ActionSupport;
+
+/**
+ * @author martin.gilday
+ *
+ */
+@BlockByDefault
+public class BlockingByDefaultAction extends ActionSupport {
+
+ @Allowed
+ private String name;
+ private String job;
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setJob(String job) {
+ this.job = job;
+ }
+
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/BlockingByDefaultModel.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/BlockingByDefaultModel.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/BlockingByDefaultModel.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/BlockingByDefaultModel.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,22 @@
+package org.apache.struts2.xwork2.interceptor.annotations;
+
+/**
+ * @author jafl
+ *
+ */
+@BlockByDefault
+public class BlockingByDefaultModel {
+
+ @Allowed
+ private String m1;
+ private String m2;
+
+ public void setM1(String s) {
+ m1 = s;
+ }
+
+ public void setM2(String s) {
+ m2 = s;
+ }
+
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/ShortcircuitedAction.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/ShortcircuitedAction.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/ShortcircuitedAction.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/interceptor/annotations/ShortcircuitedAction.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.interceptor.annotations;
+
+import org.apache.struts2.xwork2.Action;
+
+/**
+ * @author Zsolt Szasz, zsolt at lorecraft dot com
+ * @author Rainer Hermanns
+ */
+public class ShortcircuitedAction extends BaseAnnotatedAction {
+ @Before(priority=5)
+ public String before() {
+ log = log + "before";
+ return "shortcircuit";
+ }
+
+ public String execute() {
+ log = log + "-execute-";
+ return Action.SUCCESS;
+ }
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/ognl/OgnlUtilTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/ognl/OgnlUtilTest.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/ognl/OgnlUtilTest.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/ognl/OgnlUtilTest.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,726 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.ognl;
+
+import org.apache.struts2.xwork2.ActionContext;
+import org.apache.struts2.xwork2.XWorkException;
+import org.apache.struts2.xwork2.XWorkTestCase;
+import org.apache.struts2.xwork2.conversion.impl.XWorkConverter;
+import org.apache.struts2.xwork2.interceptor.ChainingInterceptor;
+import org.apache.struts2.xwork2.test.User;
+import org.apache.struts2.xwork2.util.CompoundRoot;
+import org.apache.struts2.xwork2.util.ValueStack;
+import org.apache.struts2.xwork2.util.reflection.ReflectionContextState;
+import ognl.*;
+import org.apache.struts2.xwork2.util.Bar;
+import org.apache.struts2.xwork2.util.Foo;
+import org.apache.struts2.xwork2.util.Owner;
+
+import java.lang.reflect.Method;
+import java.util.*;
+
+
+/**
+ * Unit test of {@link ognlUtil}.
+ *
+ * @version $Date: 2011-12-02 12:24:48 +0100 (Fri, 02 Dec 2011) $ $Id: OgnlUtilTest.java 1209415 2011-12-02 11:24:48Z lukaszlenart $
+ */
+public class OgnlUtilTest extends XWorkTestCase {
+
+ private OgnlUtil ognlUtil;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ ognlUtil = container.getInstance(OgnlUtil.class);
+ }
+
+ public void testCanSetADependentObject() throws Exception {
+ String dogName = "fido";
+
+ OgnlRuntime.setNullHandler(Owner.class, new NullHandler() {
+ public Object nullMethodResult(Map map, Object o, String s, Object[] objects) {
+ return null;
+ }
+
+ public Object nullPropertyValue(Map map, Object o, Object o1) {
+ String methodName = o1.toString();
+ String getter = "set" + methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
+ Method[] methods = o.getClass().getDeclaredMethods();
+ System.out.println(getter);
+
+ for (Method method : methods) {
+ String name = method.getName();
+
+ if (!getter.equals(name) || (method.getParameterTypes().length != 1)) {
+ continue;
+ } else {
+ Class clazz = method.getParameterTypes()[0];
+
+ try {
+ Object param = clazz.newInstance();
+ method.invoke(o, new Object[]{param});
+
+ return param;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ return null;
+ }
+ });
+
+ Owner owner = new Owner();
+ Map context = Ognl.createDefaultContext(owner);
+ Map props = new HashMap();
+ props.put("dog.name", dogName);
+
+ ognlUtil.setProperties(props, owner, context);
+ assertNotNull("expected Ognl to create an instance of Dog", owner.getDog());
+ assertEquals(dogName, owner.getDog().getName());
+ }
+
+ public void testCacheEnabled() throws OgnlException {
+ OgnlUtil.setEnableExpressionCache("true");
+ Object expr0 = ognlUtil.compile("test");
+ Object expr2 = ognlUtil.compile("test");
+ assertSame(expr0, expr2);
+ }
+
+ public void testCacheDisabled() throws OgnlException {
+ OgnlUtil.setEnableExpressionCache("false");
+ Object expr0 = ognlUtil.compile("test");
+ Object expr2 = ognlUtil.compile("test");
+ assertNotSame(expr0, expr2);
+ }
+
+ public void testCanSetDependentObjectArray() {
+ EmailAction action = new EmailAction();
+ Map<String, Object> context = Ognl.createDefaultContext(action);
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put("email[0].address", "addr1");
+ props.put("email[1].address", "addr2");
+ props.put("email[2].address", "addr3");
+
+ ognlUtil.setProperties(props, action, context);
+ assertEquals(3, action.email.size());
+ assertEquals("addr1", action.email.get(0).toString());
+ assertEquals("addr2", action.email.get(1).toString());
+ assertEquals("addr3", action.email.get(2).toString());
+ }
+
+ public void testCopySameType() {
+ Foo foo1 = new Foo();
+ Foo foo2 = new Foo();
+
+ Map context = Ognl.createDefaultContext(foo1);
+
+ Calendar cal = Calendar.getInstance();
+ cal.clear();
+ cal.set(Calendar.MONTH, Calendar.FEBRUARY);
+ cal.set(Calendar.DAY_OF_MONTH, 12);
+ cal.set(Calendar.YEAR, 1982);
+
+ foo1.setTitle("blah");
+ foo1.setNumber(1);
+ foo1.setPoints(new long[]{1, 2, 3});
+ foo1.setBirthday(cal.getTime());
+ foo1.setUseful(false);
+
+ ognlUtil.copy(foo1, foo2, context);
+
+ assertEquals(foo1.getTitle(), foo2.getTitle());
+ assertEquals(foo1.getNumber(), foo2.getNumber());
+ assertEquals(foo1.getPoints(), foo2.getPoints());
+ assertEquals(foo1.getBirthday(), foo2.getBirthday());
+ assertEquals(foo1.isUseful(), foo2.isUseful());
+ }
+
+
+ public void testIncudeExcludes() {
+
+ Foo foo1 = new Foo();
+ Foo foo2 = new Foo();
+
+ Calendar cal = Calendar.getInstance();
+ cal.clear();
+ cal.set(Calendar.MONTH, Calendar.FEBRUARY);
+ cal.set(Calendar.DAY_OF_MONTH, 12);
+ cal.set(Calendar.YEAR, 1982);
+
+ foo1.setPoints(new long[]{1, 2, 3});
+ foo1.setBirthday(cal.getTime());
+ foo1.setUseful(false);
+
+
+ foo1.setTitle("foo1 title");
+ foo1.setNumber(1);
+
+ foo2.setTitle("foo2 title");
+ foo2.setNumber(2);
+
+ Map<String, Object> context = Ognl.createDefaultContext(foo1);
+
+ List<String> excludes = new ArrayList<String>();
+ excludes.add("title");
+ excludes.add("number");
+
+ ognlUtil.copy(foo1, foo2, context, excludes, null);
+ // these values should remain unchanged in foo2
+ assertEquals(foo2.getTitle(), "foo2 title");
+ assertEquals(foo2.getNumber(), 2);
+
+ // these values should be changed/copied
+ assertEquals(foo1.getPoints(), foo2.getPoints());
+ assertEquals(foo1.getBirthday(), foo2.getBirthday());
+ assertEquals(foo1.isUseful(), foo2.isUseful());
+
+
+ Bar b1 = new Bar();
+ Bar b2 = new Bar();
+
+ b1.setTitle("bar1 title");
+ b1.setSomethingElse(10);
+
+
+ b1.setId(new Long(1));
+
+ b2.setTitle("");
+ b2.setId(new Long(2));
+
+ context = Ognl.createDefaultContext(b1);
+ List<String> includes = new ArrayList<String>();
+ includes.add("title");
+ includes.add("somethingElse");
+
+ ognlUtil.copy(b1, b2, context, null, includes);
+ // includes properties got copied
+ assertEquals(b1.getTitle(), b2.getTitle());
+ assertEquals(b1.getSomethingElse(), b2.getSomethingElse());
+
+ // id properties did not
+ assertEquals(b2.getId(), new Long(2));
+
+ }
+
+
+ public void testCopyUnevenObjects() {
+ Foo foo = new Foo();
+ Bar bar = new Bar();
+
+ Map<String, Object> context = Ognl.createDefaultContext(foo);
+
+ Calendar cal = Calendar.getInstance();
+ cal.clear();
+ cal.set(Calendar.MONTH, Calendar.FEBRUARY);
+ cal.set(Calendar.DAY_OF_MONTH, 12);
+ cal.set(Calendar.YEAR, 1982);
+
+ foo.setTitle("blah");
+ foo.setNumber(1);
+ foo.setPoints(new long[]{1, 2, 3});
+ foo.setBirthday(cal.getTime());
+ foo.setUseful(false);
+
+ ognlUtil.copy(foo, bar, context);
+
+ assertEquals(foo.getTitle(), bar.getTitle());
+ assertEquals(0, bar.getSomethingElse());
+ }
+
+ public void testDeepSetting() {
+ Foo foo = new Foo();
+ foo.setBar(new Bar());
+
+ Map<String, Object> context = Ognl.createDefaultContext(foo);
+
+ Map<String, Object> props = new HashMap();
+ props.put("bar.title", "i am barbaz");
+ ognlUtil.setProperties(props, foo, context);
+
+ assertEquals(foo.getBar().getTitle(), "i am barbaz");
+ }
+
+ public void testNoExceptionForUnmatchedGetterAndSetterWithThrowPropertyException() {
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put("myIntegerProperty", new Integer(1234));
+
+ TestObject testObject = new TestObject();
+
+ //this used to fail in OGNL versions < 2.7
+ ognlUtil.setProperties(props, testObject, true);
+ assertEquals(1234, props.get("myIntegerProperty"));
+ }
+
+ public void testExceptionForWrongPropertyNameWithThrowPropertyException() {
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put("myStringProperty", "testString");
+
+ TestObject testObject = new TestObject();
+
+ try {
+ ognlUtil.setProperties(props, testObject, true);
+ fail("Should rise NoSuchPropertyException because of wrong property name");
+ } catch (Exception e) {
+ //expected
+ }
+ }
+
+ public void testOgnlHandlesCrapAtTheEndOfANumber() {
+ Foo foo = new Foo();
+ Map<String, Object> context = Ognl.createDefaultContext(foo);
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put("aLong", "123a");
+
+ ognlUtil.setProperties(props, foo, context);
+ assertEquals(0, foo.getALong());
+ }
+
+ /**
+ * Test that type conversion is performed on indexed collection properties.
+ */
+ public void testSetIndexedValue() {
+ ValueStack stack = ActionContext.getContext().getValueStack();
+ Map<String, Object> stackContext = stack.getContext();
+ stackContext.put(ReflectionContextState.CREATE_NULL_OBJECTS, Boolean.TRUE);
+ stackContext.put(ReflectionContextState.DENY_METHOD_EXECUTION, Boolean.TRUE);
+ stackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+
+ User user = new User();
+ stack.push(user);
+
+ // indexed string w/ existing array
+ user.setList(new ArrayList<String>());
+ user.getList().add("");
+
+ String[] foo = new String[]{"asdf"};
+ stack.setValue("list[0]", foo);
+ assertNotNull(user.getList());
+ assertEquals(1, user.getList().size());
+ assertEquals(String.class, user.getList().get(0).getClass());
+ assertEquals("asdf", user.getList().get(0));
+ }
+
+ public void testSetPropertiesBoolean() {
+ Foo foo = new Foo();
+
+ Map context = Ognl.createDefaultContext(foo);
+
+ Map props = new HashMap();
+ props.put("useful", "true");
+ ognlUtil.setProperties(props, foo, context);
+
+ assertEquals(true, foo.isUseful());
+
+ props = new HashMap();
+ props.put("useful", "false");
+ ognlUtil.setProperties(props, foo, context);
+
+ assertEquals(false, foo.isUseful());
+ }
+
+ public void testSetPropertiesDate() {
+ Locale orig = Locale.getDefault();
+ Locale.setDefault(Locale.US);
+
+ Foo foo = new Foo();
+
+ Map context = Ognl.createDefaultContext(foo);
+
+ Map props = new HashMap();
+ props.put("birthday", "02/12/1982");
+ // US style test
+ ognlUtil.setProperties(props, foo, context);
+
+ Calendar cal = Calendar.getInstance();
+ cal.clear();
+ cal.set(Calendar.MONTH, Calendar.FEBRUARY);
+ cal.set(Calendar.DAY_OF_MONTH, 12);
+ cal.set(Calendar.YEAR, 1982);
+
+ assertEquals(cal.getTime(), foo.getBirthday());
+
+ Locale.setDefault(Locale.UK);
+ //UK style test
+ props.put("event", "18/10/2006 14:23:45");
+ props.put("meeting", "09/09/2006 14:30");
+ ognlUtil.setProperties(props, foo, context);
+
+ cal = Calendar.getInstance();
+ cal.clear();
+ cal.set(Calendar.MONTH, Calendar.OCTOBER);
+ cal.set(Calendar.DAY_OF_MONTH, 18);
+ cal.set(Calendar.YEAR, 2006);
+ cal.set(Calendar.HOUR_OF_DAY, 14);
+ cal.set(Calendar.MINUTE, 23);
+ cal.set(Calendar.SECOND, 45);
+
+ assertEquals(cal.getTime(), foo.getEvent());
+
+ cal = Calendar.getInstance();
+ cal.clear();
+ cal.set(Calendar.MONTH, Calendar.SEPTEMBER);
+ cal.set(Calendar.DAY_OF_MONTH, 9);
+ cal.set(Calendar.YEAR, 2006);
+ cal.set(Calendar.HOUR_OF_DAY, 14);
+ cal.set(Calendar.MINUTE, 30);
+
+ assertEquals(cal.getTime(), foo.getMeeting());
+
+ Locale.setDefault(orig);
+
+ Locale.setDefault(orig);
+
+ //test RFC 3339 date format for JSON
+ props.put("event", "1996-12-19T16:39:57Z");
+ ognlUtil.setProperties(props, foo, context);
+
+ cal = Calendar.getInstance();
+ cal.clear();
+ cal.set(Calendar.MONTH, Calendar.DECEMBER);
+ cal.set(Calendar.DAY_OF_MONTH, 19);
+ cal.set(Calendar.YEAR, 1996);
+ cal.set(Calendar.HOUR_OF_DAY, 16);
+ cal.set(Calendar.MINUTE, 39);
+ cal.set(Calendar.SECOND, 57);
+
+ assertEquals(cal.getTime(), foo.getEvent());
+
+ //test setting a calendar property
+ props.put("calendar", "1996-12-19T16:39:57Z");
+ ognlUtil.setProperties(props, foo, context);
+ assertEquals(cal, foo.getCalendar());
+ }
+
+ public void testSetPropertiesInt() {
+ Foo foo = new Foo();
+
+ Map context = Ognl.createDefaultContext(foo);
+
+ Map props = new HashMap();
+ props.put("number", "2");
+ ognlUtil.setProperties(props, foo, context);
+
+ assertEquals(2, foo.getNumber());
+ }
+
+ public void testSetPropertiesLongArray() {
+ Foo foo = new Foo();
+
+ Map context = Ognl.createDefaultContext(foo);
+
+ Map props = new HashMap();
+ props.put("points", new String[]{"1", "2"});
+ ognlUtil.setProperties(props, foo, context);
+
+ assertNotNull(foo.getPoints());
+ assertEquals(2, foo.getPoints().length);
+ assertEquals(1, foo.getPoints()[0]);
+ assertEquals(2, foo.getPoints()[1]);
+ }
+
+ public void testSetPropertiesString() {
+ Foo foo = new Foo();
+
+ Map context = Ognl.createDefaultContext(foo);
+
+ Map props = new HashMap();
+ props.put("title", "this is a title");
+ ognlUtil.setProperties(props, foo, context);
+
+ assertEquals(foo.getTitle(), "this is a title");
+ }
+
+ public void testSetProperty() {
+ Foo foo = new Foo();
+ Map context = Ognl.createDefaultContext(foo);
+ assertFalse(123456 == foo.getNumber());
+ ognlUtil.setProperty("number", "123456", foo, context);
+ assertEquals(123456, foo.getNumber());
+ }
+
+
+ public void testSetList() throws Exception {
+ ChainingInterceptor foo = new ChainingInterceptor();
+ ChainingInterceptor foo2 = new ChainingInterceptor();
+
+ OgnlContext context = (OgnlContext) Ognl.createDefaultContext(null);
+ SimpleNode expression = (SimpleNode) Ognl.parseExpression("{'a','ruby','b','tom'}");
+
+
+ Ognl.getValue(expression, context, "aksdj");
+
+ final ValueStack stack = ActionContext.getContext().getValueStack();
+
+ Object result = Ognl.getValue(ognlUtil.compile("{\"foo\",'ruby','b','tom'}"), context, foo);
+ foo.setIncludes((Collection) result);
+
+ assertEquals(4, foo.getIncludes().size());
+ assertEquals("foo", foo.getIncludes().toArray()[0]);
+ assertEquals("ruby", foo.getIncludes().toArray()[1]);
+ assertEquals("b", "" + foo.getIncludes().toArray()[2]);
+ assertEquals("tom", foo.getIncludes().toArray()[3]);
+
+ Object result2 = Ognl.getValue(ognlUtil.compile("{\"foo\",'ruby','b','tom'}"), context, foo2);
+ ognlUtil.setProperty("includes", result2, foo2, context);
+
+ assertEquals(4, foo.getIncludes().size());
+ assertEquals("foo", foo.getIncludes().toArray()[0]);
+ assertEquals("ruby", foo.getIncludes().toArray()[1]);
+ assertEquals("b", "" + foo.getIncludes().toArray()[2]);
+ assertEquals("tom", foo.getIncludes().toArray()[3]);
+
+ result = ActionContext.getContext().getValueStack().findValue("{\"foo\",'ruby','b','tom'}");
+
+ foo.setIncludes((Collection) result);
+ assertEquals(ArrayList.class, result.getClass());
+
+ assertEquals(4, foo.getIncludes().size());
+ assertEquals("foo", foo.getIncludes().toArray()[0]);
+ assertEquals("ruby", foo.getIncludes().toArray()[1]);
+ assertEquals("b", "" + foo.getIncludes().toArray()[2]);
+ assertEquals("tom", foo.getIncludes().toArray()[3]);
+ }
+
+
+ public void testStringToLong() {
+ Foo foo = new Foo();
+
+ Map context = Ognl.createDefaultContext(foo);
+
+ Map props = new HashMap();
+ props.put("aLong", "123");
+
+ ognlUtil.setProperties(props, foo, context);
+ assertEquals(123, foo.getALong());
+
+ props.put("aLong", new String[]{"123"});
+
+ foo.setALong(0);
+ ognlUtil.setProperties(props, foo, context);
+ assertEquals(123, foo.getALong());
+ }
+
+ public void testNullProperties() {
+ Foo foo = new Foo();
+ foo.setALong(88);
+
+ Map context = Ognl.createDefaultContext(foo);
+
+ ognlUtil.setProperties(null, foo, context);
+ assertEquals(88, foo.getALong());
+
+ Map props = new HashMap();
+ props.put("aLong", "99");
+ ognlUtil.setProperties(props, foo, context);
+ assertEquals(99, foo.getALong());
+ }
+
+ public void testCopyNull() {
+ Foo foo = new Foo();
+ Map context = Ognl.createDefaultContext(foo);
+ ognlUtil.copy(null, null, context);
+
+ ognlUtil.copy(foo, null, context);
+ ognlUtil.copy(null, foo, context);
+ }
+
+ public void testGetTopTarget() throws Exception {
+ Foo foo = new Foo();
+ Map context = Ognl.createDefaultContext(foo);
+
+ CompoundRoot root = new CompoundRoot();
+ Object top = ognlUtil.getRealTarget("top", context, root);
+ assertEquals(root, top); // top should be root
+
+ root.push(foo);
+ Object val = ognlUtil.getRealTarget("unknown", context, root);
+ assertNull(val); // not found
+ }
+
+ public void testGetBeanMap() throws Exception {
+ Bar bar = new Bar();
+ bar.setTitle("I have beer");
+
+ Foo foo = new Foo();
+ foo.setALong(123);
+ foo.setNumber(44);
+ foo.setBar(bar);
+ foo.setTitle("Hello Santa");
+ foo.setUseful(true);
+
+ // just do some of the 15 tests
+ Map beans = ognlUtil.getBeanMap(foo);
+ assertNotNull(beans);
+ assertEquals(19, beans.size());
+ assertEquals("Hello Santa", beans.get("title"));
+ assertEquals(new Long("123"), beans.get("ALong"));
+ assertEquals(new Integer("44"), beans.get("number"));
+ assertEquals(bar, beans.get("bar"));
+ assertEquals(Boolean.TRUE, beans.get("useful"));
+ }
+
+ public void testGetBeanMapNoReadMethod() throws Exception {
+ MyWriteBar bar = new MyWriteBar();
+ bar.setBar("Sams");
+
+ Map beans = ognlUtil.getBeanMap(bar);
+ assertEquals(2, beans.size());
+ assertEquals(new Integer("1"), beans.get("id"));
+ assertEquals("There is no read method for bar", beans.get("bar"));
+ }
+
+ /**
+ * XW-281
+ */
+ public void testSetBigIndexedValue() {
+ ValueStack stack = ActionContext.getContext().getValueStack();
+ Map stackContext = stack.getContext();
+ stackContext.put(ReflectionContextState.CREATE_NULL_OBJECTS, Boolean.FALSE);
+ stackContext.put(ReflectionContextState.DENY_METHOD_EXECUTION, Boolean.TRUE);
+ stackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+
+ User user = new User();
+ stack.push(user);
+
+ // indexed string w/ existing array
+ user.setList(new ArrayList());
+
+ String[] foo = new String[]{"asdf"};
+ ((OgnlValueStack)stack).setDevMode("true");
+ try {
+ stack.setValue("list.1114778947765", foo);
+ fail("non-valid expression: list.1114778947765");
+ }
+ catch(RuntimeException ex) {
+ ; // it's oke
+ }
+
+ try {
+ stack.setValue("1114778947765", foo);
+ fail("non-valid expression: 1114778947765");
+ }
+ catch(RuntimeException ex) {
+ ;
+ }
+
+ try {
+ stack.setValue("1234", foo);
+ fail("non-valid expression: 1114778947765");
+ }
+ catch(RuntimeException ex) {
+ ;
+ }
+
+ ((OgnlValueStack)stack).setDevMode("false");
+ stack.setValue("list.1114778947765", foo);
+ stack.setValue("1114778947765", foo);
+ stack.setValue("1234", foo);
+ }
+
+
+ public static class Email {
+ String address;
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ @Override
+ public String toString() {
+ return address;
+ }
+ }
+
+ static class TestObject {
+ private Integer myIntegerProperty;
+ private Long myLongProperty;
+ private String myStrProperty;
+
+ public void setMyIntegerProperty(Integer myIntegerProperty) {
+ this.myIntegerProperty = myIntegerProperty;
+ }
+
+ public String getMyIntegerProperty() {
+ return myIntegerProperty.toString();
+ }
+
+ public void setMyLongProperty(Long myLongProperty) {
+ this.myLongProperty = myLongProperty;
+ }
+
+ public Long getMyLongProperty() {
+ return myLongProperty;
+ }
+
+ public void setMyStrProperty(String myStrProperty) {
+ this.myStrProperty = myStrProperty;
+ }
+
+ public String getMyStrProperty() {
+ return myStrProperty;
+ }
+ }
+
+ class EmailAction {
+ public List email = new OgnlList(Email.class);
+
+ public List getEmail() {
+ return this.email;
+ }
+ }
+
+ class OgnlList extends ArrayList {
+ private Class clazz;
+
+ public OgnlList(Class clazz) {
+ this.clazz = clazz;
+ }
+
+ @Override
+ public synchronized Object get(int index) {
+ while (index >= this.size()) {
+ try {
+ this.add(clazz.newInstance());
+ } catch (Exception e) {
+ throw new XWorkException(e);
+ }
+ }
+
+ return super.get(index);
+ }
+ }
+
+ private class MyWriteBar {
+ private int id;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setBar(String name) {
+ if ("Sams".equals(name))
+ id = 1;
+ else
+ id = 999;
+ }
+
+ }
+}
Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/ognl/OgnlValueStackTest.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/ognl/OgnlValueStackTest.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/ognl/OgnlValueStackTest.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/test/java/org/apache/struts2/xwork2/ognl/OgnlValueStackTest.java Fri Dec 2 16:33:03 2011
@@ -0,0 +1,1037 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.ognl;
+
+import junit.framework.Assert;
+import org.apache.struts2.xwork2.conversion.impl.XWorkConverter;
+import org.apache.struts2.xwork2.ActionContext;
+import org.apache.struts2.xwork2.TextProvider;
+import org.apache.struts2.xwork2.XWorkException;
+import org.apache.struts2.xwork2.XWorkTestCase;
+import org.apache.struts2.xwork2.ognl.accessor.CompoundRootAccessor;
+import org.apache.struts2.xwork2.test.TestBean2;
+import org.apache.struts2.xwork2.util.Bar;
+import org.apache.struts2.xwork2.util.Foo;
+import org.apache.struts2.xwork2.util.CompoundRoot;
+import org.apache.struts2.xwork2.util.reflection.ReflectionContextState;
+import ognl.PropertyAccessor;
+import org.apache.struts2.xwork2.SimpleAction;
+import org.apache.struts2.xwork2.TestBean;
+import org.apache.struts2.xwork2.util.BarJunior;
+import org.apache.struts2.xwork2.util.Cat;
+import org.apache.struts2.xwork2.util.Dog;
+
+import java.io.*;
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+
+/**
+ * Unit test for OgnlValueStack.
+ */
+public class OgnlValueStackTest extends XWorkTestCase {
+
+ public static Integer staticNullMethod() {
+ return null;
+ }
+
+ private OgnlUtil ognlUtil;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ ognlUtil = container.getInstance(OgnlUtil.class);
+ }
+
+ private OgnlValueStack createValueStack() {
+ return createValueStack(true);
+ }
+
+ private OgnlValueStack createValueStack(boolean allowStaticMethodAccess) {
+ OgnlValueStack stack = new OgnlValueStack(
+ container.getInstance(XWorkConverter.class),
+ (CompoundRootAccessor) container.getInstance(PropertyAccessor.class, CompoundRoot.class.getName()),
+ container.getInstance(TextProvider.class, "system"), allowStaticMethodAccess);
+ container.inject(stack);
+ return stack;
+ }
+
+ public void testExpOverridesCanStackExpUp() throws Exception {
+ Map expr1 = new LinkedHashMap();
+ expr1.put("expr1", "'expr1value'");
+
+ OgnlValueStack vs = createValueStack();
+ vs.setExprOverrides(expr1);
+
+ assertEquals(vs.findValue("expr1"), "expr1value");
+
+ Map expr2 = new LinkedHashMap();
+ expr2.put("expr2", "'expr2value'");
+ expr2.put("expr3", "'expr3value'");
+ vs.setExprOverrides(expr2);
+
+ assertEquals(vs.findValue("expr2"), "expr2value");
+ assertEquals(vs.findValue("expr3"), "expr3value");
+ }
+
+
+ public void testArrayAsString() {
+ OgnlValueStack vs = createValueStack();
+
+ Dog dog = new Dog();
+ dog.setAge(12);
+ dog.setName("Rover");
+ dog.setChildAges(new int[]{1, 2});
+
+ vs.push(dog);
+ assertEquals("1, 2", vs.findValue("childAges", String.class));
+ }
+
+ public void testFailOnException() {
+ OgnlValueStack vs = createValueStack();
+
+ Dog dog = new Dog();
+ vs.push(dog);
+ try {
+ vs.findValue("bite", true);
+ fail("Failed to throw exception on EL error");
+ } catch (Exception ex) {
+ //ok
+ }
+ }
+
+ public void testFailOnErrorOnInheritedProperties() {
+ //this shuld not fail as the property is defined on a parent class
+ OgnlValueStack vs = createValueStack();
+
+ Foo foo = new Foo();
+ BarJunior barjr = new BarJunior();
+ foo.setBarJunior(barjr);
+ vs.push(foo);
+
+ assertNull(barjr.getTitle());
+ vs.findValue("barJunior.title", true);
+ }
+
+ public void testSuccessFailOnErrorOnInheritedPropertiesWithMethods() {
+ //this shuld not fail as the property is defined on a parent class
+ OgnlValueStack vs = createValueStack();
+
+ Foo foo = new Foo();
+ BarJunior barjr = new BarJunior();
+ foo.setBarJunior(barjr);
+ vs.push(foo);
+
+ assertNull(barjr.getTitle());
+ vs.findValue("getBarJunior().title", true);
+ }
+
+ public void testFailFailOnErrorOnInheritedPropertiesWithMethods() {
+ OgnlValueStack vs = createValueStack();
+
+ Foo foo = new Foo();
+ BarJunior barjr = new BarJunior();
+ foo.setBarJunior(barjr);
+ vs.push(foo);
+
+ assertNull(barjr.getTitle());
+ try {
+ vs.findValue("getBarJunior().title2", true);
+ fail("should have failed on missing property");
+ } catch (Exception e) {
+ }
+ }
+
+ public void testFailOnMissingProperty() {
+ OgnlValueStack vs = createValueStack();
+
+ Dog dog = new Dog();
+ vs.push(dog);
+ try {
+ vs.findValue("someprop", true);
+ fail("Failed to throw exception on EL missing property");
+ } catch (Exception ex) {
+ //ok
+ }
+ }
+
+ public void testFailOnMissingMethod() {
+ OgnlValueStack vs = createValueStack();
+
+ Dog dog = new Dog();
+ vs.push(dog);
+ try {
+ vs.findValue("someprop()", true);
+ fail("Failed to throw exception on EL missing method");
+ } catch (Exception ex) {
+ //ok
+ }
+ }
+
+ public void testFailsOnMethodThatThrowsException() {
+ SimpleAction action = new SimpleAction();
+ OgnlValueStack stack = createValueStack();
+ stack.push(action);
+
+ action.setThrowException(true);
+ try {
+ stack.findValue("exceptionMethod12()", true);
+ fail("Failed to throw exception on EL method exception");
+ } catch (Exception ex) {
+ //ok
+ }
+ }
+
+
+ public void testDoesNotFailOnNonActionObjects() {
+ //if a value is not found, then it will check for missing properties
+ //it needs to check in all objects in the stack, not only actions, see WW-3306
+ OgnlValueStack vs = createValueStack();
+
+ Dog dog = new Dog();
+ dog.setHates(null);
+ vs.push(dog);
+ vs.findValue("hates", true);
+ }
+
+
+ public void testFailOnMissingNestedProperty() {
+ OgnlValueStack vs = createValueStack();
+
+ Dog dog = new Dog();
+ dog.setHates(new Cat());
+ vs.push(dog);
+ try {
+ vs.findValue("hates.someprop", true);
+ fail("Failed to throw exception on EL missing nested property");
+ } catch (Exception ex) {
+ //ok
+ }
+ }
+
+ public void testBasic() {
+ OgnlValueStack vs = createValueStack();
+
+ Dog dog = new Dog();
+ dog.setAge(12);
+ dog.setName("Rover");
+
+ vs.push(dog);
+ assertEquals("Rover", vs.findValue("name", String.class));
+ }
+
+ public void testStatic() {
+ OgnlValueStack vs = createValueStack();
+
+ Dog dog = new Dog();
+ dog.setDeity("fido");
+ vs.push(dog);
+ assertEquals("fido", vs.findValue("@org.apache.struts2.xwork2.util.Dog@getDeity()", String.class));
+ }
+
+ public void testStaticMethodDisallow() {
+ OgnlValueStack vs = createValueStack(false);
+
+ Dog dog = new Dog();
+ dog.setDeity("fido");
+ vs.push(dog);
+ assertNull(vs.findValue("@org.apache.struts2.xwork2.util.Dog@getDeity()", String.class));
+ }
+
+ public void testBasicSet() {
+ OgnlValueStack vs = createValueStack();
+
+ Dog dog = new Dog();
+ dog.setAge(12);
+ dog.setName("Rover");
+
+ vs.set("dog", dog);
+ assertEquals("Rover", vs.findValue("dog.name", String.class));
+ }
+
+ public void testCallMethodOnNullObject() {
+ OgnlValueStack stack = createValueStack();
+ assertNull(stack.findValue("foo.size()"));
+ }
+
+ public void testCallMethodThatThrowsExceptionTwice() {
+ SimpleAction action = new SimpleAction();
+ OgnlValueStack stack = createValueStack();
+ stack.push(action);
+
+ action.setThrowException(true);
+ assertNull(stack.findValue("exceptionMethod1()"));
+ action.setThrowException(false);
+ assertEquals("OK", stack.findValue("exceptionMethod()"));
+ }
+
+
+ public void testCallMethodWithNullArg() {
+ SimpleAction action = new SimpleAction();
+ OgnlValueStack stack = createValueStack();
+ stack.push(action);
+
+ stack.findValue("setName(blah)");
+ assertNull(action.getName());
+
+ action.setBlah("blah");
+ stack.findValue("setName(blah)");
+ assertEquals("blah", action.getName());
+ }
+
+ public void testConvertStringArrayToList() {
+ Foo foo = new Foo();
+ OgnlValueStack vs = createValueStack();
+ vs.push(foo);
+
+ vs.setValue("strings", new String[]{"one", "two"});
+
+ assertNotNull(foo.getStrings());
+ assertEquals("one", foo.getStrings().get(0));
+ assertEquals("two", foo.getStrings().get(1));
+ }
+
+ public void testFindValueWithConversion() {
+
+ // register converter
+ TestBean2 tb2 = new TestBean2();
+
+ OgnlValueStack stack = createValueStack();
+ stack.push(tb2);
+ Map myContext = stack.getContext();
+
+ Map props = new HashMap();
+ props.put("cat", "Kitty");
+ ognlUtil.setProperties(props, tb2, myContext);
+ // expect String to be converted into a Cat
+ Assert.assertEquals("Kitty", tb2.getCat().getName());
+
+ // findValue should be able to access the name
+ Object value = stack.findValue("cat.name == 'Kitty'", Boolean.class);
+ assertNotNull(value);
+ assertEquals(Boolean.class, value.getClass());
+ assertEquals(Boolean.TRUE, value);
+
+ value = stack.findValue("cat == null", Boolean.class);
+ assertNotNull(value);
+ assertEquals(Boolean.class, value.getClass());
+ assertEquals(Boolean.FALSE, value);
+ }
+
+
+ public void testDeepProperties() {
+ OgnlValueStack vs = createValueStack();
+
+ Cat cat = new Cat();
+ cat.setName("Smokey");
+
+ Dog dog = new Dog();
+ dog.setAge(12);
+ dog.setName("Rover");
+ dog.setChildAges(new int[]{1, 2});
+ dog.setHates(cat);
+
+ vs.push(dog);
+ assertEquals("Smokey", vs.findValue("hates.name", String.class));
+ }
+
+ public void testFooBarAsString() {
+ OgnlValueStack vs = createValueStack();
+ Foo foo = new Foo();
+ Bar bar = new Bar();
+ bar.setTitle("blah");
+ bar.setSomethingElse(123);
+ foo.setBar(bar);
+
+ vs.push(foo);
+ assertEquals("blah:123", vs.findValue("bar", String.class));
+ }
+
+ public void testGetBarAsString() {
+ Foo foo = new Foo();
+ Bar bar = new Bar();
+ bar.setTitle("bar");
+ bar.setSomethingElse(123);
+ foo.setBar(bar);
+
+ OgnlValueStack vs = createValueStack();
+ vs.push(foo);
+
+ String output = (String) vs.findValue("bar", String.class);
+ assertEquals("bar:123", output);
+ }
+
+ public void testGetComplexBarAsString() {
+ // children foo->foo->foo
+ Foo foo = new Foo();
+ Foo foo2 = new Foo();
+ foo.setChild(foo2);
+
+ Foo foo3 = new Foo();
+ foo2.setChild(foo3);
+
+ // relatives
+ Foo fooA = new Foo();
+ foo.setRelatives(new Foo[]{fooA});
+
+ Foo fooB = new Foo();
+ foo2.setRelatives(new Foo[]{fooB});
+
+ Foo fooC = new Foo();
+ foo3.setRelatives(new Foo[]{fooC});
+
+ // the bar
+ Bar bar = new Bar();
+ bar.setTitle("bar");
+ bar.setSomethingElse(123);
+
+ // now place the bar all over
+ foo.setBar(bar);
+ foo2.setBar(bar);
+ foo3.setBar(bar);
+ fooA.setBar(bar);
+ fooB.setBar(bar);
+ fooC.setBar(bar);
+
+ OgnlValueStack vs = createValueStack();
+ vs.push(foo);
+
+ vs.getContext().put("foo", foo);
+
+ assertEquals("bar:123", vs.findValue("#foo.bar", String.class));
+ assertEquals("bar:123", vs.findValue("bar", String.class));
+ assertEquals("bar:123", vs.findValue("child.bar", String.class));
+ assertEquals("bar:123", vs.findValue("child.child.bar", String.class));
+ assertEquals("bar:123", vs.findValue("relatives[0].bar", String.class));
+ assertEquals("bar:123", vs.findValue("child.relatives[0].bar", String.class));
+ assertEquals("bar:123", vs.findValue("child.child.relatives[0].bar", String.class));
+
+ vs.push(vs.findValue("child"));
+ assertEquals("bar:123", vs.findValue("bar", String.class));
+ assertEquals("bar:123", vs.findValue("child.bar", String.class));
+ assertEquals("bar:123", vs.findValue("relatives[0].bar", String.class));
+ assertEquals("bar:123", vs.findValue("child.relatives[0].bar", String.class));
+ }
+
+ public void testGetNullValue() {
+ Dog dog = new Dog();
+ OgnlValueStack stack = createValueStack();
+ stack.push(dog);
+ assertNull(stack.findValue("name"));
+ }
+
+ public void testMapEntriesAvailableByKey() {
+ Foo foo = new Foo();
+ String title = "a title";
+ foo.setTitle(title);
+
+ OgnlValueStack vs = createValueStack();
+ vs.push(foo);
+
+ Map map = new HashMap();
+ String a_key = "a";
+ String a_value = "A";
+ map.put(a_key, a_value);
+
+ String b_key = "b";
+ String b_value = "B";
+ map.put(b_key, b_value);
+
+ vs.push(map);
+
+ assertEquals(title, vs.findValue("title"));
+ assertEquals(a_value, vs.findValue(a_key));
+ assertEquals(b_value, vs.findValue(b_key));
+ }
+
+ public void testMethodCalls() {
+ OgnlValueStack vs = createValueStack();
+
+ Dog dog1 = new Dog();
+ dog1.setAge(12);
+ dog1.setName("Rover");
+
+ Dog dog2 = new Dog();
+ dog2.setAge(1);
+ dog2.setName("Jack");
+ vs.push(dog1);
+ vs.push(dog2);
+
+ //assertEquals(new Boolean(false), vs.findValue("'Rover'.endsWith('Jack')"));
+ //assertEquals(new Boolean(false), vs.findValue("'Rover'.endsWith(name)"));
+ //assertEquals("RoverJack", vs.findValue("[1].name + name"));
+ assertEquals(new Boolean(false), vs.findValue("[1].name.endsWith(name)"));
+
+ assertEquals(new Integer(1 * 7), vs.findValue("computeDogYears()"));
+ assertEquals(new Integer(1 * 2), vs.findValue("multiplyAge(2)"));
+ assertEquals(new Integer(12 * 7), vs.findValue("[1].computeDogYears()"));
+ assertEquals(new Integer(12 * 5), vs.findValue("[1].multiplyAge(5)"));
+ assertNull(vs.findValue("thisMethodIsBunk()"));
+ assertEquals(new Integer(12 * 1), vs.findValue("[1].multiplyAge(age)"));
+
+ assertEquals("Jack", vs.findValue("name"));
+ assertEquals("Rover", vs.findValue("[1].name"));
+
+ //hates will be null
+ assertEquals(Boolean.TRUE, vs.findValue("nullSafeMethod(hates)"));
+ }
+
+ public void testMismatchedGettersAndSettersCauseExceptionInSet() {
+ OgnlValueStack vs = createValueStack();
+
+ BadJavaBean bean = new BadJavaBean();
+ vs.push(bean);
+
+ //this used to fail in OGNl versdion < 2.7
+ vs.setValue("count", "1", true);
+ assertEquals("1", bean.getCount());
+
+ try {
+ vs.setValue("count2", "a", true);
+ fail("Expected an exception for mismatched getter and setter");
+ } catch (XWorkException e) {
+ //expected
+ }
+ }
+
+ public void testNoExceptionInSetForDefault() {
+ OgnlValueStack vs = createValueStack();
+
+ BadJavaBean bean = new BadJavaBean();
+ vs.push(bean);
+
+ //this used to fail in OGNl versdion < 2.7
+ vs.setValue("count", "1", true);
+ assertEquals("1", bean.getCount());
+
+ try {
+ vs.setValue("count2", "a", true);
+ fail("Expected an exception for mismatched getter and setter");
+ } catch (XWorkException e) {
+ //expected
+ }
+ }
+
+ public void testNullEntry() {
+ OgnlValueStack vs = createValueStack();
+
+ Dog dog = new Dog();
+ dog.setName("Rover");
+
+ vs.push(dog);
+ assertEquals("Rover", vs.findValue("name", String.class));
+
+ vs.push(null);
+ assertEquals("Rover", vs.findValue("name", String.class));
+ }
+
+ public void testNullMethod() {
+ Dog dog = new Dog();
+ OgnlValueStack stack = createValueStack();
+ stack.push(dog);
+ assertNull(stack.findValue("nullMethod()"));
+ assertNull(stack.findValue("@org.apache.struts2.xwork2.util.OgnlValueStackTest@staticNullMethod()"));
+ }
+
+ public void testPetSoarBug() {
+ Cat cat = new Cat();
+ cat.setFoo(new Foo());
+
+ Bar bar = new Bar();
+ bar.setTitle("bar");
+ bar.setSomethingElse(123);
+ cat.getFoo().setBar(bar);
+
+ OgnlValueStack vs = createValueStack();
+ vs.push(cat);
+
+ assertEquals("bar:123", vs.findValue("foo.bar", String.class));
+ }
+
+ public void testPrimitiveSettingWithInvalidValueAddsFieldErrorInDevMode() {
+ SimpleAction action = new SimpleAction();
+ OgnlValueStack stack = createValueStack();
+ stack.getContext().put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+ stack.setDevMode("true");
+ stack.push(action);
+
+ try {
+ stack.setValue("bar", "3x");
+ fail("Attempt to set 'bar' int property to '3x' should result in RuntimeException");
+ }
+ catch (RuntimeException re) {
+ assertTrue(true);
+ }
+
+ Map conversionErrors = (Map) stack.getContext().get(ActionContext.CONVERSION_ERRORS);
+ assertTrue(conversionErrors.containsKey("bar"));
+ }
+
+ public void testPrimitiveSettingWithInvalidValueAddsFieldErrorInNonDevMode() {
+ SimpleAction action = new SimpleAction();
+ OgnlValueStack stack = createValueStack();
+ 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 testObjectSettingWithInvalidValueDoesNotCauseSetCalledWithNull() {
+ SimpleAction action = new SimpleAction();
+ action.setBean(new TestBean());
+ OgnlValueStack stack = createValueStack();
+ stack.getContext().put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+ stack.push(action);
+ try {
+ stack.setValue("bean", "foobar", true);
+ fail("Should have thrown a type conversion exception");
+ } catch (XWorkException e) {
+ // expected
+ }
+
+ Map conversionErrors = (Map) stack.getContext().get(ActionContext.CONVERSION_ERRORS);
+ assertTrue(conversionErrors.containsKey("bean"));
+ assertNotNull(action.getBean());
+ }
+
+
+ public void testSerializable() throws IOException, ClassNotFoundException {
+ OgnlValueStack vs = createValueStack();
+
+ Dog dog = new Dog();
+ dog.setAge(12);
+ dog.setName("Rover");
+
+ vs.push(dog);
+ assertEquals("Rover", vs.findValue("name", String.class));
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+ oos.writeObject(vs);
+ oos.flush();
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ ObjectInputStream ois = new ObjectInputStream(bais);
+
+ OgnlValueStack newVs = (OgnlValueStack) ois.readObject();
+ assertEquals("Rover", newVs.findValue("name", String.class));
+ }
+
+ public void testSetAfterPush() {
+ OgnlValueStack vs = createValueStack();
+
+ Dog d = new Dog();
+ d.setName("Rover");
+ vs.push(d);
+
+ vs.set("name", "Bill");
+
+ assertEquals("Bill", vs.findValue("name"));
+
+ }
+
+ public void testSetBarAsString() {
+ Foo foo = new Foo();
+
+ OgnlValueStack vs = createValueStack();
+ vs.push(foo);
+
+ vs.setValue("bar", "bar:123");
+
+ assertEquals("bar", foo.getBar().getTitle());
+ assertEquals(123, foo.getBar().getSomethingElse());
+ }
+
+ public void testSetBeforePush() {
+ OgnlValueStack vs = createValueStack();
+
+ vs.set("name", "Bill");
+ Dog d = new Dog();
+ d.setName("Rover");
+ vs.push(d);
+
+ assertEquals("Rover", vs.findValue("name"));
+
+ }
+
+ public void testSetDeepBarAsString() {
+ Foo foo = new Foo();
+ Foo foo2 = new Foo();
+ foo.setChild(foo2);
+
+ OgnlValueStack vs = createValueStack();
+ vs.push(foo);
+
+ vs.setValue("child.bar", "bar:123");
+
+ assertEquals("bar", foo.getChild().getBar().getTitle());
+ assertEquals(123, foo.getChild().getBar().getSomethingElse());
+ }
+
+ public void testSetNullList() {
+ Foo foo = new Foo();
+ OgnlValueStack vs = createValueStack();
+ vs.getContext().put(ReflectionContextState.CREATE_NULL_OBJECTS, Boolean.TRUE);
+ vs.push(foo);
+
+ vs.setValue("cats[0].name", "Cat One");
+ vs.setValue("cats[1].name", "Cat Two");
+
+ assertNotNull(foo.getCats());
+ assertEquals(2, foo.getCats().size());
+ assertEquals("Cat One", ((Cat) foo.getCats().get(0)).getName());
+ assertEquals("Cat Two", ((Cat) foo.getCats().get(1)).getName());
+
+ vs.setValue("cats[0].foo.cats[1].name", "Deep null cat");
+ assertNotNull(((Cat) foo.getCats().get(0)).getFoo());
+ assertNotNull(((Cat) foo.getCats().get(0)).getFoo().getCats());
+ assertNotNull(((Cat) foo.getCats().get(0)).getFoo().getCats().get(1));
+ assertEquals("Deep null cat", ((Cat) ((Cat) foo.getCats().get(0)).getFoo().getCats().get(1)).getName());
+ }
+
+ public void testSetMultiple() {
+ OgnlValueStack vs = createValueStack();
+ int origSize = vs.getRoot().size();
+ vs.set("something", new Object());
+ vs.set("somethingElse", new Object());
+ vs.set("yetSomethingElse", new Object());
+ assertEquals(origSize + 1, vs.getRoot().size());
+
+ }
+
+ public void testSetNullMap() {
+ Foo foo = new Foo();
+ OgnlValueStack vs = createValueStack();
+ vs.getContext().put(ReflectionContextState.CREATE_NULL_OBJECTS, Boolean.TRUE);
+ vs.push(foo);
+
+ vs.setValue("catMap['One'].name", "Cat One");
+ vs.setValue("catMap['Two'].name", "Cat Two");
+
+ assertNotNull(foo.getCatMap());
+ assertEquals(2, foo.getCatMap().size());
+ assertEquals("Cat One", ((Cat) foo.getCatMap().get("One")).getName());
+ assertEquals("Cat Two", ((Cat) foo.getCatMap().get("Two")).getName());
+
+ vs.setValue("catMap['One'].foo.catMap['Two'].name", "Deep null cat");
+ assertNotNull(((Cat) foo.getCatMap().get("One")).getFoo());
+ assertNotNull(((Cat) foo.getCatMap().get("One")).getFoo().getCatMap());
+ assertNotNull(((Cat) foo.getCatMap().get("One")).getFoo().getCatMap().get("Two"));
+ assertEquals("Deep null cat", ((Cat) ((Cat) foo.getCatMap().get("One")).getFoo().getCatMap().get("Two")).getName());
+ }
+
+ public void testSetReallyDeepBarAsString() {
+ Foo foo = new Foo();
+ Foo foo2 = new Foo();
+ foo.setChild(foo2);
+
+ Foo foo3 = new Foo();
+ foo2.setChild(foo3);
+
+ OgnlValueStack vs = createValueStack();
+ vs.push(foo);
+
+ vs.setValue("child.child.bar", "bar:123");
+
+ assertEquals("bar", foo.getChild().getChild().getBar().getTitle());
+ assertEquals(123, foo.getChild().getChild().getBar().getSomethingElse());
+ }
+
+ public void testSettingDogGender() {
+ OgnlValueStack vs = createValueStack();
+
+ Dog dog = new Dog();
+ vs.push(dog);
+
+ vs.setValue("male", "false");
+
+ assertEquals(false, dog.isMale());
+ }
+
+ public void testStatics() {
+ OgnlValueStack vs = createValueStack();
+
+ Cat cat = new Cat();
+ vs.push(cat);
+
+ Dog dog = new Dog();
+ dog.setAge(12);
+ dog.setName("Rover");
+ vs.push(dog);
+
+ assertEquals("Canine", vs.findValue("@vs@SCIENTIFIC_NAME"));
+ assertEquals("Canine", vs.findValue("@vs1@SCIENTIFIC_NAME"));
+ assertEquals("Feline", vs.findValue("@vs2@SCIENTIFIC_NAME"));
+ assertEquals(new Integer(BigDecimal.ROUND_HALF_DOWN), vs.findValue("@java.math.BigDecimal@ROUND_HALF_DOWN"));
+ assertNull(vs.findValue("@vs3@BLAH"));
+ assertNull(vs.findValue("@com.nothing.here.Nothing@BLAH"));
+ }
+
+ public void testTop() {
+ OgnlValueStack vs = createValueStack();
+
+ Dog dog1 = new Dog();
+ dog1.setAge(12);
+ dog1.setName("Rover");
+
+ Dog dog2 = new Dog();
+ dog2.setAge(1);
+ dog2.setName("Jack");
+ vs.push(dog1);
+ vs.push(dog2);
+
+ assertEquals(dog2, vs.findValue("top"));
+ assertEquals("Jack", vs.findValue("top.name"));
+ }
+
+ public void testTopIsDefaultTextProvider() {
+ OgnlValueStack vs = createValueStack();
+
+ assertEquals(container.getInstance(TextProvider.class, "system"), vs.findValue("top"));
+ }
+
+ public void testTwoDogs() {
+ OgnlValueStack vs = createValueStack();
+
+ Dog dog1 = new Dog();
+ dog1.setAge(12);
+ dog1.setName("Rover");
+
+ Dog dog2 = new Dog();
+ dog2.setAge(1);
+ dog2.setName("Jack");
+ vs.push(dog1);
+ vs.push(dog2);
+
+ assertEquals("Jack", vs.findValue("name"));
+ assertEquals("Rover", vs.findValue("[1].name"));
+
+ assertEquals(dog2, vs.pop());
+ assertEquals("Rover", vs.findValue("name"));
+ }
+
+ public void testTypeConversionError() {
+ TestBean bean = new TestBean();
+ OgnlValueStack stack = createValueStack();
+ stack.push(bean);
+ stack.getContext().put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
+ try {
+ stack.setValue("count", "a", true);
+ fail("Should have thrown a type conversion exception");
+ } catch (XWorkException e) {
+ // expected
+ }
+
+ Map conversionErrors = (Map) stack.getContext().get(ActionContext.CONVERSION_ERRORS);
+ assertTrue(conversionErrors.containsKey("count"));
+ }
+
+ public void testConstructorWithAStack() {
+ OgnlValueStack stack = createValueStack();
+ stack.push("Hello World");
+
+ OgnlValueStack stack2 = new OgnlValueStack(stack,
+ container.getInstance(XWorkConverter.class),
+ (CompoundRootAccessor) container.getInstance(PropertyAccessor.class, CompoundRoot.class.getName()), true);
+ container.inject(stack2);
+
+ assertEquals(stack.getRoot(), stack2.getRoot());
+ assertEquals(stack.peek(), stack2.peek());
+ assertEquals("Hello World", stack2.pop());
+
+ }
+
+ public void testDefaultType() {
+ OgnlValueStack stack = createValueStack();
+ stack.setDefaultType(String.class);
+ stack.push("Hello World");
+
+ assertEquals("Hello World", stack.findValue("top"));
+ assertEquals(null, stack.findValue(null));
+
+ stack.setDefaultType(Integer.class);
+ stack.push(new Integer(123));
+ assertEquals(new Integer(123), stack.findValue("top"));
+ }
+
+ public void testFindString() {
+ OgnlValueStack stack = createValueStack();
+ stack.setDefaultType(Integer.class);
+ stack.push("Hello World");
+
+ assertEquals("Hello World", stack.findString("top"));
+ assertEquals(null, stack.findString(null));
+ }
+
+ public void testExpOverrides() {
+ Map overrides = new HashMap();
+ overrides.put("claus", "top");
+
+ OgnlValueStack stack = createValueStack();
+ stack.setExprOverrides(overrides);
+ stack.push("Hello World");
+
+ assertEquals("Hello World", stack.findValue("claus"));
+ assertEquals("Hello World", stack.findString("claus"));
+ assertEquals("Hello World", stack.findValue("top"));
+ assertEquals("Hello World", stack.findString("top"));
+
+ assertEquals("Hello World", stack.findValue("claus", String.class));
+ assertEquals("Hello World", stack.findValue("top", String.class));
+
+ stack.getContext().put("santa", "Hello Santa");
+ assertEquals("Hello Santa", stack.findValue("santa", String.class));
+ assertEquals(null, stack.findValue("unknown", String.class));
+ }
+
+ public void testWarnAboutInvalidProperties() {
+ OgnlValueStack stack = createValueStack();
+ MyAction action = new MyAction();
+ action.setName("Don");
+ stack.push(action);
+
+ // how to test the warning was logged?
+ assertEquals("Don", stack.findValue("name", String.class));
+ assertEquals(null, stack.findValue("address", String.class));
+ // should log warning
+ assertEquals(null, stack.findValue("address.invalidProperty", String.class));
+
+ // if country is null, OGNL throws an exception
+ /*action.setAddress(new Address());
+ stack.push(action);*/
+ // should log warning
+ assertEquals(null, stack.findValue("address.country.id", String.class));
+ assertEquals(null, stack.findValue("address.country.name", String.class));
+ }
+
+ class BadJavaBean {
+ private int count;
+ private int count2;
+
+ public void setCount(int count) {
+ this.count = count;
+ }
+
+ public String getCount() {
+ return "" + count;
+ }
+
+ public void setCount2(String count2) {
+ this.count2 = Integer.parseInt(count2);
+ }
+
+ public int getCount2() {
+ return count2;
+ }
+ }
+
+ class MyAction {
+ private Long id;
+ private String name;
+ private Address address;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Address getAddress() {
+ return address;
+ }
+
+ public void setAddress(Address address) {
+ this.address = address;
+ }
+ }
+
+ class Address {
+ private String address;
+ private Country country;
+ private String city;
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public Country getCountry() {
+ return country;
+ }
+
+ public void setCountry(Country country) {
+ this.country = country;
+ }
+ }
+
+ class Country {
+ private String iso;
+ private String name;
+ private String displayName;
+
+ public String getIso() {
+ return iso;
+ }
+
+ public void setIso(String iso) {
+ this.iso = iso;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public void setDisplayName(String displayName) {
+ this.displayName = displayName;
+ }
+ }
+}