/**
   * Builds and returns an Eval Conditional Element
   *
   * @param context The current build context
   * @param utils The current build utils instance
   * @param patternBuilder not used by EvalBuilder
   * @param descr The Eval Descriptor to build the eval conditional element from
   * @return the Eval Conditional Element
   */
  public RuleConditionElement build(
      final RuleBuildContext context, final BaseDescr descr, final Pattern prefixPattern) {
    // it must be an EvalDescr
    final EvalDescr evalDescr = (EvalDescr) descr;

    try {
      MVELDialect dialect = (MVELDialect) context.getDialect(context.getDialect().getId());

      Map<String, Declaration> decls =
          context.getDeclarationResolver().getDeclarations(context.getRule());

      AnalysisResult analysis =
          context
              .getDialect()
              .analyzeExpression(
                  context,
                  evalDescr,
                  evalDescr.getContent(),
                  new BoundIdentifiers(
                      context.getDeclarationResolver().getDeclarationClasses(decls),
                      context.getPackageBuilder().getGlobals()));

      Collection<Declaration> col = decls.values();
      Declaration[] previousDeclarations = (Declaration[]) col.toArray(new Declaration[col.size()]);

      MVELCompilationUnit unit =
          dialect.getMVELCompilationUnit(
              (String) evalDescr.getContent(), analysis, previousDeclarations, null, null, context);
      final EvalCondition eval = new EvalCondition(previousDeclarations);

      MVELEvalExpression expr = new MVELEvalExpression(unit, dialect.getId());
      eval.setEvalExpression(expr);

      MVELDialectRuntimeData data =
          (MVELDialectRuntimeData)
              context
                  .getPkg()
                  .getDialectRuntimeRegistry()
                  .getDialectData(context.getDialect().getId());
      data.addCompileable(eval, expr);

      expr.compile(context.getPackageBuilder().getRootClassLoader());
      return eval;
    } catch (final Exception e) {
      context
          .getErrors()
          .add(
              new DescrBuildError(
                  context.getParentDescr(),
                  evalDescr,
                  e,
                  "Unable to build expression for 'eval':"
                      + e.getMessage()
                      + " '"
                      + evalDescr.getContent()
                      + "'"));
      return null;
    }
  }
  /**
   * Builds and returns an Eval Conditional Element
   *
   * @param context The current build context
   * @param utils The current build utils instance
   * @param patternBuilder not used by EvalBuilder
   * @param descr The Eval Descriptor to build the eval conditional element from
   * @return the Eval Conditional Element
   */
  public RuleConditionElement build(
      final RuleBuildContext context, final BaseDescr descr, final Pattern prefixPattern) {
    // it must be an EvalDescr
    final EvalDescr evalDescr = (EvalDescr) descr;

    try {
      final DroolsMVELFactory factory =
          new DroolsMVELFactory(
              context.getDeclarationResolver().getDeclarations(),
              null,
              context.getPkg().getGlobals());

      Dialect.AnalysisResult analysis =
          context
              .getDialect()
              .analyzeExpression(
                  context,
                  evalDescr,
                  evalDescr.getContent(),
                  new Set[] {
                    context.getDeclarationResolver().getDeclarations().keySet(),
                    context.getPkg().getGlobals().keySet()
                  });
      final List[] usedIdentifiers = analysis.getBoundIdentifiers();

      final Declaration[] declarations = new Declaration[usedIdentifiers[0].size()];
      for (int i = 0, size = usedIdentifiers[0].size(); i < size; i++) {
        declarations[i] =
            context.getDeclarationResolver().getDeclaration((String) usedIdentifiers[0].get(i));
      }

      final EvalCondition eval = new EvalCondition(declarations);

      Serializable expr =
          ((MVELDialect) context.getDialect())
              .compile((String) evalDescr.getContent(), analysis, null, null, null, context);

      eval.setEvalExpression(new MVELEvalExpression(expr, factory, context.getDialect().getId()));

      return eval;
    } catch (final Exception e) {
      context
          .getErrors()
          .add(
              new DescrBuildError(
                  context.getParentDescr(),
                  evalDescr,
                  e,
                  "Unable to build expression for 'eval' node '" + evalDescr.getContent() + "'"));
      return null;
    }
  }
  public void testSimpleExpression() {
    final Package pkg = new Package("pkg1");
    final RuleDescr ruleDescr = new RuleDescr("rule 1");

    PackageBuilder pkgBuilder = new PackageBuilder(pkg);
    final PackageBuilderConfiguration conf = pkgBuilder.getPackageBuilderConfiguration();
    MVELDialect mvelDialect = (MVELDialect) pkgBuilder.getDialectRegistry().getDialect("mvel");

    final InstrumentedBuildContent context =
        new InstrumentedBuildContent(
            conf, pkg, ruleDescr, pkgBuilder.getDialectRegistry(), mvelDialect);

    final InstrumentedDeclarationScopeResolver declarationResolver =
        new InstrumentedDeclarationScopeResolver();

    final FieldExtractor extractor =
        cache.getExtractor(Cheese.class, "price", getClass().getClassLoader());

    final Pattern pattern = new Pattern(0, new ClassObjectType(int.class));
    final Declaration declaration = new Declaration("a", extractor, pattern);
    final Map map = new HashMap();
    map.put("a", declaration);
    declarationResolver.setDeclarations(map);
    context.setDeclarationResolver(declarationResolver);

    final EvalDescr evalDescr = new EvalDescr();
    evalDescr.setContent("a == 10");

    final MVELEvalBuilder builder = new MVELEvalBuilder();
    final EvalCondition eval = (EvalCondition) builder.build(context, evalDescr);

    final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
    final WorkingMemory wm = ruleBase.newStatefulSession();

    final Cheese cheddar = new Cheese("cheddar", 10);
    final InternalFactHandle f0 = (InternalFactHandle) wm.insert(cheddar);
    final ReteTuple tuple = new ReteTuple(f0);

    Object evalContext = eval.createContext();

    assertTrue(eval.isAllowed(tuple, wm, evalContext));

    cheddar.setPrice(9);
    wm.update(f0, cheddar);
    assertFalse(eval.isAllowed(tuple, wm, evalContext));
  }
 private boolean usesDeclaration(final EvalCondition condition) {
   boolean usesDecl = false;
   final Declaration[] declarations = condition.getRequiredDeclarations();
   for (int j = 0; !usesDecl && j < declarations.length; j++) {
     usesDecl = (declarations[j].getPattern().getObjectType() == this.objectType);
   }
   return usesDecl;
 }
  @Test
  public void test1() {
    KnowledgePackage pkg1 = getKnowledgePackage1();
    KnowledgePackage pkg2 = getKnowledgePackage1();
    KnowledgePackage pkg3 = getKnowledgePackage2();

    Rule rule1 = ((KnowledgePackageImp) pkg1).pkg.getRule("rule1");
    Rule rule2 = ((KnowledgePackageImp) pkg2).pkg.getRule("rule1");
    Rule rule3 = ((KnowledgePackageImp) pkg3).pkg.getRule("rule1");

    // test return value
    Pattern p1 = (Pattern) rule1.getLhs().getChildren().get(0);
    VariableConstraint rvc1 = (VariableConstraint) p1.getConstraints().get(0);
    ReturnValueExpression rve1 = ((ReturnValueRestriction) rvc1.getRestriction()).getExpression();

    Pattern p2 = (Pattern) rule2.getLhs().getChildren().get(0);
    VariableConstraint rvc2 = (VariableConstraint) p2.getConstraints().get(0);
    ReturnValueExpression rve2 = ((ReturnValueRestriction) rvc2.getRestriction()).getExpression();

    assertNotSame(rve1, rve2);
    assertEquals(rve1, rve2);

    Pattern p3 = (Pattern) rule3.getLhs().getChildren().get(0);
    VariableConstraint rvc3 = (VariableConstraint) p3.getConstraints().get(0);
    ReturnValueExpression rve3 = ((ReturnValueRestriction) rvc3.getRestriction()).getExpression();

    assertNotSame(rve1, rve3);
    assertThat(rve1, not(equalTo(rve3)));

    // test inline eval
    PredicateConstraint pc1 = (PredicateConstraint) p1.getConstraints().get(1);
    PredicateExpression pe1 = (PredicateExpression) pc1.getPredicateExpression();

    PredicateConstraint pc2 = (PredicateConstraint) p2.getConstraints().get(1);
    PredicateExpression pe2 = (PredicateExpression) pc2.getPredicateExpression();
    assertNotSame(pe1, pe2);
    assertEquals(pe1, pe2);

    PredicateConstraint pc3 = (PredicateConstraint) p3.getConstraints().get(1);
    PredicateExpression pe3 = (PredicateExpression) pc3.getPredicateExpression();
    assertNotSame(pe1, pe3);
    assertThat(pe1, not(equalTo(pe3)));

    // test eval
    EvalCondition ec1 = (EvalCondition) rule1.getLhs().getChildren().get(1);
    EvalExpression ee1 = (EvalExpression) ec1.getEvalExpression();

    EvalCondition ec2 = (EvalCondition) rule2.getLhs().getChildren().get(1);
    EvalExpression ee2 = (EvalExpression) ec2.getEvalExpression();
    assertNotSame(ee1, ee2);
    assertEquals(ee1, ee2);

    EvalCondition ec3 = (EvalCondition) rule3.getLhs().getChildren().get(1);
    EvalExpression ee3 = (EvalExpression) ec3.getEvalExpression();
    assertNotSame(ee1, ee3);
    assertThat(ee1, not(equalTo(ee3)));

    // test consequence
    assertNotSame(rule1.getConsequence(), rule2.getConsequence());
    assertEquals(rule1.getConsequence(), rule2.getConsequence());
    assertNotSame(rule1.getConsequence(), rule3.getConsequence());
    assertThat(rule1.getConsequence(), not(equalTo(rule3.getConsequence())));

    // check LHS equals
    assertNotSame(rule1.getLhs(), rule2.getLhs());
    assertEquals(rule1.getLhs(), rule2.getLhs());

    assertNotSame(rule1.getLhs(), rule3.getLhs());
    assertThat(rule1.getLhs(), not(equalTo(rule3.getLhs())));
  }
Beispiel #6
0
  /**
   * Builds and returns an Eval Conditional Element
   *
   * @param context The current build context
   * @param utils The current build utils instance
   * @param patternBuilder not used by EvalBuilder
   * @param descr The Eval Descriptor to build the eval conditional element from
   * @return the Eval Conditional Element
   */
  public RuleConditionElement build(
      final RuleBuildContext context, final BaseDescr descr, final Pattern prefixPattern) {
    boolean typesafe = context.isTypesafe();
    // it must be an EvalDescr
    final EvalDescr evalDescr = (EvalDescr) descr;

    try {
      MVELDialect dialect = (MVELDialect) context.getDialect(context.getDialect().getId());

      Map<String, Declaration> decls =
          context.getDeclarationResolver().getDeclarations(context.getRule());

      AnalysisResult analysis =
          context
              .getDialect()
              .analyzeExpression(
                  context,
                  evalDescr,
                  evalDescr.getContent(),
                  new BoundIdentifiers(
                      context.getDeclarationResolver().getDeclarationClasses(decls),
                      context.getPackageBuilder().getGlobals()));

      final BoundIdentifiers usedIdentifiers = analysis.getBoundIdentifiers();
      int i = usedIdentifiers.getDeclrClasses().keySet().size();
      Declaration[] previousDeclarations = new Declaration[i];
      i = 0;
      for (String id : usedIdentifiers.getDeclrClasses().keySet()) {
        previousDeclarations[i++] = decls.get(id);
      }
      Arrays.sort(previousDeclarations, SortDeclarations.instance);

      MVELCompilationUnit unit =
          dialect.getMVELCompilationUnit(
              (String) evalDescr.getContent(),
              analysis,
              previousDeclarations,
              null,
              null,
              context,
              "drools",
              KnowledgeHelper.class,
              false);
      final EvalCondition eval = new EvalCondition(previousDeclarations);

      MVELEvalExpression expr = new MVELEvalExpression(unit, dialect.getId());
      eval.setEvalExpression(expr);

      MVELDialectRuntimeData data =
          (MVELDialectRuntimeData)
              context.getPkg().getDialectRuntimeRegistry().getDialectData("mvel");
      data.addCompileable(eval, expr);

      expr.compile(data);
      return eval;
    } catch (final Exception e) {
      copyErrorLocation(e, evalDescr);
      context.addError(
          new DescrBuildError(
              context.getParentDescr(),
              evalDescr,
              e,
              "Unable to build expression for 'eval':"
                  + e.getMessage()
                  + " '"
                  + evalDescr.getContent()
                  + "'"));
      return null;
    } finally {
      context.setTypesafe(typesafe);
    }
  }