/*
* 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 com.opensymphony.xwork2.ognl;
import com.opensymphony.xwork2.*;
import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
import com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor;
import com.opensymphony.xwork2.test.TestBean2;
import com.opensymphony.xwork2.util.*;
import com.opensymphony.xwork2.util.Foo;
import com.opensymphony.xwork2.util.reflection.ReflectionContextState;
import ognl.PropertyAccessor;
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("@com.opensymphony.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("@com.opensymphony.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
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("@com.opensymphony.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;
}
}
}