package org.mvel2.tests.core;
import org.mvel2.CompileException;
import org.mvel2.ConversionHandler;
import org.mvel2.DataConversion;
import org.mvel2.MVEL;
import org.mvel2.ParserConfiguration;
import org.mvel2.ParserContext;
import org.mvel2.compiler.CompiledExpression;
import org.mvel2.compiler.ExecutableStatement;
import org.mvel2.compiler.ExpressionCompiler;
import org.mvel2.integration.impl.DefaultLocalVariableResolverFactory;
import org.mvel2.integration.impl.StaticMethodImportResolverFactory;
import org.mvel2.optimizers.OptimizerFactory;
import org.mvel2.tests.core.res.Bar;
import org.mvel2.tests.core.res.Base;
import org.mvel2.tests.core.res.Cheese;
import org.mvel2.tests.core.res.Foo;
import org.mvel2.tests.core.res.MyInterface2;
import org.mvel2.tests.core.res.MyInterface3;
import org.mvel2.tests.core.res.SampleBean;
import org.mvel2.util.MethodStub;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Formatter;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import static org.mvel2.MVEL.*;
/**
* @author Mike Brock .
*/
public class TypesAndInferenceTests extends AbstractTest {
public void testGenericInference() {
String expression = "$result = person.footributes[0].name";
ParserContext ctx;
MVEL.analysisCompile(expression,
ctx = ParserContext.create().stronglyTyped().withInput("person", Person.class));
assertEquals(String.class, ctx.getVarOrInputTypeOrNull("$result"));
Serializable s =
MVEL.compileExpression(expression, ParserContext.create().stronglyTyped().withInput("person", Person.class));
Map<String, Object> vars = new HashMap<String, Object>();
Person p = new Person();
p.setFootributes(new ArrayList<Foo>());
p.getFootributes().add(new Foo());
vars.put("person", p);
assertEquals("dog", executeExpression(s, vars));
}
public void testGenericInference2() {
ParserContext ctx;
MVEL.analysisCompile("$result = person.maptributes['fooey'].name",
ctx = ParserContext.create().stronglyTyped().withInput("person", Person.class));
assertEquals(String.class, ctx.getVarOrInputTypeOrNull("$result"));
}
public void testVarInputs() {
ParserContext pCtx = ParserContext.create();
MVEL.analysisCompile("test != foo && bo.addSomething(trouble) " +
"&& 1 + 2 / 3 == 1; String bleh = foo; twa = bleh;", pCtx);
assertEquals(4,
pCtx.getInputs().size());
assertTrue(pCtx.getInputs().containsKey("test"));
assertTrue(pCtx.getInputs().containsKey("foo"));
assertTrue(pCtx.getInputs().containsKey("bo"));
assertTrue(pCtx.getInputs().containsKey("trouble"));
assertEquals(2,
pCtx.getVariables().size());
assertTrue(pCtx.getVariables().containsKey("bleh"));
assertTrue(pCtx.getVariables().containsKey("twa"));
assertEquals(String.class,
pCtx.getVarOrInputType("bleh"));
}
public void testVarInputs2() {
ParserContext ctx = new ParserContext();
ExpressionCompiler compiler =
new ExpressionCompiler("test != foo && bo.addSomething(trouble); String bleh = foo; twa = bleh;", ctx);
compiler.compile();
System.out.println(ctx.getVarOrInputType("bleh"));
}
public void testVarInputs3() {
ExpressionCompiler compiler = new ExpressionCompiler("addresses['home'].street");
compiler.compile();
assertFalse(compiler.getParserContextState().getInputs().keySet().contains("home"));
}
public void testVarInputs4() {
ExpressionCompiler compiler = new ExpressionCompiler("System.out.println( message );");
compiler.compile();
assertTrue(compiler.getParserContextState().getInputs().keySet().contains("message"));
}
public void testVarInputs5() {
ParserContext pCtx = ParserContext.create().withInput("list", List.class);
MVEL.analysisCompile("String nodeName = list[0];\nSystem.out.println(nodeName);nodeName = list[1];\nSystem.out.println(nodeName);", pCtx);
assertEquals(1,
pCtx.getInputs().size());
assertTrue(pCtx.getInputs().containsKey("list"));
assertEquals(1,
pCtx.getVariables().size());
assertTrue(pCtx.getVariables().containsKey("nodeName"));
assertEquals(List.class,
pCtx.getVarOrInputType("list"));
assertEquals(String.class,
pCtx.getVarOrInputType("nodeName"));
}
public void testDetermineRequiredInputsInConstructor() throws Exception {
ParserContext ctx = new ParserContext();
ctx.setStrictTypeEnforcement(false);
ctx.setStrongTyping(false);
ctx.addImport(Foo.class);
ExpressionCompiler compiler = new ExpressionCompiler("new Foo244( $bar, $bar.age );", ctx);
Serializable compiled = compiler.compile();
Set<String> requiredInputs = compiler.getParserContextState().getInputs().keySet();
assertEquals(1, requiredInputs.size());
assertTrue(requiredInputs.contains("$bar"));
}
public void testAnalyzer() {
ParserContext ctx = new ParserContext();
MVEL.compileExpression("order.id == 10", ctx);
for (String input : ctx.getInputs().keySet()) {
System.out.println("input>" + input);
}
assertEquals(1, ctx.getInputs().size());
assertTrue(ctx.getInputs().containsKey("order"));
}
public void testAnalysisCompile() {
ParserContext pCtx = new ParserContext();
ExpressionCompiler e = new ExpressionCompiler("foo.aValue = 'bar'", pCtx);
e.setVerifyOnly(true);
e.compile();
assertTrue(pCtx.getInputs().keySet().contains("foo"));
assertEquals(1,
pCtx.getInputs().size());
assertEquals(0,
pCtx.getVariables().size());
}
public void testMultiVarDeclr() {
String ex = "var a, b, c";
ParserContext ctx = new ParserContext();
ExpressionCompiler compiler = new ExpressionCompiler(ex, ctx);
compiler.setVerifyOnly(true);
compiler.compile();
assertEquals(3,
ctx.getVariables().size());
}
public void testVarDeclr() {
String ex = "var a";
ParserContext ctx = new ParserContext();
ExpressionCompiler compiler = new ExpressionCompiler(ex, ctx);
compiler.setVerifyOnly(true);
compiler.compile();
assertEquals(1,
ctx.getVariables().size());
}
public void testMultiTypeVarDeclr() {
String ex = "String a, b, c";
ParserContext ctx = new ParserContext();
ExpressionCompiler compiler = new ExpressionCompiler(ex, ctx);
compiler.compile();
assertNotNull(ctx.getVariables());
assertEquals(3,
ctx.getVariables().entrySet().size());
for (Map.Entry<String, Class> entry : ctx.getVariables().entrySet()) {
assertEquals(String.class,
entry.getValue());
}
}
public void testMultiTypeVarDeclr2() {
String ex = "String a = 'foo', b = 'baz', c = 'bar'";
ParserContext ctx = new ParserContext();
ExpressionCompiler compiler = new ExpressionCompiler(ex, ctx);
compiler.compile();
assertNotNull(ctx.getVariables());
assertEquals(3,
ctx.getVariables().entrySet().size());
for (Map.Entry<String, Class> entry : ctx.getVariables().entrySet()) {
assertEquals(String.class,
entry.getValue());
}
}
public void testMultiTypeVarDeclr3() {
String ex = "int a = 52 * 3, b = 8, c = 16;";
ParserContext ctx = new ParserContext();
ExpressionCompiler compiler = new ExpressionCompiler(ex, ctx);
Serializable s = compiler.compile();
assertNotNull(ctx.getVariables());
assertEquals(3,
ctx.getVariables().entrySet().size());
for (Map.Entry<String, Class> entry : ctx.getVariables().entrySet()) {
assertEquals(int.class,
entry.getValue());
}
Map vars = new HashMap();
executeExpression(s,
vars);
assertEquals(52 * 3,
vars.get("a"));
assertEquals(8,
vars.get("b"));
assertEquals(16,
vars.get("c"));
}
public void testTypeVarDeclr() {
String ex = "String a;";
ParserContext ctx = new ParserContext();
ExpressionCompiler compiler = new ExpressionCompiler(ex, ctx);
compiler.compile();
assertNotNull(ctx.getVariables());
assertEquals(1,
ctx.getVariables().entrySet().size());
for (Map.Entry<String, Class> entry : ctx.getVariables().entrySet()) {
assertEquals(String.class,
entry.getValue());
}
}
public void testStrictTypingCompilation4() throws NoSuchMethodException {
ParserContext ctx = new ParserContext();
ctx.addImport(Foo.class);
ctx.setStrictTypeEnforcement(true);
ExpressionCompiler compiler = new ExpressionCompiler("x_a = new Foo()", ctx);
compiler.compile();
assertEquals(Foo.class,
ctx.getVariables().get("x_a"));
}
public void testEgressType() {
ParserContext context = new ParserContext();
context.addInput("$cheese",
Cheese.class);
ExpressionCompiler compiler = new ExpressionCompiler("( $cheese )", context);
assertEquals(Cheese.class,
compiler.compile().getKnownEgressType());
}
public void testEgressTypeCorrect() {
ExecutableStatement stmt = (ExecutableStatement)
MVEL.compileExpression("type", ParserContext.create().stronglyTyped()
.withInput("this", Cheese.class));
assertEquals(String.class,
stmt.getKnownEgressType());
}
public void testEgressTypeCorrect2() {
ParserContext context = new ParserContext();
context.setStrongTyping(true);
context.addInput("this",
SampleBean.class);
ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression("( map2[ 'yyy' ] )", context);
SampleBean s = new SampleBean();
s.getMap2().put("yyy", 1);
assertEquals(new Integer(1),
MVEL.executeExpression(stmt, s));
}
public static final List<String> STRINGS = Arrays.asList("hi",
"there");
public static class A {
public void foo(String s) {
}
public void bar(String s) {
}
public List<String> getStrings() {
return STRINGS;
}
}
public static class B extends A {
@Override
public void foo(String s) {
super.foo(s);
}
public void bar(int s) {
}
}
public static class C extends A {
}
public final void testDetermineEgressParametricType() {
final ParserContext parserContext = new ParserContext();
parserContext.setStrongTyping(true);
parserContext.addInput("strings",
List.class,
new Class[]{String.class});
final CompiledExpression expr = new ExpressionCompiler("strings", parserContext).compile();
assertTrue(STRINGS.equals(executeExpression(expr,
new A())));
/*
final Type[] typeParameters = expr.getParserContext().getLastTypeParameters();
assertTrue(typeParameters != null);
assertTrue(String.class.equals(typeParameters[0]));
*/
}
public final void testDetermineEgressParametricType2() {
final ParserContext parserContext = new ParserContext();
parserContext.setStrongTyping(true);
parserContext.addInput("strings",
List.class,
new Class[]{String.class});
final CompiledExpression expr = new ExpressionCompiler("strings",
parserContext).compile();
assertTrue(STRINGS.equals(executeExpression(expr,
new A())));
/*
final Type[] typeParameters = expr.getParserContext().getLastTypeParameters();
assertTrue(null != typeParameters);
assertTrue(String.class.equals(typeParameters[0]));
*/
}
public void testJIRA151c() {
OptimizerFactory.setDefaultOptimizer(OptimizerFactory.SAFE_REFLECTIVE);
A b = new B();
A c = new C();
ParserContext context = new ParserContext();
Object expression = MVEL.compileExpression("a.foo(value)",
context);
for (int i = 0; i < 100; i++) {
System.out.println("i: " + i);
System.out.flush();
{
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("a", b);
variables.put("value", 123);
executeExpression(expression, variables);
}
{
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("a", c);
variables.put("value", 123);
executeExpression(expression, variables);
}
}
}
public void testJIRA151d() {
OptimizerFactory.setDefaultOptimizer("ASM");
A b = new B();
A c = new C();
ParserContext context = new ParserContext();
Object expression = MVEL.compileExpression("a.foo(value)",
context);
for (int i = 0; i < 100; i++) {
System.out.println("i: " + i);
System.out.flush();
{
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("a", b);
variables.put("value", 123);
executeExpression(expression, variables);
}
{
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("a", c);
variables.put("value", 123);
executeExpression(expression, variables);
}
}
}
public void testJIRA165b() {
OptimizerFactory.setDefaultOptimizer("ASM");
A b = new B();
A a = new A();
ParserContext context = new ParserContext();
Object expression = MVEL.compileExpression("a.bar(value)",
context);
for (int i = 0; i < 100; i++) {
System.out.println("i: " + i);
System.out.flush();
{
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("a", b);
variables.put("value", 123);
executeExpression(expression, variables);
}
{
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("a", a);
variables.put("value", 123);
executeExpression(expression, variables);
}
}
}
public void testJIRA165() {
OptimizerFactory.setDefaultOptimizer(OptimizerFactory.SAFE_REFLECTIVE);
A b = new B();
A a = new A();
ParserContext context = new ParserContext();
Object expression = MVEL.compileExpression("a.bar(value)",
context);
for (int i = 0; i < 100; i++) {
System.out.println("i: " + i);
System.out.flush();
{
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("a", b);
variables.put("value", 123);
executeExpression(expression, variables);
}
{
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("a", a);
variables.put("value", 123);
executeExpression(expression, variables);
}
}
}
public void testStrictTypingCompilationWithVarInsideConstructor() {
ParserContext ctx = new ParserContext();
ctx.addInput("$likes", String.class);
ctx.addInput("results", List.class);
ctx.addImport(Cheese.class);
ctx.setStrongTyping(true);
Serializable expr = null;
try {
expr = MVEL.compileExpression("Cheese c = new Cheese( $likes, 15 );\nresults.add( c ); ", ctx);
}
catch (CompileException e) {
e.printStackTrace();
fail("This should not fail:\n" + e.getMessage());
}
List results = new ArrayList();
Map vars = new HashMap();
vars.put("$likes", "stilton");
vars.put("results", results);
executeExpression(expr, vars);
assertEquals(new Cheese("stilton", 15), results.get(0));
}
public void testParameterizedTypeInStrictMode2() {
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("ctx",
Object.class);
ExpressionCompiler compiler =
new ExpressionCompiler("org.mvel2.DataConversion.convert(ctx, String).toUpperCase()", ctx);
assertEquals(String.class,
compiler.compile().getKnownEgressType());
}
public void testParameterizedTypeInStrictMode3() {
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("base",
Base.class);
ExpressionCompiler compiler = new ExpressionCompiler("base.list");
// assertTrue(compiler.compile(ctx).getParserContext().getLastTypeParameters()[0].equals(String.class));
}
public void testParameterizedTypeInStrictMode4() {
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("base",
Base.class);
ExpressionCompiler compiler = new ExpressionCompiler("base.list.get(1).toUpperCase()", ctx);
CompiledExpression ce = compiler.compile();
assertEquals(String.class,
ce.getKnownEgressType());
}
public void testReturnType1() {
assertEquals(Double.class,
new ExpressionCompiler("100.5").compile().getKnownEgressType());
}
public void testReturnType2() {
assertEquals(Integer.class,
new ExpressionCompiler("1").compile().getKnownEgressType());
}
public void testStrongTyping3() {
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
try {
new ExpressionCompiler("foo.toUC(100.5", ctx).compile();
}
catch (Exception e) {
// should fail.
return;
}
assertTrue(false);
}
public void testEgressType1() {
assertEquals(Boolean.class,
new ExpressionCompiler("foo != null").compile().getKnownEgressType());
}
public void testStrictStaticMethodCall() {
ParserContext ctx = new ParserContext();
ctx.addImport("Bar",
Bar.class);
ctx.setStrictTypeEnforcement(true);
ExpressionCompiler compiler = new ExpressionCompiler("Bar.staticMethod()", ctx);
Serializable s = compiler.compile();
assertEquals(1,
executeExpression(s));
}
public void testStrictTypingCompilation2() throws Exception {
ParserContext ctx = new ParserContext();
//noinspection RedundantArrayCreation
ctx.addImport("getRuntime",
new MethodStub(Runtime.class.getMethod("getRuntime",
new Class[]{})));
ctx.setStrictTypeEnforcement(true);
ExpressionCompiler compiler = new ExpressionCompiler("getRuntime()", ctx);
StaticMethodImportResolverFactory si = new StaticMethodImportResolverFactory(ctx);
Serializable expression = compiler.compile();
serializationTest(expression);
assertTrue(executeExpression(expression,
si) instanceof Runtime);
}
public void testStrictTypingCompilation3() throws NoSuchMethodException {
ParserContext ctx = new ParserContext();
ctx.setStrictTypeEnforcement(true);
ExpressionCompiler compiler =
new ExpressionCompiler("message='Hello';b=7;\nSystem.out.println(message + ';' + b);\n"
+ "System.out.println(message + ';' + b); b", ctx);
assertEquals(7,
executeExpression(compiler.compile(),
new DefaultLocalVariableResolverFactory()));
}
public void testStrictStrongTypingCompilationErrors1() throws Exception {
ParserContext ctx = new ParserContext();
ctx.setStrictTypeEnforcement(true);
ctx.setStrongTyping(true);
ctx.addImport(Foo.class);
ctx.addInput("$bar", Bar.class);
try {
ExpressionCompiler compiler = new ExpressionCompiler("System.out.println( $ba );", ctx);
compiler.compile();
fail("This should not compileShared");
}
catch (Exception e) {
}
}
public void testStrictStrongTypingCompilationErrors2() throws Exception {
ParserContext ctx = new ParserContext();
ctx.setStrictTypeEnforcement(true);
ctx.setStrongTyping(true);
ctx.addImport(Foo.class);
ctx.addInput("$bar", Bar.class);
try {
MVEL.compileExpression("x_a = new Foo244( $ba ); x_a.equals($ba);", ctx);
fail("This should not compileShared");
}
catch (Exception e) {
e.printStackTrace();
}
}
public void testProvidedExternalTypes() {
ParserContext ctx = new ParserContext();
ctx.setStrictTypeEnforcement(true);
ctx.addInput("foo",
Foo.class);
ExpressionCompiler compiler = new ExpressionCompiler("foo.bar", ctx);
compiler.compile();
}
public static class ScriptHelper228 {
public void methodA() {
}
public void methodB(int param1) {
}
}
public static class Person228 {
public String getName() {
return "foo";
}
}
public void testMVEL228() {
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.setStrictTypeEnforcement(true);
HashMap<String, Class> params = new HashMap<String, Class>();
params.put("helper", ScriptHelper228.class);
params.put("person", Person228.class);
ctx.setInputs(params);
String script = "helper.methodB(2);\n" +
"person.getName2();";
try {
CompiledExpression compiled = (CompiledExpression) MVEL.compileExpression(script, ctx);
}
catch (Exception e) {
return;
}
fail("Should have thrown an exception");
}
public void testMVEL232() {
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.setStrictTypeEnforcement(true);
String script = "for(int i=0;i<2;i++) { " +
" System.out.println(i+\"\");" +
"} " +
" return true;";
try {
CompiledExpression compiled = (CompiledExpression) MVEL.compileExpression(script, ctx);
HashMap<String, Object> map = new HashMap<String, Object>();
MVEL.executeExpression(compiled, map);
}
catch (Exception e) {
e.printStackTrace();
fail("should now throw an exception");
}
}
public void testMVEL234() {
StringBuffer buffer = new StringBuffer();
buffer.append("import java.text.SimpleDateFormat;");
buffer.append("if (\"test\".matches(\"[0-9]\")) {");
buffer.append(" return false;");
buffer.append("}else{");
buffer.append(" SimpleDateFormat sqf = new SimpleDateFormat(\"yyyyMMdd\");");
buffer.append("}");
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
try {
CompiledExpression compiled = (CompiledExpression) MVEL.compileExpression(buffer.toString(), ctx);
}
catch (Exception e) {
fail(e.getMessage());
}
}
public void testMVEL235() {
StringBuffer buffer = new StringBuffer();
buffer.append("if(var1.equals(var2)) {");
buffer.append("return true;");
buffer.append("}");
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("var1", MyInterface2.class);
ctx.addInput("var2", MyInterface2.class);
try {
Serializable compiled = (Serializable) MVEL.compileExpression(buffer.toString(), ctx);
System.out.println(compiled);
}
catch (Exception e) {
fail(e.getMessage());
}
}
public void testMVEL236() {
StringBuffer buffer = new StringBuffer();
buffer.append("MyInterface2 var2 = (MyInterface2)var1;");
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("var1", MyInterface3.class);
ctx.addImport(MyInterface2.class);
ctx.addImport(MyInterface3.class);
try {
CompiledExpression compiled = (CompiledExpression) MVEL.compileExpression(buffer.toString(), ctx);
}
catch (Exception e) {
fail(e.getMessage());
}
}
public static class MapWrapper {
private Map map = new HashMap();
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
}
public void testMapPropertyAccess() {
ParserContext ctx = new ParserContext();
ctx.addImport(MapWrapper.class);
ctx.addInput("wrapper", MapWrapper.class);
ctx.setStrongTyping(true);
Serializable expr = MVEL.compileExpression("wrapper.map[\"key\"]", ctx);
MapWrapper wrapper = new MapWrapper();
wrapper.getMap().put("key", "value");
Map vars = new HashMap();
vars.put("wrapper", wrapper);
assertEquals("value", MVEL.executeExpression(expr, vars));
}
public void testTypeCast3() {
Map map = new HashMap();
map.put("foo",
new Foo());
ParserContext pCtx = new ParserContext();
pCtx.setStrongTyping(true);
pCtx.addInput("foo",
Foo.class);
Serializable s = MVEL.compileExpression("((org.mvel2.tests.core.res.Bar) foo.getBar()).name != null",
pCtx);
assertEquals(true,
executeExpression(s,
map));
assertEquals(1,
pCtx.getInputs().size());
assertEquals(true,
pCtx.getInputs().containsKey("foo"));
}
public void testMapWithStrictTyping() {
ParserContext ctx = new ParserContext();
ctx.setStrictTypeEnforcement(true);
ctx.setStrongTyping(true);
ctx.addInput("$msg",
String.class);
ctx.addInput("map",
Map.class);
ExpressionCompiler compiler = new ExpressionCompiler("map['KEY1'] == $msg", ctx);
Serializable expr = compiler.compile();
Map map = new HashMap();
map.put("KEY1",
"MSGONE");
Map vars = new HashMap();
vars.put("$msg",
"MSGONE");
vars.put("map",
map);
Boolean bool = (Boolean) executeExpression(expr,
map,
vars);
assertEquals(Boolean.TRUE,
bool);
}
public void testMapAsContextWithStrictTyping() {
ParserContext ctx = new ParserContext();
ctx.setStrictTypeEnforcement(true);
ctx.setStrongTyping(true);
ctx.addInput("$msg",
String.class);
ctx.addInput("this",
Map.class);
ExpressionCompiler compiler = new ExpressionCompiler("this['KEY1'] == $msg", ctx);
Serializable expr = compiler.compile();
Map map = new HashMap();
map.put("KEY1",
"MSGONE");
Map vars = new HashMap();
vars.put("$msg",
"MSGONE");
Boolean bool = (Boolean) executeExpression(expr,
map,
vars);
assertEquals(Boolean.TRUE,
bool);
}
public void testStrongTyping() {
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
try {
new ExpressionCompiler("blah", ctx).compile();
}
catch (Exception e) {
// should fail
return;
}
assertTrue(false);
}
public void testStrongTyping2() {
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("blah",
String.class);
try {
new ExpressionCompiler("1-blah", ctx).compile();
}
catch (Exception e) {
e.printStackTrace();
return;
}
assertTrue(false);
}
public void testParameterizedTypeInStrictMode() {
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("foo",
HashMap.class,
new Class[]{String.class, String.class});
ExpressionCompiler compiler = new ExpressionCompiler("foo.get('bar').toUpperCase()", ctx);
compiler.compile();
}
public void testSetAccessorOverloadedEqualsStrictMode2() {
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("foo",
Foo.class);
try {
CompiledExpression expr = new ExpressionCompiler("foo.aValue = 'bar'", ctx).compile();
}
catch (CompileException e) {
assertTrue(false);
}
}
public void testDataConverterStrictMode() throws Exception {
OptimizerFactory.setDefaultOptimizer("ASM");
DataConversion.addConversionHandler(Date.class,
new MVELDateCoercion());
ParserContext ctx = new ParserContext();
ctx.addImport("Cheese",
Cheese.class);
ctx.setStrongTyping(true);
ctx.setStrictTypeEnforcement(true);
Locale.setDefault(Locale.US);
Cheese expectedCheese = new Cheese();
expectedCheese.setUseBy(new SimpleDateFormat("dd-MMM-yyyy").parse("10-Jul-1974"));
ExpressionCompiler compiler = new ExpressionCompiler("c = new Cheese(); c.useBy = '10-Jul-1974'; return c", ctx);
Cheese actualCheese = (Cheese) executeExpression(compiler.compile(),
createTestMap());
assertEquals(expectedCheese.getUseBy(),
actualCheese.getUseBy());
}
public static class MVELDateCoercion implements ConversionHandler {
public boolean canConvertFrom(Class cls) {
return cls == String.class || cls.isAssignableFrom(Date.class);
}
public Object convertFrom(Object o) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
if (o instanceof String) {
return sdf.parse((String) o);
} else {
return o;
}
}
catch (Exception e) {
throw new RuntimeException("Exception was thrown",
e);
}
}
}
public void testCompileTimeCoercion() {
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("foo",
Foo.class);
assertEquals(true,
executeExpression(new ExpressionCompiler("foo.bar.woof == 'true'", ctx).compile(),
createTestMap()));
}
public void testSetCoercion() {
Serializable s = compileSetExpression("name");
Foo foo = new Foo();
executeSetExpression(s,
foo,
12);
assertEquals("12",
foo.getName());
foo = new Foo();
setProperty(foo,
"name",
12);
assertEquals("12",
foo.getName());
}
public void testSetCoercion2() {
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("sampleBean",
SampleBean.class);
Serializable s = compileSetExpression("sampleBean.map2['bleh']",
ctx);
Foo foo = new Foo();
executeSetExpression(s,
foo,
"12");
assertEquals(12,
foo.getSampleBean().getMap2().get("bleh").intValue());
foo = new Foo();
executeSetExpression(s,
foo,
"13");
assertEquals(13,
foo.getSampleBean().getMap2().get("bleh").intValue());
OptimizerFactory.setDefaultOptimizer("ASM");
ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("sampleBean",
SampleBean.class);
s = compileSetExpression("sampleBean.map2['bleh']",
ctx);
foo = new Foo();
executeSetExpression(s,
foo,
"12");
assertEquals(12,
foo.getSampleBean().getMap2().get("bleh").intValue());
executeSetExpression(s,
foo,
new Integer(12));
assertEquals(12,
foo.getSampleBean().getMap2().get("bleh").intValue());
}
public void testListCoercion() {
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("bar",
Bar.class);
Serializable s = compileSetExpression("bar.testList[0]",
ctx);
Foo foo = new Foo();
foo.getBar().getTestList().add(new Integer(-1));
executeSetExpression(s,
foo,
"12");
assertEquals(12,
foo.getBar().getTestList().get(0).intValue());
foo = new Foo();
foo.getBar().getTestList().add(new Integer(-1));
executeSetExpression(s,
foo,
"13");
assertEquals(13,
foo.getBar().getTestList().get(0).intValue());
OptimizerFactory.setDefaultOptimizer("ASM");
ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("bar",
Bar.class);
s = compileSetExpression("bar.testList[0]",
ctx);
foo = new Foo();
foo.getBar().getTestList().add(new Integer(-1));
executeSetExpression(s,
foo,
"12");
assertEquals(12,
foo.getBar().getTestList().get(0).intValue());
executeSetExpression(s,
foo,
"13");
assertEquals(13,
foo.getBar().getTestList().get(0).intValue());
}
public void testFieldCoercion1() {
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("bar",
Bar.class);
Serializable s = compileSetExpression("bar.assignTest",
ctx);
Foo foo = new Foo();
executeSetExpression(s,
foo,
12);
assertEquals("12",
foo.getBar().getAssignTest());
foo = new Foo();
executeSetExpression(s,
foo,
13);
assertEquals("13",
foo.getBar().getAssignTest());
OptimizerFactory.setDefaultOptimizer("ASM");
ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("bar",
Bar.class);
s = compileSetExpression("bar.assignTest",
ctx);
foo = new Foo();
executeSetExpression(s,
foo,
12);
assertEquals("12",
foo.getBar().getAssignTest());
executeSetExpression(s,
foo,
13);
assertEquals("13",
foo.getBar().getAssignTest());
}
public void testStaticTyping2() {
String exp = "int x = 5; int y = 2; new int[] { x, y }";
int[] res = (int[]) MVEL.eval(exp, new HashMap());
assertEquals(5, res[0]);
assertEquals(2, res[1]);
}
public void testMVEL190a() {
Serializable compiled = MVEL.compileExpression("a.toString()", ParserContext.create().stronglyTyped().withInput("a", String.class));
}
public void testPrimitiveTypes() {
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("base",
Base.class);
Serializable s = compileExpression("int x = 5; x = x + base.intValue; x",
ctx);
Map vars = new HashMap();
vars.put("base",
new Base());
Number x = (Number) executeExpression(s,
vars);
assertEquals(15,
x.intValue());
}
public void testAutoBoxing() {
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
//ctx.addInput("base", Base.class);
Serializable s = compileExpression("(list = new java.util.ArrayList()).add( 5 ); list",
ctx);
Map vars = new HashMap();
//vars.put("base", new Base());
List list = (List) executeExpression(s,
vars);
assertEquals(1,
list.size());
}
public void testAutoBoxing2() {
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("base",
Base.class);
Serializable s = compileExpression("java.util.List list = new java.util.ArrayList(); " +
"list.add( base.intValue ); list",
ctx);
Map vars = new HashMap();
vars.put("base",
new Base());
List list = (List) executeExpression(s,
vars);
assertEquals(1,
list.size());
}
public void testTypeCoercion() {
OptimizerFactory.setDefaultOptimizer("ASM");
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("base",
Base.class);
Serializable s = compileExpression("java.math.BigInteger x = new java.math.BigInteger( \"5\" );" +
" x + base.intValue;",
ctx);
Map vars = new HashMap();
vars.put("base",
new Base());
Number x = (Number) executeExpression(s,
vars);
assertEquals(15,
x.intValue());
}
public void testTypeCoercion2() {
OptimizerFactory.setDefaultOptimizer("reflective");
ParserContext ctx = new ParserContext();
ctx.setStrongTyping(true);
ctx.addInput("base",
Base.class);
Serializable s = compileExpression("java.math.BigInteger x = new java.math.BigInteger( \"5\" );" +
" x + base.intValue;",
ctx);
Map vars = new HashMap();
vars.put("base",
new Base());
Number x = (Number) executeExpression(s,
vars);
assertEquals(15,
x.intValue());
}
public void testStaticFieldAccessForInputs() {
MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = true;
ParserContext pCtx = ParserContext.create();
MVEL.analysisCompile("java.math.BigDecimal.TEN", pCtx);
assertFalse(pCtx.getInputs().containsKey("java"));
assertEquals(0,
pCtx.getInputs().size());
// MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = true;
//
// pCtx = ParserContext.create();
// MVEL.analysisCompile("java.math.BigDecimal.TEN", pCtx);
//
// assertFalse(pCtx.getInputs().containsKey("java"));
//
// assertEquals(0,
// pCtx.getInputs().size());
}
public void testStaticFieldAccessForInputsWithStrictStrong() {
ParserContext pCtx = ParserContext.create();
pCtx.setStrictTypeEnforcement(true);
pCtx.setStrongTyping(true);
MVEL.analysisCompile("java.math.BigDecimal.TEN", pCtx);
assertFalse(pCtx.getInputs().containsKey("java"));
assertEquals(0,
pCtx.getInputs().size());
MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = true;
pCtx = ParserContext.create();
pCtx.setStrictTypeEnforcement(true);
pCtx.setStrongTyping(true);
MVEL.analysisCompile("java.math.BigDecimal.TEN", pCtx);
assertFalse(pCtx.getInputs().containsKey("java"));
assertEquals(0,
pCtx.getInputs().size());
}
public void testStaticMethodsInInputsBug() {
String text = " getList( java.util.Formatter )";
ParserConfiguration pconf = new ParserConfiguration();
for (Method m : CoreConfidenceTests.StaticMethods.class.getMethods()) {
if (Modifier.isStatic(m.getModifiers())) {
pconf.addImport(m.getName(), m);
}
}
ParserContext pctx = new ParserContext(pconf);
pctx.setStrictTypeEnforcement(false);
pctx.setStrongTyping(false);
Map<String, Object> vars = new HashMap<String, Object>();
Serializable expr = MVEL.compileExpression(text, pctx);
List list = (List) MVEL.executeExpression(expr, null, vars);
assertEquals(Formatter.class, list.get(0));
assertEquals(0, pctx.getInputs().size());
}
public static class EchoContext {
public String echo(String str) {
return str;
}
}
public void testStaticMethodCallThrowsException() {
String text = " ( throwException( ) ) ";
ParserConfiguration pconf = new ParserConfiguration();
for (Method m : CoreConfidenceTests.StaticMethods.class.getMethods()) {
if (Modifier.isStatic(m.getModifiers())) {
pconf.addImport(m.getName(), m);
}
}
ParserContext pctx = new ParserContext(pconf);
pctx.setStrictTypeEnforcement(true);
pctx.setStrongTyping(true);
Map<String, Object> vars = new HashMap<String, Object>();
Serializable expr = MVEL.compileExpression(text, pctx);
try {
MVEL.executeExpression(expr);
fail("this should throw an exception");
}
catch (Exception e) {
e.printStackTrace();
}
}
public void testContextMethodCallsInStrongMode() {
ParserContext context = new ParserContext();
context.setStrongTyping(true);
context.addInput("this",
EchoContext.class);
ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression("this.echo( 'Mac')", context);
stmt = (ExecutableStatement) MVEL.compileExpression("echo( 'Mac')", context);
assertEquals("Mac", MVEL.executeExpression(stmt, new EchoContext()));
}
public void testForLoopTypeCoercion() {
ParserContext pCtx = ParserContext.create();
pCtx.setStrongTyping(true);
pCtx.addInput("$type", String.class);
pCtx.addInput("l", List.class);
Map<String, Object> vars = new HashMap<String, Object>();
vars.put("$type", "pc!!");
List list = new ArrayList();
vars.put("l", list);
ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression("for (byte bt:$type.getBytes()) {l.add( bt);}", pCtx);
MVEL.executeExpression(stmt, null, vars);
byte[] exp = "pc!!".getBytes();
// byte[] res = new byte[list.size()];
for (int i = 0; i < exp.length; i++) {
assertEquals(exp[i], list.get(i));
}
}
public void testGetCorrectInputs() {
String str = "total = total + $cheese.price";
ParserConfiguration pconf = new ParserConfiguration();
ParserContext pctx = new ParserContext(pconf);
pctx.setStrongTyping(true);
pctx.addInput("total", int.class);
pctx.addInput("$cheese", Cheese.class);
ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx);
assertTrue("Should not contain" + pctx.getVariables(), pctx.getVariables().isEmpty());
}
public void testTypeCalculation() {
ParserContext ctx = ParserContext.create().stronglyTyped();
ctx.addInput("foo", Foo.class);
Class cls = MVEL.analyze("foo.bar.testList.get(0)", ctx);
assertTrue(Integer.class.isAssignableFrom(cls));
}
public static class AGenericTestClass {
private Map<String, String> map;
/**
* @return the map
*/
public Map<String, String> getMap() {
return map;
}
/**
* @param map the map to set
*/
public void setMap(Map<String, String> map) {
this.map = map;
}
}
public void testGenericMethods() {
String str = "Integer.parseInt( a.getMap().get(\"x\") )";
ParserConfiguration pconf = new ParserConfiguration();
ParserContext pctx = new ParserContext(pconf);
pctx.setStrongTyping(true);
pctx.addInput("a", AGenericTestClass.class);
ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx);
AGenericTestClass a = new AGenericTestClass();
a.setMap(new HashMap<String, String>());
a.getMap().put("x", "10");
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("a", a);
Number result = (Number) MVEL.executeExpression(stmt, null, variables);
assertEquals(10, result.intValue());
}
public static class Address {
private String street;
public Address(String street) {
this.street = street;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((street == null) ? 0 : street.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Address other = (Address) obj;
if (street == null) {
if (other.street != null) return false;
} else if (!street.equals(other.street)) return false;
return true;
}
}
public static class PersonAddresses {
private List<Address> addresses = new ArrayList<Address>();
public List<Address> getAddresses() {
return addresses;
}
public void setAddresses(List<Address> addresses) {
this.addresses = addresses;
}
}
public void testGenerics1() {
String str = "addresses[0] == new Address(\"s1\") && addresses[0].street == new Address(\"s1\").street";
ParserConfiguration pconf = new ParserConfiguration();
ParserContext pctx = new ParserContext(pconf);
pctx.setStrongTyping(true);
pctx.addInput("this", PersonAddresses.class);
pctx.addImport(Address.class);
pctx.addImport(PersonAddresses.class);
ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx);
PersonAddresses ctx = new PersonAddresses();
ctx.getAddresses().add(new Address("s1"));
Boolean result = (Boolean) MVEL.executeExpression(stmt, ctx);
assertTrue(result);
}
}