public void testTypeVarDeclr() {
    String ex = "String a;";
    ParserContext ctx = new ParserContext();
    ExpressionCompiler compiler = new ExpressionCompiler(ex);
    compiler.compile(ctx);

    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 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 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 testMultiTypeVarDeclr3() {
    String ex = "int a = 52 * 3, b = 8, c = 16;";
    ParserContext ctx = new ParserContext();
    ExpressionCompiler compiler = new ExpressionCompiler(ex);
    Serializable s = compiler.compile(ctx);

    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 testVarDeclr() {
    String ex = "var a";

    ParserContext ctx = new ParserContext();
    ExpressionCompiler compiler = new ExpressionCompiler(ex);
    compiler.setVerifyOnly(true);
    compiler.compile(ctx);

    assertEquals(1, ctx.getVariables().size());
  }
  public void testAnalysisCompile() {
    ParserContext pCtx = new ParserContext();
    ExpressionCompiler e = new ExpressionCompiler("foo.aValue = 'bar'");
    e.setVerifyOnly(true);

    e.compile(pCtx);

    assertTrue(pCtx.getInputs().keySet().contains("foo"));
    assertEquals(1, pCtx.getInputs().size());
    assertEquals(0, pCtx.getVariables().size());
  }
  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 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"));
  }
Exemple #9
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;
  }