use of org.kie.api.definition.rule.Rule in project drools by kiegroup.
the class RuleCoverageListenerTest method testCoverage.
@Test
public void testCoverage() throws Exception {
// configuring mock event
AfterMatchFiredEvent amfe = mock(AfterMatchFiredEvent.class);
Match match = mock(Match.class);
Rule rule = mock(Rule.class);
when(amfe.getMatch()).thenReturn(match);
when(match.getRule()).thenReturn(rule);
when(rule.getName()).thenReturn("rule1").thenReturn("rule2").thenReturn("rule3");
HashSet<String> rules = new HashSet<String>();
rules.add("rule1");
rules.add("rule2");
rules.add("rule3");
RuleCoverageListener ls = new RuleCoverageListener(rules);
Assert.assertEquals(3, ls.rules.size());
Assert.assertEquals(0, ls.getPercentCovered());
ls.afterMatchFired(amfe);
Assert.assertEquals(2, ls.rules.size());
assertTrue(ls.rules.contains("rule2"));
assertTrue(ls.rules.contains("rule3"));
assertFalse(ls.rules.contains("rule1"));
Assert.assertEquals(33, ls.getPercentCovered());
ls.afterMatchFired(amfe);
Assert.assertEquals(1, ls.rules.size());
assertFalse(ls.rules.contains("rule2"));
assertFalse(ls.rules.contains("rule1"));
assertTrue(ls.rules.contains("rule3"));
Assert.assertEquals(66, ls.getPercentCovered());
ls.afterMatchFired(amfe);
Assert.assertEquals(0, ls.rules.size());
assertFalse(ls.rules.contains("rule2"));
assertFalse(ls.rules.contains("rule1"));
assertFalse(ls.rules.contains("rule3"));
Assert.assertEquals(100, ls.getPercentCovered());
}
use of org.kie.api.definition.rule.Rule in project drools by kiegroup.
the class KnowledgeBuilderTest method testKnowledgeProviderWithRules.
@Test
public void testKnowledgeProviderWithRules() {
KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder();
String str = "";
str += "package org.drools.compiler.test1\n";
str += "rule rule1\n";
str += "when\n";
str += "then\n";
str += "end\n\n";
str += "rule rule2\n";
str += "when\n";
str += "then\n";
str += "end\n";
builder.add(ResourceFactory.newByteArrayResource(str.getBytes()), ResourceType.DRL);
str = "package org.drools.compiler.test2\n";
str += "rule rule3\n";
str += "when\n";
str += "then\n";
str += "end\n\n";
str += "rule rule4\n";
str += "when\n";
str += "then\n";
str += "end\n";
builder.add(ResourceFactory.newByteArrayResource(str.getBytes()), ResourceType.DRL);
Collection<KiePackage> pkgs = builder.getKnowledgePackages();
assertNotNull(pkgs);
assertEquals(2, pkgs.size());
KiePackage test1 = getKnowledgePackage(pkgs, "org.drools.compiler.test1");
Collection<Rule> rules = test1.getRules();
assertEquals(2, rules.size());
Rule rule = getRule(rules, "rule1");
assertEquals("rule1", rule.getName());
rule = getRule(rules, "rule2");
assertEquals("rule2", rule.getName());
KiePackage test2 = getKnowledgePackage(pkgs, "org.drools.compiler.test2");
rules = test2.getRules();
assertEquals(2, rules.size());
rule = getRule(rules, "rule3");
assertEquals("rule3", rule.getName());
rule = getRule(rules, "rule4");
assertEquals("rule4", rule.getName());
}
use of org.kie.api.definition.rule.Rule in project drools by kiegroup.
the class KnowledgeBaseImpl method internalAddPackages.
private void internalAddPackages(List<InternalKnowledgePackage> clonedPkgs) {
for (InternalWorkingMemory wm : getWorkingMemories()) {
wm.flushPropagations();
}
// we need to merge all byte[] first, so that the root classloader can resolve classes
for (InternalKnowledgePackage newPkg : clonedPkgs) {
newPkg.checkValidity();
this.eventSupport.fireBeforePackageAdded(newPkg);
if (newPkg.hasTraitRegistry()) {
getTraitRegistry().merge(newPkg.getTraitRegistry());
}
InternalKnowledgePackage pkg = this.pkgs.get(newPkg.getName());
if (pkg == null) {
pkg = new KnowledgePackageImpl(newPkg.getName());
// @TODO we really should have a single root cache
pkg.setClassFieldAccessorCache(this.classFieldAccessorCache);
pkgs.put(pkg.getName(), pkg);
}
// first merge anything related to classloader re-wiring
pkg.getDialectRuntimeRegistry().merge(newPkg.getDialectRuntimeRegistry(), this.rootClassLoader, true);
}
processAllTypesDeclaration(clonedPkgs);
for (InternalKnowledgePackage newPkg : clonedPkgs) {
// Add functions
JavaDialectRuntimeData runtime = ((JavaDialectRuntimeData) newPkg.getDialectRuntimeRegistry().getDialectData("java"));
for (Function function : newPkg.getFunctions().values()) {
String functionClassName = function.getClassName();
try {
registerFunctionClassAndInnerClasses(functionClassName, runtime, this::registerAndLoadTypeDefinition);
} catch (ClassNotFoundException e) {
throw new RuntimeException("Unable to compile function '" + function.getName() + "'", e);
}
}
}
// now iterate again, this time onBeforeExecute will handle any wiring or cloader re-creating that needs to be done as part of the merge
for (InternalKnowledgePackage newPkg : clonedPkgs) {
InternalKnowledgePackage pkg = this.pkgs.get(newPkg.getName());
// this needs to go here, as functions will set a java dialect to dirty
if (newPkg.getFunctions() != null) {
for (Map.Entry<String, Function> entry : newPkg.getFunctions().entrySet()) {
pkg.addFunction(entry.getValue());
}
}
pkg.getDialectRuntimeRegistry().onBeforeExecute();
// with the classloader recreated for all byte[] classes, we should now merge and wire any new accessors
pkg.getClassFieldAccessorStore().merge(newPkg.getClassFieldAccessorStore());
}
for (InternalKnowledgePackage newPkg : clonedPkgs) {
InternalKnowledgePackage pkg = this.pkgs.get(newPkg.getName());
// now merge the new package into the existing one
mergePackage(pkg, newPkg);
// add the window declarations to the kbase
for (WindowDeclaration window : newPkg.getWindowDeclarations().values()) {
this.reteooBuilder.addNamedWindow(window);
}
// add entry points to the kbase
for (String id : newPkg.getEntryPointIds()) {
this.reteooBuilder.addEntryPoint(id);
}
// add the rules to the RuleBase
for (Rule r : newPkg.getRules()) {
RuleImpl rule = (RuleImpl) r;
checkMultithreadedEvaluation(rule);
internalAddRule(rule);
}
// add the flows to the RuleBase
if (newPkg.getRuleFlows() != null) {
final Map<String, Process> flows = newPkg.getRuleFlows();
for (Process process : flows.values()) {
internalAddProcess(process);
}
}
if (!newPkg.getResourceTypePackages().isEmpty()) {
KieWeavers weavers = ServiceRegistry.getInstance().get(KieWeavers.class);
for (ResourceTypePackage rtkKpg : newPkg.getResourceTypePackages().values()) {
ResourceType rt = rtkKpg.getResourceType();
KieWeaverService factory = weavers.getWeavers().get(rt);
factory.weave(this, newPkg, rtkKpg);
}
}
ruleUnitRegistry.add(newPkg.getRuleUnitRegistry());
this.eventSupport.fireAfterPackageAdded(newPkg);
}
if (config.isMultithreadEvaluation() && !hasMultiplePartitions()) {
disableMultithreadEvaluation("The rete network cannot be partitioned: disabling multithread evaluation");
}
}
use of org.kie.api.definition.rule.Rule in project drools by kiegroup.
the class AttributesTest method testRuleAttributes.
@Test
public void testRuleAttributes() throws Exception {
setKSession(getModelSession(source, VERBOSE));
setKbase(getKSession().getKieBase());
checkGeneratedRules();
for (Rule r : getKbase().getKiePackage("org.kie.pmml.attribs.test").getRules()) {
assertEquals("test-rf", ((RuleImpl) r).getAgendaGroup());
assertEquals("test-rf", ((RuleImpl) r).getRuleFlowGroup());
}
}
use of org.kie.api.definition.rule.Rule in project drools by kiegroup.
the class MVELExprAnalyzer method analyzeExpression.
// ------------------------------------------------------------
// Instance methods
// ------------------------------------------------------------
/**
* Analyze an expression.
*
* @param expr
* The expression to analyze.
* @param availableIdentifiers
* 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.
*/
@SuppressWarnings("unchecked")
public static MVELAnalysisResult analyzeExpression(final PackageBuildContext context, final String expr, final BoundIdentifiers availableIdentifiers, final Map<String, Class<?>> localTypes, String contextIdentifier, Class kcontextClass) {
if (expr.trim().length() <= 0) {
MVELAnalysisResult result = analyze((Set<String>) Collections.EMPTY_SET, availableIdentifiers);
result.setMvelVariables(new HashMap<String, Class<?>>());
result.setTypesafe(true);
return result;
}
MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = true;
MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true;
MVEL.COMPILER_OPT_ALLOW_RESOLVE_INNERCLASSES_WITH_DOTNOTATION = true;
MVEL.COMPILER_OPT_SUPPORT_JAVA_STYLE_CLASS_LITERALS = true;
MVELDialect dialect = (MVELDialect) context.getDialect("mvel");
ParserConfiguration conf = context.getMVELDialectRuntimeData().getParserConfiguration();
conf.setClassLoader(context.getKnowledgeBuilder().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());
}
if (availableIdentifiers.getOperators() != null) {
for (Entry<String, EvaluatorWrapper> opEntry : availableIdentifiers.getOperators().entrySet()) {
parserContext1.addInput(opEntry.getKey(), opEntry.getValue().getClass());
}
}
parserContext1.setStrictTypeEnforcement(false);
parserContext1.setStrongTyping(false);
parserContext1.setInterceptors(dialect.getInterceptors());
Class<?> returnType;
try {
returnType = MVEL.analyze(expr, parserContext1);
} catch (Exception e) {
BaseDescr base = (context instanceof RuleBuildContext) ? ((RuleBuildContext) context).getRuleDescr() : context.getParentDescr();
if (e instanceof CompileException && e.getCause() != null && e.getMessage().startsWith("[Error: null]")) {
// rewrite error message in cause original message is null
e = new CompileException(e.getCause().toString(), ((CompileException) e).getExpr(), ((CompileException) e).getCursor(), e.getCause());
}
DialectUtil.copyErrorLocation(e, context.getParentDescr());
context.addError(new DescrBuildError(base, context.getParentDescr(), null, "Unable to Analyse Expression " + expr + ":\n" + e.getMessage()));
return null;
}
Set<String> requiredInputs = new HashSet<String>();
requiredInputs.addAll(parserContext1.getInputs().keySet());
HashMap<String, Class<?>> variables = (HashMap<String, Class<?>>) ((Map) parserContext1.getVariables());
if (localTypes != null) {
for (String str : localTypes.keySet()) {
// we have to do this due to mvel regressions on detecting true local vars
variables.remove(str);
}
}
// MVEL includes direct fields of context object in non-strict mode. so we need to strip those
if (availableIdentifiers.getThisClass() != null) {
requiredInputs.removeIf(s -> PropertyTools.getFieldOrAccessor(availableIdentifiers.getThisClass(), s) != null);
}
// 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());
for (String input : requiredInputs) {
if ("this".equals(input)) {
continue;
}
Class<?> cls = availableIdentifiers.resolveType(input);
if (cls == null) {
if (input.equals(contextIdentifier) || input.equals("kcontext")) {
cls = kcontextClass;
} else if (input.equals("rule")) {
cls = Rule.class;
} else if (localTypes != null) {
cls = localTypes.get(input);
}
}
if (cls != null) {
parserContext2.addInput(input, cls);
}
}
if (availableIdentifiers.getThisClass() != null) {
parserContext2.addInput("this", availableIdentifiers.getThisClass());
}
boolean typesafe = context.isTypesafe();
try {
returnType = MVEL.analyze(expr, parserContext2);
typesafe = true;
} catch (Exception e) {
// is this an error, or can we fall back to non-typesafe mode?
if (typesafe) {
BaseDescr base = (context instanceof RuleBuildContext) ? ((RuleBuildContext) context).getRuleDescr() : context.getParentDescr();
DialectUtil.copyErrorLocation(e, context.getParentDescr());
context.addError(new DescrBuildError(base, context.getParentDescr(), null, "Unable to Analyse Expression " + expr + ":\n" + e.getMessage()));
return null;
}
}
if (typesafe) {
requiredInputs = new HashSet<String>();
requiredInputs.addAll(parserContext2.getInputs().keySet());
requiredInputs.addAll(variables.keySet());
variables = (HashMap<String, Class<?>>) ((Map) parserContext2.getVariables());
if (localTypes != null) {
for (String str : localTypes.keySet()) {
// we have to do this due to mvel regressions on detecting true local vars
variables.remove(str);
}
}
}
MVELAnalysisResult result = analyze(requiredInputs, availableIdentifiers);
result.setReturnType(returnType);
result.setMvelVariables(variables);
result.setTypesafe(typesafe);
return result;
}
Aggregations