public void prepare(Map<String, Object> model) { if (eh == null) eh = EvalTools.prepare(exp, model, functions); }
public Expression prepare(Map<String, Object> model, Map<String, UserFunction> functions, List<String> imports) { switch (type) { case IF: { List<String> args = getBlocks(statement, true); if (args.size() > 1) throw new IllegalStateException("more then one statement in condition: " + statement); AsBooleanExpression condition = new AsBooleanExpression(EvalTools.prepare(args.get(0), model, functions, imports)); Expression then = bodyStatement != null ? bodyStatement.prepare(model, functions, imports) : EvalTools.prepare(body, model, functions, imports); Expression elseExpression = optionalStatement != null ? optionalStatement.prepare(model, functions, imports) : EvalTools.prepare(optional, model, functions, imports); if (elseExpression == null) return new IfExpression(condition, then); else return new IfExpression(condition, then, elseExpression); } default: throw new IllegalStateException("not implemented yet"); } }
return trimBrackets(s.substring(0, db + 1) + t.substring(0, m.start() - 1) + t.substring(m.start()));
close = findCloseBracket(s, start, to); return close + 1; } else { return getBlock(s, start, to, statement);
String before = s.substring(start, m.start()).trim(); if (before.length() > 0) { return getStringBlock(s, from, to, statement); int close = findCloseBracket(s, m.end()); if (close < 0) throw new IllegalStateException("can't find closing bracket in expression: " + s); close = findCloseBracket(s, start, to); return getElse(s, start, to, inner); return start; } else { start = getBlock(s, start, to, inner); return getElse(s, start, to, inner); return start; return getStringBlock(s, from, to, statement);
do { comment = exp.indexOf("/*", comment + 1); if (comment != -1 && !inString(exp, 0, comment)) { int commentEnd = exp.indexOf("*/", comment); if (commentEnd == -1) String trimmed = trimBrackets(exp); while (trimmed != exp) { exp = trimmed; trimmed = trimBrackets(exp); if (!isTemplate && exp.startsWith("\"") && exp.endsWith("\"") && inString(exp, 0, exp.length() - 1)) { return prepare(exp.substring(1, exp.length() - 1), model, functions, imports, true); end = findCloseBracket(exp, start + 2); String sub = exp.substring(start + 2, end); tb.append(prepare(sub, model, functions, imports, false)); end++; } else { tb.append(exp.substring(end, m.start())); String sub = m.group(1); tb.append(prepare(sub, model, functions, imports, false)); end = m.end(); if (isClosure(exp)) { exp = exp.substring(1, exp.length() - 1).trim(); ClosureExpression closure = new ClosureExpression(); List<String> lines = getBlocks(exp);
@Test public void testCast() { final Map<String, Object> model = new HashMap<String, Object>(); Map<String, UserFunction> functions = new HashMap<String, UserFunction>(); List<String> imports = new ArrayList<String>(); Expression exp; assertEquals(Integer.class, EvalTools.evaluate("(Integer) 1", model).getClass()); checkException(new Runnable() { @Override public void run() { EvalTools.evaluate("(String) 1", model); } }, ClassCastException.class, "java.lang.Integer cannot be cast to java.lang.String"); model.put("foo", new EvalToolsTest.Foo()); exp = EvalTools.prepare("(com.wizzardo.tools.evaluation.EvalToolsTest.Foo) foo", model, functions, imports, false); Assert.assertEquals(Foo.class, exp.get(model).getClass()); imports.add("com.wizzardo.tools.evaluation.EvalToolsTest"); model.put("foo", new EvalToolsTest.Foo()); exp = EvalTools.prepare("(EvalToolsTest.Foo) foo", model, functions, imports, false); Assert.assertEquals(Foo.class, exp.get(model).getClass()); assertEquals(HashMap.class, EvalTools.evaluate("(Map<Integer, String>) [:]", model).getClass()); assertEquals(ArrayList.class, EvalTools.evaluate("(List<Integer>) []", model).getClass()); }
l = EvalTools.getStatements("if(true) { System.out.println(\"true\"); }"); assertEquals(1, l.size()); s = l.get(0); l = EvalTools.getStatements("if(true) System.out.println(\"true\");"); assertEquals(1, l.size()); s = l.get(0); l = EvalTools.getStatements("if(true)" + "System.out.println(\"true\");" + "System.out.println(\"other\");"); l = EvalTools.getStatements("if(true) if(!false)" + "System.out.println(\"true\");" + "System.out.println(\"other\");"); assertEquals(2, EvalTools.evaluate(exp, model)); model.put("i", 2); assertEquals(4, EvalTools.evaluate(exp, model)); model.put("i", -1); assertEquals(-1, EvalTools.evaluate(exp, model)); assertEquals(5, EvalTools.evaluate(exp, model)); model.put("i", 2); assertEquals(7, EvalTools.evaluate(exp, model)); model.put("i", -1); assertEquals(-1, EvalTools.evaluate(exp, model)); assertEquals(4, EvalTools.evaluate(exp, model));
static List<String> getBlocks(String exp) { return getBlocks(exp, false); }
@Test public void testGetParts() throws Exception { List<String> l = EvalTools.getParts("sin(1)+2"); Assert.assertEquals(3, l.size()); Assert.assertEquals("sin", l.get(0)); l = EvalTools.getParts("sin(1)"); Assert.assertEquals(2, l.size()); Assert.assertEquals("sin", l.get(0)); Assert.assertEquals("(1)", l.get(1)); l = EvalTools.getParts("'(olo)'+1"); Assert.assertEquals(1, l.size()); Assert.assertEquals("'(olo)'+1", l.get(0)); l = EvalTools.getParts("(1+2)*3"); Assert.assertEquals(2, l.size()); Assert.assertEquals("(1+2)", l.get(0)); Assert.assertEquals("*3", l.get(1)); l = EvalTools.getParts("'qwe'.concat('rty')"); Assert.assertEquals(3, l.size()); Assert.assertEquals("'qwe'", l.get(0)); l = EvalTools.getParts("('qwe').concat('rty')"); Assert.assertEquals(3, l.size()); Assert.assertEquals("('qwe')", l.get(0)); l = EvalTools.getParts("k[0]"); Assert.assertEquals(2, l.size());
protected static int findCloseBracket(String s, int from) { return findCloseBracket(s, from, s.length()); }
private static Class findClass(String s) { return findClass(s, null); }
static List<Statement> getStatements(String s) { List<Statement> statements = new ArrayList<Statement>(); Matcher m = IF_FOR_WHILE.matcher(s); int start = 0; int to = s.length(); while (m.find(start)) { if (m.start() != start) { statements.add(new Statement(s.substring(start, m.start()))); } Statement statement = new Statement(); start = getBlock(s, m.start(), to, statement); statements.add(statement.bodyStatement); } if (start != to) { String sub = s.substring(start, to).trim(); if (sub.length() > 0) statements.add(new Statement(sub)); } return statements; }
int last = 0; while (m.find()) { if (countOpenBrackets(argsRaw, last, m.start()) == 0) { l.add(argsRaw.substring(last, m.start()).trim()); last = m.end();
do { comment = exp.indexOf("/*", comment + 1); if (comment != -1 && !inString(exp, 0, comment)) { int commentEnd = exp.indexOf("*/", comment); if (commentEnd == -1) String trimmed = trimBrackets(exp); while (trimmed != exp) { exp = trimmed; trimmed = trimBrackets(exp); if (!isTemplate && exp.startsWith("\"") && exp.endsWith("\"") && inString(exp, 0, exp.length() - 1)) { return prepare(exp.substring(1, exp.length() - 1), model, functions, imports, true); end = findCloseBracket(exp, start + 2); String sub = exp.substring(start + 2, end); tb.append(prepare(sub, model, functions, imports, false)); end++; } else { tb.append(exp.substring(end, m.start())); String sub = m.group(1); tb.append(prepare(sub, model, functions, imports, false)); end = m.end(); if (isClosure(exp)) { exp = exp.substring(1, exp.length() - 1).trim(); ClosureExpression closure = new ClosureExpression(); List<String> lines = getBlocks(exp);
String before = s.substring(start, m.start()).trim(); if (before.length() > 0) { return getStringBlock(s, from, to, statement); int close = findCloseBracket(s, m.end()); if (close < 0) throw new IllegalStateException("can't find closing bracket in expression: " + s); close = findCloseBracket(s, start, to); return getElse(s, start, to, inner); return start; } else { start = getBlock(s, start, to, inner); return getElse(s, start, to, inner); return start; return getStringBlock(s, from, to, statement);
Map<String, Object> model = new HashMap<String, Object>(); Assert.assertTrue(EvalTools.prepare("{ -> 1}").get() instanceof ClosureExpression); Assert.assertEquals(1, ((ClosureExpression) EvalTools.prepare("{ -> 1}").get()).get()); Assert.assertEquals(1, EvalTools.prepare("{1}()").get()); Assert.assertTrue(EvalTools.prepare("{ it.toUpperCase() }").get() instanceof ClosureExpression); assertEquals("UPPER", ((ClosureExpression) EvalTools.prepare("{ it.toUpperCase() }").get()).get(model)); assertEquals("UP", ((ClosureExpression) EvalTools.prepare("{ " + "it=it.substring(0,2)\n" + "it.toUpperCase()\n" + EvalTools.evaluate("def l = ['a','b','c']", model); assertEquals("[A, B, C]", EvalTools.evaluate("l.collect({it.toUpperCase()})", model).toString()); assertEquals("UPPER", ((ClosureExpression) EvalTools.prepare("{s -> s.toUpperCase() }").get()).get(model)); assertEquals("UPPER", ((ClosureExpression) EvalTools.prepare("{String s -> s.toUpperCase() }").get()).get(model)); assertEquals("UPPER", ((ClosureExpression) EvalTools.prepare("{def s -> s.toUpperCase() }").get()).get(model)); Assert.assertTrue(EvalTools.prepare("def toUpperCase = {it.toUpperCase()}\ntoUpperCase").get(model) instanceof ClosureExpression); assertEquals("UPPER", EvalTools.prepare("def toUpperCase = {it.toUpperCase()}\ntoUpperCase(s)").get(model)); ClosureExpression closure = (ClosureExpression) EvalTools.prepare("{s.toUpperCase()}").get(model); assertEquals("UPPER", closure.get()); model.put("s", "lower");
close = findCloseBracket(s, start, to); return close + 1; } else { return getBlock(s, start, to, statement);
static List<String> getBlocks(String exp) { return getBlocks(exp, false); }