use of org.drools.drl.ast.descr.RuleDescr in project drools by kiegroup.
the class MVELConsequenceBuilder method build.
public void build(final RuleBuildContext context, String consequenceName) {
// pushing consequence LHS into the stack for variable resolution
context.getDeclarationResolver().pushOnBuildStack(context.getRule().getLhs());
try {
MVELDialect dialect = (MVELDialect) context.getDialect("mvel");
final RuleDescr ruleDescr = context.getRuleDescr();
String text = (RuleImpl.DEFAULT_CONSEQUENCE_NAME.equals(consequenceName)) ? (String) ruleDescr.getConsequence() : (String) ruleDescr.getNamedConsequences().get(consequenceName);
text = processMacros(text);
text = rewriteModify(text);
Map<String, Declaration> decls = context.getDeclarationResolver().getDeclarations(context.getRule());
AnalysisResult analysis = dialect.analyzeBlock(context, text, new BoundIdentifiers(DeclarationScopeResolver.getDeclarationClasses(decls), context, Collections.EMPTY_MAP, KnowledgeHelper.class), null, "drools", KnowledgeHelper.class);
if (analysis == null) {
// something bad happened, issue already logged in errors
return;
}
text = rewriteUpdates(context, analysis, text);
final BoundIdentifiers usedIdentifiers = analysis.getBoundIdentifiers();
final Declaration[] declarations = new Declaration[usedIdentifiers.getDeclrClasses().size()];
String[] declrStr = new String[declarations.length];
int j = 0;
for (String str : usedIdentifiers.getDeclrClasses().keySet()) {
declrStr[j] = str;
declarations[j++] = decls.get(str);
}
Arrays.sort(declarations, SortDeclarations.instance);
for (int i = 0; i < declrStr.length; i++) {
declrStr[i] = declarations[i].getIdentifier();
}
context.getRule().setRequiredDeclarationsForConsequence(consequenceName, declrStr);
MVELCompilationUnit unit = dialect.getMVELCompilationUnit(text, analysis, declarations, null, null, context, "drools", KnowledgeHelper.class, false, MVELCompilationUnit.Scope.CONSEQUENCE);
MVELConsequence expr = new MVELConsequence(unit, dialect.getId(), consequenceName);
if (RuleImpl.DEFAULT_CONSEQUENCE_NAME.equals(consequenceName)) {
context.getRule().setConsequence(expr);
} else {
context.getRule().addNamedConsequence(consequenceName, expr);
}
MVELDialectRuntimeData data = (MVELDialectRuntimeData) context.getPkg().getDialectRuntimeRegistry().getDialectData("mvel");
data.addCompileable(context.getRule(), expr);
expr.compile(data, context.getRule());
} catch (final Exception e) {
copyErrorLocation(e, context.getRuleDescr());
context.addError(new DescrBuildError(context.getParentDescr(), context.getRuleDescr(), null, "Unable to build expression for 'consequence': " + e.getMessage() + " '" + context.getRuleDescr().getConsequence() + "'"));
}
}
use of org.drools.drl.ast.descr.RuleDescr in project drools by kiegroup.
the class ChangeSetBuilder method diffDescrs.
private static <T extends BaseDescr> void diffDescrs(byte[] ob, byte[] cb, ResourceChangeSet pkgcs, List<T> odescrs, List<T> cdescrs, ResourceChange.Type type, DescrNameConverter<T> descrNameConverter) {
Set<String> updatedRules = null;
if (type == ResourceChange.Type.RULE) {
updatedRules = new HashSet<>();
((List<RuleDescr>) cdescrs).sort(RULE_HIERARCHY_COMPARATOR);
}
for (T crd : cdescrs) {
String cName = descrNameConverter.getName(crd);
// unfortunately have to iterate search for a rule with the same name
boolean found = false;
for (Iterator<T> it = odescrs.iterator(); it.hasNext(); ) {
T ord = it.next();
if (descrNameConverter.getName(ord).equals(cName)) {
found = true;
it.remove();
// is brittle and heavier than iterating an array
if (!StringUtils.codeAwareEqualsIgnoreSpaces(new String(Arrays.copyOfRange(ob, ord.getStartCharacter(), ord.getEndCharacter())), new String(Arrays.copyOfRange(cb, crd.getStartCharacter(), crd.getEndCharacter()))) || (type == ResourceChange.Type.RULE && updatedRules.contains(((RuleDescr) crd).getParentName()))) {
pkgcs.getChanges().add(new ResourceChange(ChangeType.UPDATED, type, cName));
if (type == ResourceChange.Type.RULE) {
updatedRules.add(cName);
}
}
break;
}
}
if (!found) {
pkgcs.getChanges().add(new ResourceChange(ChangeType.ADDED, type, cName));
}
}
for (T ord : odescrs) {
pkgcs.getChanges().add(new ResourceChange(ChangeType.REMOVED, type, descrNameConverter.getName(ord)));
}
}
use of org.drools.drl.ast.descr.RuleDescr in project drools by kiegroup.
the class MVELAccumulateBuilderTest method testSimpleExpression.
@Test
public void testSimpleExpression() {
KnowledgeBuilderImpl pkgBuilder = new KnowledgeBuilderImpl();
pkgBuilder.addPackage(new PackageDescr("pkg1"));
InternalKnowledgePackage pkg = pkgBuilder.getPackage("pkg1");
final RuleDescr ruleDescr = new RuleDescr("rule 1");
final KnowledgeBuilderConfigurationImpl conf = pkgBuilder.getBuilderConfiguration();
DialectCompiletimeRegistry dialectRegistry = pkgBuilder.getPackageRegistry(pkg.getName()).getDialectCompiletimeRegistry();
MVELDialect mvelDialect = (MVELDialect) dialectRegistry.getDialect("mvel");
final RuleBuildContext context = new RuleBuildContext(pkgBuilder, ruleDescr, dialectRegistry, pkg, mvelDialect);
final AccumulateDescr accDescr = new AccumulateDescr();
final PatternDescr inputPattern = new PatternDescr("org.drools.mvel.compiler.Cheese", "$cheese");
accDescr.setInputPattern(inputPattern);
accDescr.setInitCode("total = 0;");
accDescr.setActionCode("total += $cheese.price;");
accDescr.setReverseCode("total -= $cheese.price;");
accDescr.setResultCode("new Integer(total)");
final MVELAccumulateBuilder builder = new MVELAccumulateBuilder();
final Accumulate acc = (Accumulate) builder.build(context, accDescr);
((MVELCompileable) acc.getAccumulators()[0]).compile((MVELDialectRuntimeData) pkgBuilder.getPackageRegistry(pkg.getName()).getDialectRuntimeRegistry().getDialectData("mvel"));
InternalKnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase();
StatefulKnowledgeSessionImpl ksession = (StatefulKnowledgeSessionImpl) kBase.newKieSession();
BuildContext buildContext = new BuildContext(kBase, Collections.emptyList());
MockLeftTupleSink sink = new MockLeftTupleSink(buildContext);
MockTupleSource source = new MockTupleSource(1, buildContext);
source.setObjectCount(1);
sink.setLeftTupleSource(source);
final Cheese cheddar1 = new Cheese("cheddar", 10);
final Cheese cheddar2 = new Cheese("cheddar", 8);
final InternalFactHandle f0 = (InternalFactHandle) ksession.insert(new InitialFactImpl());
final InternalFactHandle f1 = (InternalFactHandle) ksession.insert(cheddar1);
final InternalFactHandle f2 = (InternalFactHandle) ksession.insert(cheddar2);
final LeftTupleImpl tuple = new LeftTupleImpl(f0, sink, true);
Object wmContext = acc.createWorkingMemoryContext();
AccumulateNode.AccumulateContext accContext = new AccumulateNode.AccumulateContext();
Object funcContext = acc.createFunctionContext();
funcContext = acc.init(wmContext, accContext, funcContext, tuple, ksession);
accContext.setFunctionContext(funcContext);
Object value1 = acc.accumulate(wmContext, accContext, tuple, f1, ksession);
acc.accumulate(wmContext, accContext, tuple, f2, ksession);
assertEquals(new Integer(18), acc.getResult(wmContext, accContext, tuple, ksession));
LeftTuple match = new FromNodeLeftTuple();
match.setContextObject(value1);
acc.tryReverse(wmContext, accContext, tuple, f1, null, match, ksession);
assertEquals(new Integer(8), acc.getResult(wmContext, accContext, tuple, ksession));
}
use of org.drools.drl.ast.descr.RuleDescr in project drools by kiegroup.
the class MVELConsequenceBuilderTest method testImperativeCodeError.
@Test
public void testImperativeCodeError() throws Exception {
InternalKnowledgePackage pkg = CoreComponentFactory.get().createKnowledgePackage("pkg1");
final RuleDescr ruleDescr = new RuleDescr("rule 1");
ruleDescr.setConsequence("if (cheese.price == 10) { cheese.price = 5; }");
Properties properties = new Properties();
properties.setProperty("drools.dialect.default", "mvel");
KnowledgeBuilderConfigurationImpl cfg1 = new KnowledgeBuilderConfigurationImpl(properties);
KnowledgeBuilderImpl pkgBuilder = new KnowledgeBuilderImpl(pkg, cfg1);
PackageRegistry pkgRegistry = pkgBuilder.getPackageRegistry(pkg.getName());
DialectCompiletimeRegistry dialectRegistry = pkgBuilder.getPackageRegistry(pkg.getName()).getDialectCompiletimeRegistry();
MVELDialect mvelDialect = (MVELDialect) dialectRegistry.getDialect(pkgRegistry.getDialect());
final RuleBuildContext context = new RuleBuildContext(pkgBuilder, ruleDescr, dialectRegistry, pkg, mvelDialect);
final InstrumentedDeclarationScopeResolver declarationResolver = new InstrumentedDeclarationScopeResolver();
final ObjectType cheeseObjeectType = new ClassObjectType(Cheese.class);
final Pattern pattern = new Pattern(0, cheeseObjeectType);
final PatternExtractor extractor = new PatternExtractor(cheeseObjeectType);
final Declaration declaration = new Declaration("cheese", extractor, pattern);
final Map<String, Declaration> map = new HashMap<String, Declaration>();
map.put("cheese", declaration);
declarationResolver.setDeclarations(map);
context.setDeclarationResolver(declarationResolver);
final MVELConsequenceBuilder builder = new MVELConsequenceBuilder();
builder.build(context, RuleImpl.DEFAULT_CONSEQUENCE_NAME);
InternalKnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase();
StatefulKnowledgeSessionImpl ksession = (StatefulKnowledgeSessionImpl) kBase.newKieSession();
final Cheese cheddar = new Cheese("cheddar", 10);
final InternalFactHandle f0 = (InternalFactHandle) ksession.insert(cheddar);
final LeftTupleImpl tuple = new LeftTupleImpl(f0, null, true);
final AgendaItem item = new AgendaItemImpl(0, tuple, 10, null, null, null);
final DefaultKnowledgeHelper kbHelper = new DefaultKnowledgeHelper(ksession);
kbHelper.setActivation(item);
try {
((MVELConsequence) context.getRule().getConsequence()).compile((MVELDialectRuntimeData) pkgBuilder.getPackageRegistry(pkg.getName()).getDialectRuntimeRegistry().getDialectData("mvel"));
context.getRule().getConsequence().evaluate(kbHelper, ksession);
fail("should throw an exception, as 'if' is not allowed");
} catch (Exception e) {
}
assertEquals(10, cheddar.getPrice());
}
use of org.drools.drl.ast.descr.RuleDescr in project drools by kiegroup.
the class MVELConsequenceBuilderTest method setupTest.
private void setupTest(String consequence, Map<String, Object> namedConsequences) {
builder = new MVELConsequenceBuilder();
InternalKnowledgePackage pkg = CoreComponentFactory.get().createKnowledgePackage("org.drools.mvel.compiler.test");
pkg.addImport(new ImportDeclaration(Cheese.class.getCanonicalName()));
KnowledgeBuilderConfigurationImpl conf = new KnowledgeBuilderConfigurationImpl();
KnowledgeBuilderImpl pkgBuilder = new KnowledgeBuilderImpl(pkg, conf);
ruleDescr = new RuleDescr("test consequence builder");
ruleDescr.setConsequence(consequence);
ruleDescr.addAttribute(new AttributeDescr("dialect", "mvel"));
for (Entry<String, Object> entry : namedConsequences.entrySet()) {
ruleDescr.addNamedConsequences(entry.getKey(), entry.getValue());
}
RuleImpl rule = new RuleImpl(ruleDescr.getName());
rule.addPattern(new Pattern(0, new ClassObjectType(Cheese.class), "$cheese"));
rule.addPattern(new Pattern(0, new ClassObjectType(Map.class), "$map"));
PackageRegistry pkgRegistry = pkgBuilder.getPackageRegistry(pkg.getName());
DialectCompiletimeRegistry reg = pkgBuilder.getPackageRegistry(pkg.getName()).getDialectCompiletimeRegistry();
context = new RuleBuildContext(pkgBuilder, ruleDescr, reg, pkg, reg.getDialect(pkgRegistry.getDialect()));
context.getDeclarationResolver().pushOnBuildStack(rule.getLhs());
context.getDialect().getConsequenceBuilder().build(context, RuleImpl.DEFAULT_CONSEQUENCE_NAME);
for (String name : namedConsequences.keySet()) {
context.getDialect().getConsequenceBuilder().build(context, name);
}
context.getDialect().addRule(context);
pkgRegistry.getPackage().addRule(context.getRule());
pkgBuilder.compileAll();
pkgBuilder.reloadAll();
if (pkgBuilder.hasErrors()) {
fail(pkgBuilder.getErrors().toString());
}
}
Aggregations