package org.mvel2.tests.core;
import junit.framework.TestCase;
import org.mvel2.MVEL;
import org.mvel2.PropertyAccessor;
import org.mvel2.asm.MethodVisitor;
import static org.mvel2.asm.Opcodes.*;
import org.mvel2.integration.*;
import org.mvel2.optimizers.OptimizerFactory;
import org.mvel2.optimizers.impl.asm.ProducesBytecode;
import org.mvel2.tests.core.res.Bar;
import org.mvel2.tests.core.res.Base;
import org.mvel2.tests.core.res.Foo;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PropertyHandlerTests extends TestCase {
Base base = new Base();
public class TestPropertyHandler implements PropertyHandler, ProducesBytecode {
public Object getProperty(String name, Object contextObj,
VariableResolverFactory variableFactory) {
assertNotNull(contextObj);
assertEquals("0", name);
assertTrue(contextObj instanceof List);
return "gotcalled";
}
public Object setProperty(String name, Object contextObj,
VariableResolverFactory variableFactory, Object value) {
assertNotNull(contextObj);
assertEquals("0", name);
assertTrue(contextObj instanceof List);
((List) contextObj).set(0, "set");
return null;
}
public void produceBytecodeGet(MethodVisitor mv, String propertyName, VariableResolverFactory factory) {
mv.visitLdcInsn("gotcalled");
}
public void produceBytecodePut(MethodVisitor mv, String propertyName, VariableResolverFactory factory) {
mv.visitTypeInsn(CHECKCAST, "java/util/List");
mv.visitInsn(ICONST_0);
mv.visitLdcInsn("set");
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "set", "(ILjava/lang/Object;)Ljava/lang/Object;");
mv.visitInsn(POP);
mv.visitInsn(ACONST_NULL);
}
}
@Override
protected void setUp() throws Exception {
PropertyHandlerFactory.registerPropertyHandler(List.class, new TestPropertyHandler());
}
@Override
protected void tearDown() throws Exception {
GlobalListenerFactory.disposeAll();
PropertyHandlerFactory.disposeAll();
}
public void testListPropertyHandler() {
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
assertEquals("gotcalled", PropertyAccessor.get("list[0]", base));
PropertyAccessor.set(base, "list[0]", "hey you");
assertEquals("set", base.list.get(0));
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = false;
}
public void testListPropertyHandler2() {
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
Serializable s = MVEL.compileSetExpression("list[0]");
Base b;
MVEL.executeSetExpression(s, new Base(), "hey you");
MVEL.executeSetExpression(s, b = new Base(), "hey you");
assertEquals("set", b.list.get(0));
}
public void testListPropertyHandler3() {
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
OptimizerFactory.setDefaultOptimizer("ASM");
Serializable s = MVEL.compileSetExpression("list[0]");
Base b;
MVEL.executeSetExpression(s, new Base(), "hey you");
MVEL.executeSetExpression(s, b = new Base(), "hey you");
assertEquals("set", b.list.get(0));
}
public void testListPropertyHandler4() {
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
OptimizerFactory.setDefaultOptimizer("ASM");
final String[] res = new String[1];
GlobalListenerFactory.registerGetListener(new Listener() {
public void onEvent(Object context, String contextName, VariableResolverFactory variableFactory, Object value) {
System.out.println("Listener Fired:" + contextName);
res[0] = contextName;
}
});
Serializable s = MVEL.compileSetExpression("list[0]");
Base b;
MVEL.executeSetExpression(s, new Base(), "hey you");
res[0] = null;
MVEL.executeSetExpression(s, b = new Base(), "hey you");
assertEquals("set", b.list.get(0));
assertEquals("list", res[0]);
}
public void testNullPropertyHandler() {
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
OptimizerFactory.setDefaultOptimizer("ASM");
PropertyHandlerFactory.setNullPropertyHandler(new PropertyHandler() {
public Object getProperty(String name, Object contextObj, VariableResolverFactory variableFactory) {
return "NULL";
}
public Object setProperty(String name, Object contextObj, VariableResolverFactory variableFactory, Object value) {
return "NULL";
}
});
Foo foo = new Foo();
Bar bar = foo.getBar();
foo.setBar(null);
Map map = new HashMap();
map.put("foo", foo);
Serializable s = MVEL.compileExpression("foo.bar");
assertEquals("NULL", MVEL.executeExpression(s, map));
assertEquals("NULL", MVEL.executeExpression(s, map));
foo.setBar(bar);
assertEquals(bar, MVEL.executeExpression(s, map));
}
public void testNullPropertyHandler2() {
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
OptimizerFactory.setDefaultOptimizer("reflective");
PropertyHandlerFactory.setNullPropertyHandler(new PropertyHandler() {
public Object getProperty(String name, Object contextObj, VariableResolverFactory variableFactory) {
return "NULL";
}
public Object setProperty(String name, Object contextObj, VariableResolverFactory variableFactory, Object value) {
return "NULL";
}
});
Foo foo = new Foo();
Bar bar = foo.getBar();
foo.setBar(null);
Map map = new HashMap();
map.put("foo", foo);
Serializable s = MVEL.compileExpression("foo.bar");
assertEquals("NULL", MVEL.executeExpression(s, map));
assertEquals("NULL", MVEL.executeExpression(s, map));
foo.setBar(bar);
assertEquals(bar, MVEL.executeExpression(s, map));
}
public void testMapPropertyHandler() {
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
PropertyHandlerFactory.registerPropertyHandler(Map.class, new
PropertyHandler() {
public Object getProperty(String name, Object contextObj,
VariableResolverFactory variableFactory) {
assertNotNull(contextObj);
assertEquals("'key'", name);
assertTrue(contextObj instanceof Map);
return "gotcalled";
}
public Object setProperty(String name, Object contextObj,
VariableResolverFactory variableFactory, Object value) {
assertNotNull(contextObj);
assertEquals("'key'", name);
assertTrue(contextObj instanceof Map);
((Map) contextObj).put("key", "set");
return null;
}
});
assertEquals("gotcalled", PropertyAccessor.get("funMap['key']", base));
PropertyAccessor.set(base, "funMap['key']", "hey you");
assertEquals("set", base.funMap.get("key"));
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = false;
}
public void testArrayPropertyHandler() {
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
PropertyHandlerFactory.registerPropertyHandler(Array.class, new
PropertyHandler() {
public Object getProperty(String name, Object contextObj,
VariableResolverFactory variableFactory) {
assertNotNull(contextObj);
assertEquals("0", name);
assertTrue(contextObj.getClass().isArray());
return "gotcalled";
}
public Object setProperty(String name, Object contextObj,
VariableResolverFactory variableFactory, Object value) {
assertNotNull(contextObj);
assertEquals("0", name);
assertTrue(contextObj.getClass().isArray());
Array.set(contextObj, 0, "set");
return null;
}
});
assertEquals("gotcalled", PropertyAccessor.get("stringArray[0]", base));
PropertyAccessor.set(base, "stringArray[0]", "hey you");
assertEquals("set", base.stringArray[0]);
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = false;
}
public void testSetListListener() {
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
class MyListener implements Listener {
public int counter;
public void onEvent(Object context, String contextName,
VariableResolverFactory variableFactory, Object value) {
counter++;
}
}
class MyBean {
private List someList;
public List getSomeList() {
return someList;
}
}
MyListener listener = new MyListener();
GlobalListenerFactory.registerGetListener(listener);
MVEL.getProperty("someList", new MyBean());
MVEL.getProperty("someList", new MyBean());
assertEquals(2, listener.counter);
}
public void _testListener() {
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
class MyListener implements Listener {
public int count;
public void onEvent(Object context, String contextName,
VariableResolverFactory variableFactory, Object value) {
count++;
}
}
MyListener listener = new MyListener();
GlobalListenerFactory.registerGetListener(listener);
PropertyHandlerFactory.setNullPropertyHandler(new PropertyHandler() {
public Object getProperty(String name, Object contextObj,
VariableResolverFactory variableFactory) {
List someList = new ArrayList();
someList.add(new Foo());
return someList;
}
public Object setProperty(String name, Object contextObj,
VariableResolverFactory variableFactory, Object value) {
return null;
}
});
PropertyHandlerFactory.registerPropertyHandler(List.class, new
PropertyHandler() {
public Object getProperty(String name, Object contextObj,
VariableResolverFactory variableFactory) {
List list = (List) contextObj;
int index = Integer.valueOf(name);
while (index >= list.size()) {
list.add(new Foo());
}
return list.get(index);
}
public Object setProperty(String name, Object contextObj,
VariableResolverFactory variableFactory, Object value) {
return null;
}
});
Foo foo = new Foo();
final Serializable fooExpr0 =
MVEL.compileSetExpression("collectionTest[0].name");
final Serializable fooExpr1 =
MVEL.compileSetExpression("collectionTest[1].name");
MVEL.executeSetExpression(fooExpr0, foo, "John Galt");
MVEL.executeSetExpression(fooExpr1, foo, "The Joker");
assertEquals(2, listener.count);
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = false;
}
public class WorkObject {
Map<String, Object> map = new HashMap<String, Object>();
public boolean hasFieldName(String name) {
return map.containsKey(name);
}
public Object getFieldValue(String name) {
return map.get(name);
}
public void setFieldValue(String name, Object value, boolean bool) {
map.put(name, value);
}
}
public class WebPropertyHandler implements PropertyHandler {
public Object getProperty(String arg0, Object arg1,
VariableResolverFactory arg2) {
WorkObject wob = (WorkObject) arg1;
if (wob.hasFieldName(arg0)) {
return wob.getFieldValue(arg0);
}
else
return null;
}
public Object setProperty(String arg0, Object arg1,
VariableResolverFactory arg2, Object arg3) {
WorkObject wob = (WorkObject) arg1;
wob.setFieldValue(arg0, arg3, true);
return arg3;
}
}
public void testPropertyHandlerSetting() {
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
PropertyHandlerFactory.registerPropertyHandler(WorkObject.class, new WebPropertyHandler());
Map vars = new HashMap();
WorkObject wo = new WorkObject();
vars.put("wobj", wo);
MVEL.setProperty(vars, "wobj.foo", "foobie");
assertEquals("foobie", wo.getFieldValue("foo"));
}
}