/** * 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()))); }
/** * 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); } }