@Test
  public void testDebugSymbolCount() {
    String expr =
        "System.out.println( \"a1\" );\n"
            + "System.out.println( \"a2\" );\n"
            + "System.out.println( \"a3\" );\n"
            + "System.out.println( \"a4\" );\n";

    ExpressionCompiler compiler = new ExpressionCompiler(expr);

    ParserContext context = new ParserContext();
    context.setDebugSymbols(true);
    context.addImport("System", System.class);
    context.setStrictTypeEnforcement(true);
    // context.setDebugSymbols( true );
    context.setSourceFile("mysource");

    Serializable compiledExpression = compiler.compile(context);

    String s = DebugTools.decompile(compiledExpression);

    System.out.println("s " + s);

    int fromIndex = 0;
    int count = 0;
    while ((fromIndex = s.indexOf("DEBUG_SYMBOL", fromIndex + 1)) > -1) {
      count++;
    }
    assertEquals(4, count);
  }
  public void testProvidedExternalTypes() {
    ExpressionCompiler compiler = new ExpressionCompiler("foo.bar");
    ParserContext ctx = new ParserContext();
    ctx.setStrictTypeEnforcement(true);
    ctx.addInput("foo", Foo.class);

    compiler.compile(ctx);
  }
  public void testStrictStaticMethodCall() {
    ExpressionCompiler compiler = new ExpressionCompiler("Bar.staticMethod()");
    ParserContext ctx = new ParserContext();
    ctx.addImport("Bar", Bar.class);
    ctx.setStrictTypeEnforcement(true);

    Serializable s = compiler.compile(ctx);

    assertEquals(1, executeExpression(s));
  }
  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 testStrictTypingCompilation4() throws NoSuchMethodException {
    ParserContext ctx = new ParserContext();

    ctx.addImport(Foo.class);
    ctx.setStrictTypeEnforcement(true);

    ExpressionCompiler compiler = new ExpressionCompiler("x_a = new Foo()");

    compiler.compile(ctx);

    assertEquals(Foo.class, ctx.getVariables().get("x_a"));
  }
  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");

    assertEquals(
        7, executeExpression(compiler.compile(ctx), new DefaultLocalVariableResolverFactory()));
  }
  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 );");

    Serializable compiled = compiler.compile(ctx);

    Set<String> requiredInputs = compiler.getParserContextState().getInputs().keySet();
    assertEquals(1, requiredInputs.size());
    assertTrue(requiredInputs.contains("$bar"));
  }
  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 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 );");

      compiler.compile(ctx);
      fail("This should not compileShared");
    } catch (Exception e) {
    }
  }
  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()");
    StaticMethodImportResolverFactory si = new StaticMethodImportResolverFactory(ctx);

    Serializable expression = compiler.compile(ctx);

    serializationTest(expression);

    assertTrue(executeExpression(expression, si) instanceof Runtime);
  }
  public void testMapAsContextWithStrictTyping() {
    ExpressionCompiler compiler = new ExpressionCompiler("this['KEY1'] == $msg");
    ParserContext ctx = new ParserContext();
    ctx.setStrictTypeEnforcement(true);
    ctx.setStrongTyping(true);
    ctx.addInput("$msg", String.class);
    ctx.addInput("this", Map.class);
    Serializable expr = compiler.compile(ctx);

    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 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 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 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");
    Cheese actualCheese = (Cheese) executeExpression(compiler.compile(ctx), createTestMap());
    assertEquals(expectedCheese.getUseBy(), actualCheese.getUseBy());
  }
  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 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();
    }
  }
Beispiel #17
0
  /**
   * Analyze an expression.
   *
   * @param expr The expression to analyze.
   * @param availDecls Total set of declarations available.
   * @return The <code>Set</code> of declarations used by the expression.
   * @throws RecognitionException If an error occurs in the parser.
   */
  public MVELAnalysisResult analyzeExpression(
      final PackageBuildContext context,
      final String expr,
      final BoundIdentifiers availableIdentifiers,
      final Map<String, Class<?>> localTypes) {
    MVELAnalysisResult result = null;
    if (expr.trim().length() > 0) {
      MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = true;
      MVELDialect dialect = (MVELDialect) context.getDialect("mvel");

      // creating a reusable parser configuration
      ParserConfiguration conf = new ParserConfiguration();
      conf.setImports(dialect.getImports());
      conf.setPackageImports((HashSet) dialect.getPackgeImports());

      conf.setClassLoader(context.getPackageBuilder().getRootClassLoader());

      // first compilation is for verification only
      // @todo proper source file name
      final ParserContext parserContext1 = new ParserContext(conf);
      if (localTypes != null) {
        for (Entry entry : localTypes.entrySet()) {
          parserContext1.addInput((String) entry.getKey(), (Class) entry.getValue());
        }
      }
      if (availableIdentifiers.getThisClass() != null) {
        parserContext1.addInput("this", availableIdentifiers.getThisClass());
      }

      parserContext1.setStrictTypeEnforcement(false);
      parserContext1.setStrongTyping(false);
      parserContext1.setInterceptors(dialect.getInterceptors());
      Class returnType = null;

      try {
        returnType = MVEL.analyze(expr, parserContext1);
      } catch (Exception e) {
        context
            .getErrors()
            .add(
                new DescrBuildError(
                    context.getParentDescr(),
                    null,
                    null,
                    "Unable to Analyse Expression " + expr + ":\n" + e.getMessage()));
        return null;
      }

      Set<String> requiredInputs = new HashSet();
      requiredInputs.addAll(parserContext1.getInputs().keySet());
      HashMap<String, Class<?>> variables =
          (HashMap<String, Class<?>>) ((Map) parserContext1.getVariables());

      // MVEL includes direct fields of context object in non-strict mode. so we need to strip those
      if (availableIdentifiers.getThisClass() != null) {
        for (Iterator<String> it = requiredInputs.iterator(); it.hasNext(); ) {
          if (PropertyTools.getFieldOrAccessor(availableIdentifiers.getThisClass(), it.next())
              != null) {
            it.remove();
          }
        }
      }

      // now, set the required input types and compile again
      final ParserContext parserContext2 = new ParserContext(conf);
      parserContext2.setStrictTypeEnforcement(true);
      parserContext2.setStrongTyping(true);
      parserContext2.setInterceptors(dialect.getInterceptors());

      if (context.isTypesafe()) {
        if (localTypes != null) {
          for (Entry<String, Class<?>> entry : localTypes.entrySet()) {
            parserContext2.addInput(entry.getKey(), entry.getValue());
          }
        }

        for (String str : requiredInputs) {
          Class cls = availableIdentifiers.getDeclarations().get(str);
          if (cls != null) {
            parserContext2.addInput(str, cls);
            continue;
          }

          if (cls == null) {
            cls = availableIdentifiers.getGlobals().get(str);
            if (cls != null) {
              parserContext2.addInput(str, cls);
              continue;
            }
          }

          if (cls == null) {
            if (str.equals("drools")) {
              parserContext2.addInput("drools", KnowledgeHelper.class);
            } else if (str.equals("kcontext")) {
              parserContext2.addInput("kcontext", RuleContext.class);
            }
            if (str.equals("rule")) {
              parserContext2.addInput("rule", Rule.class);
            }
          }
        }

        if (availableIdentifiers.getThisClass() != null) {
          parserContext2.addInput("this", availableIdentifiers.getThisClass());
        }

        try {
          returnType = MVEL.analyze(expr, parserContext2);
        } catch (Exception e) {
          context
              .getErrors()
              .add(
                  new DescrBuildError(
                      context.getParentDescr(),
                      null,
                      null,
                      "Unable to Analyse Expression " + expr + ":\n" + e.getMessage()));
          return null;
        }

        requiredInputs = new HashSet();
        requiredInputs.addAll(parserContext2.getInputs().keySet());
        requiredInputs.addAll(variables.keySet());
        variables = (HashMap<String, Class<?>>) ((Map) parserContext2.getVariables());
      }

      result = analyze(requiredInputs, availableIdentifiers);

      result.setReturnType(returnType);

      result.setMvelVariables(variables);
    } else {
      result = analyze((Set<String>) Collections.EMPTY_SET, availableIdentifiers);
      result.setMvelVariables(new HashMap<String, Class<?>>());
    }
    return result;
  }