Skip to content

Commit

Permalink
[DROOLS-3508] Search for Mvel dialect in Package attributes (apache#2215
Browse files Browse the repository at this point in the history
)

* [DROOLS-3508] Also search for Mvel dialect in pkg attributes

* Move setDialect in RuleContext

* Removed comment
  • Loading branch information
lucamolteni authored and mariofusco committed Jan 15, 2019
1 parent 5a67f5e commit e8f8ed1
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 30 deletions.
Expand Up @@ -63,14 +63,12 @@
import org.drools.modelcompiler.builder.PackageModel;
import org.drools.modelcompiler.builder.errors.ParseExpressionErrorResult;
import org.drools.modelcompiler.builder.errors.UnknownDeclarationError;
import org.drools.modelcompiler.builder.generator.RuleContext.RuleDialect;
import org.drools.modelcompiler.builder.generator.expressiontyper.ExpressionTyper;
import org.drools.modelcompiler.builder.generator.expressiontyper.ExpressionTyperContext;
import org.drools.modelcompiler.builder.generator.visitor.ModelGeneratorVisitor;
import org.kie.soup.project.datamodel.commons.types.TypeResolver;

import static java.util.stream.Collectors.toList;

import static org.drools.javaparser.JavaParser.parseExpression;
import static org.drools.modelcompiler.builder.PackageModel.DATE_TIME_FORMATTER_FIELD;
import static org.drools.modelcompiler.builder.generator.DrlxParseUtil.classToReferenceType;
Expand Down Expand Up @@ -138,35 +136,40 @@ public static void generateModel(KnowledgeBuilderImpl kbuilder, InternalKnowledg
new WindowReferenceGenerator(packageModel, typeResolver).addWindowReferences(kbuilder, packageDescr.getWindowDeclarations());
packageModel.addAllFunctions(packageDescr.getFunctions().stream().map(FunctionGenerator::toFunction).collect(toList()));


for(RuleDescr descr : packageDescr.getRules()) {
RuleContext context = new RuleContext(kbuilder, packageModel, typeResolver, isPattern);
context.setDialectFromAttributes(packageDescr.getAttributes());
if (descr instanceof QueryDescr) {
QueryGenerator.processQueryDef( kbuilder, typeResolver, packageModel, (QueryDescr) descr, isPattern);
QueryGenerator.processQueryDef(packageModel, (QueryDescr) descr, context);
}
}

for (RuleDescr descr : packageDescr.getRules()) {
RuleContext context = new RuleContext(kbuilder, packageModel, typeResolver, isPattern);
context.setDialectFromAttributes(packageDescr.getAttributes());
if (descr instanceof QueryDescr) {
QueryGenerator.processQuery(kbuilder, packageModel, (QueryDescr) descr);
} else {
processRule(kbuilder, typeResolver, packageModel, packageDescr, descr, isPattern);
processRule(kbuilder, packageModel, packageDescr, descr, context);
}
}
}


private static void processRule(KnowledgeBuilderImpl kbuilder, TypeResolver typeResolver, PackageModel packageModel, PackageDescr packageDescr, RuleDescr ruleDescr, boolean isPattern) {
RuleContext context = new RuleContext(kbuilder, packageModel, ruleDescr, typeResolver, isPattern);
private static void processRule(KnowledgeBuilderImpl kbuilder, PackageModel packageModel, PackageDescr packageDescr, RuleDescr ruleDescr, RuleContext context) {
context.setDescr(ruleDescr);
context.addGlobalDeclarations(packageModel.getGlobals());

for(Entry<String, Object> kv : ruleDescr.getNamedConsequences().entrySet()) {
context.addNamedConsequence(kv.getKey(), kv.getValue().toString());
}

setDialectFromRuleDescr(context, ruleDescr);
context.setDialectFromAttributes(ruleDescr.getAttributes().values());

RuleUnitDescription ruleUnitDescr = context.getRuleUnitDescr();
BlockStmt ruleVariablesBlock = new BlockStmt();
createUnitData( context, ruleUnitDescr, ruleVariablesBlock );
createUnitData(context, ruleUnitDescr, ruleVariablesBlock );

new ModelGeneratorVisitor(context, packageModel).visit(getExtendedLhs(packageDescr, ruleDescr));
final String ruleMethodName = "rule_" + toId(ruleDescr.getName());
Expand Down Expand Up @@ -303,17 +306,6 @@ private static void addDynamicAttributeArgument( RuleContext context, MethodCall
}
}

public static void setDialectFromRuleDescr(RuleContext context, RuleDescr ruleDescr) {
for (Entry<String, AttributeDescr> as : ruleDescr.getAttributes().entrySet()) {
if (as.getKey().equals("dialect")) {
if (as.getValue().getValue().equals("mvel")) {
context.setRuleDialect(RuleDialect.MVEL);
}
return;
}
}
}

/**
* Build a list of method calls, representing each needed {@link org.drools.model.impl.RuleBuilder#metadata(String, Object)}
* starting from a drools-compiler {@link RuleDescr}.
Expand Down
Expand Up @@ -23,7 +23,6 @@
import org.drools.model.QueryDef;
import org.drools.modelcompiler.builder.PackageModel;
import org.drools.modelcompiler.builder.generator.visitor.ModelGeneratorVisitor;
import org.kie.soup.project.datamodel.commons.types.TypeResolver;

import static org.drools.modelcompiler.builder.generator.DrlxParseUtil.getClassFromContext;
import static org.drools.modelcompiler.builder.generator.DrlxParseUtil.toClassOrInterfaceType;
Expand All @@ -33,8 +32,8 @@

public class QueryGenerator {

public static void processQueryDef( KnowledgeBuilderImpl kbuilder, TypeResolver typeResolver, PackageModel packageModel, QueryDescr queryDescr, boolean isPattern ) {
RuleContext context = new RuleContext(kbuilder, packageModel, queryDescr, typeResolver, isPattern);
public static void processQueryDef(PackageModel packageModel, QueryDescr queryDescr, RuleContext context) {
context.setDescr(queryDescr);
String queryName = queryDescr.getName();
final String queryDefVariableName = toQueryDef(queryName);
context.setQueryName(Optional.of(queryDefVariableName));
Expand Down Expand Up @@ -82,8 +81,8 @@ public static void processQuery(KnowledgeBuilderImpl kbuilder, PackageModel pack
String queryDefVariableName = toQueryDef(queryDescr.getName());
RuleContext context = packageModel.getQueryDefWithType().get(queryDefVariableName).getContext();
context.addGlobalDeclarations(packageModel.getGlobals());
context.setDialectFromAttributes(queryDescr.getAttributes().values());

ModelGenerator.setDialectFromRuleDescr(context, queryDescr);
new ModelGeneratorVisitor(context, packageModel).visit(queryDescr.getLhs());
final Type queryType = JavaParser.parseType(Query.class.getCanonicalName());

Expand Down
Expand Up @@ -18,6 +18,7 @@
import org.drools.compiler.builder.impl.KnowledgeBuilderImpl;
import org.drools.compiler.compiler.BaseKnowledgeBuilderResultImpl;
import org.drools.compiler.lang.descr.AnnotationDescr;
import org.drools.compiler.lang.descr.AttributeDescr;
import org.drools.compiler.lang.descr.BaseDescr;
import org.drools.compiler.lang.descr.PatternDescr;
import org.drools.compiler.lang.descr.RuleDescr;
Expand Down Expand Up @@ -46,7 +47,7 @@ public class RuleContext {
private final PackageModel packageModel;
private final TypeResolver typeResolver;
private DRLIdGenerator idGenerator;
private final RuleDescr descr;
private RuleDescr descr;
private final boolean generatePatternDSL;

private List<DeclarationSpec> allDeclarations = new ArrayList<>();
Expand Down Expand Up @@ -82,18 +83,16 @@ public enum RuleDialect {

public BaseDescr parentDesc = null;

public RuleContext(KnowledgeBuilderImpl kbuilder, PackageModel packageModel, RuleDescr ruleDescr, TypeResolver typeResolver, boolean generatePatternDSL) {
public RuleContext(KnowledgeBuilderImpl kbuilder, PackageModel packageModel, TypeResolver typeResolver, boolean generatePatternDSL) {
this.kbuilder = kbuilder;
this.packageModel = packageModel;
this.idGenerator = packageModel.getExprIdGenerator();
this.descr = ruleDescr;
exprPointer.push( this.expressions::add );
this.typeResolver = typeResolver;
this.generatePatternDSL = generatePatternDSL;
findUnitClass();
}

private void findUnitClass() {
private void findUnitDescr() {
if (descr == null) {
return;
}
Expand Down Expand Up @@ -303,6 +302,11 @@ public RuleDescr getRuleDescr() {
return descr;
}

public void setDescr(RuleDescr descr) {
this.descr = descr;
findUnitDescr();
}

public String getRuleName() {
return descr.getName();
}
Expand Down Expand Up @@ -448,5 +452,16 @@ private void clear() {
} );
}
}

public void setDialectFromAttributes(Collection<AttributeDescr> attributes) {
for (AttributeDescr a : attributes) {
if (a.getName().equals("dialect")) {
if (a.getValue().equals("mvel")) {
setRuleDialect(RuleDialect.MVEL);
}
return;
}
}
}
}

Expand Up @@ -118,7 +118,7 @@ private List<Expression> parseConditions( KnowledgeBuilderImpl kbuilder, Package
return descrs.stream()
.map( descr -> {
String expression = descr.toString();
RuleContext context = new RuleContext(kbuilder, packageModel, null, typeResolver, true);
RuleContext context = new RuleContext(kbuilder, packageModel, typeResolver, true);
DrlxParseResult drlxParseResult = new ConstraintParser(context, packageModel).drlxParse(patternType, pattern.getIdentifier(), expression);
return drlxParseResult.acceptWithReturnValue(new ParseResultVisitor<Optional<Expression>>() {
@Override
Expand Down
Expand Up @@ -324,4 +324,29 @@ public void testMvelFunctionWithDeclaredTypeArg() {
ksession.dispose();
}
}

@Test
public void testMultiDrlWithSamePackageMvel() throws Exception {
// DROOLS-3508
String drl1 = "package org.pkg\n" +
"import " + Person.class.getCanonicalName() + "\n" +
"dialect \"mvel\"\n"; // MVEL dialect defined at package level.

String drl2 = "package org.pkg\n" +
"rule R1\n" +
"no-loop\n" +
"when\n" +
" $p : Person( name == \"John\" )\n" +
"then\n" +
" $p.age = 1;\n" +
" update($p);\n" +
"end\n";

KieSession ksession = getKieSession(drl1, drl2);

Person john = new Person("John", 24);
ksession.insert(john);
assertEquals(1, ksession.fireAllRules());
assertEquals(1, john.getAge());
}
}
Expand Up @@ -45,7 +45,8 @@ public void setUp() throws Exception {
imports = new HashSet<>();
packageModel = new PackageModel("", null, false, null, new DRLIdGenerator());
typeResolver = new ClassTypeResolver(imports, getClass().getClassLoader());
ruleContext = new RuleContext(knowledgeBuilder, packageModel, ruleDescr, typeResolver, true);
ruleContext = new RuleContext(knowledgeBuilder, packageModel, typeResolver, true);
ruleContext.setDescr(ruleDescr);
imports.add("org.drools.modelcompiler.domain.Person");
}

Expand Down

0 comments on commit e8f8ed1

Please sign in to comment.