use of org.drools.core.definitions.rule.impl.RuleImpl in project drools by kiegroup.
the class RuleExecutor method fire.
private int fire(InternalWorkingMemory wm, InternalAgenda agenda, AgendaFilter filter, int fireCount, int fireLimit) {
int localFireCount = 0;
if (!tupleList.isEmpty()) {
if (!fireExitedEarly && isDeclarativeAgendaEnabled()) {
// Network Evaluation can notify meta rules, which should be given a chance to fire first
RuleAgendaItem nextRule = agenda.peekNextRule();
if (!isHigherSalience(nextRule)) {
fireExitedEarly = true;
return localFireCount;
}
}
RuleTerminalNode rtn = (RuleTerminalNode) pmem.getPathEndNode();
RuleImpl rule = rtn.getRule();
Tuple tuple = getNextTuple();
if (rule.isAllMatches()) {
fireConsequenceEvent(wm, agenda, (AgendaItem) tuple, DefaultAgenda.ON_BEFORE_ALL_FIRES_CONSEQUENCE_NAME);
}
Tuple lastTuple = null;
for (; tuple != null; lastTuple = tuple, tuple = getNextTuple()) {
// if the current Rule is no-loop and the origin rule is the same then return
if (cancelAndContinue(wm, rtn, rule, tuple, filter)) {
continue;
}
AgendaItem item = (AgendaItem) tuple;
if (agenda.getActivationsFilter() != null && !agenda.getActivationsFilter().accept(item, wm, rtn)) {
// only relevant for seralization, to not refire Matches already fired
continue;
}
fireActivation(wm, agenda, item);
localFireCount++;
if (rtn.getLeftTupleSource() == null) {
// The activation firing removed this rule from the rule base
break;
}
agenda.flushPropagations();
// dyanmic salience may have updated it, so get again.
int salience = ruleAgendaItem.getSalience();
if (queue != null && !queue.isEmpty() && salience != queue.peek().getSalience()) {
ruleAgendaItem.dequeue();
ruleAgendaItem.setSalience(queue.peek().getSalience());
ruleAgendaItem.getAgendaGroup().add(ruleAgendaItem);
}
if (!rule.isAllMatches()) {
// if firing rule is @All don't give way to other rules
if (haltRuleFiring(fireCount, fireLimit, localFireCount, agenda)) {
// another rule has high priority and is on the agenda, so evaluate it first
break;
}
if (!wm.isSequential()) {
reEvaluateNetwork(agenda);
}
}
}
if (rule.isAllMatches()) {
fireConsequenceEvent(wm, agenda, (AgendaItem) lastTuple, DefaultAgenda.ON_AFTER_ALL_FIRES_CONSEQUENCE_NAME);
}
}
removeRuleAgendaItemWhenEmpty(wm);
fireExitedEarly = false;
return localFireCount;
}
use of org.drools.core.definitions.rule.impl.RuleImpl in project drools by kiegroup.
the class AddRemoveRule method removeRule.
/**
* This method is called before the rule nodes are removed from the network.
* For remove tuples are processed before the segments and pmems have been adjusted
*/
public static void removeRule(TerminalNode tn, InternalWorkingMemory[] wms, InternalKnowledgeBase kBase) {
if (log.isTraceEnabled()) {
log.trace("Removing Rule {}", tn.getRule().getName());
}
boolean hasProtos = kBase.hasSegmentPrototypes();
boolean hasWms = wms.length > 0;
if (!hasProtos && !hasWms) {
return;
}
RuleImpl rule = tn.getRule();
LeftTupleNode firstSplit = getNetworkSplitPoint(tn);
PathEndNodes pathEndNodes = getPathEndNodes(kBase, firstSplit, tn, rule, hasProtos, hasWms);
for (InternalWorkingMemory wm : wms) {
wm.flushPropagations();
PathEndNodeMemories tnms = getPathEndMemories(wm, pathEndNodes);
if (!tnms.subjectPmems.isEmpty()) {
if (NodeTypeEnums.LeftInputAdapterNode == firstSplit.getType() && firstSplit.getAssociationsSize() == 1) {
if (tnms.subjectPmem != null) {
flushStagedTuples(firstSplit, tnms.subjectPmem, wm);
}
processLeftTuples(firstSplit, wm, false, tn.getRule());
removeNewPaths(wm, tnms.subjectPmems);
} else {
flushStagedTuples(tn, tnms.subjectPmem, pathEndNodes, wm);
processLeftTuples(firstSplit, wm, false, tn.getRule());
removeNewPaths(wm, tnms.subjectPmems);
Map<PathMemory, SegmentMemory[]> prevSmemsLookup = reInitPathMemories(tnms.otherPmems, tn);
// must collect all visited SegmentMemories, for link notification
Set<SegmentMemory> smemsToNotify = handleExistingPaths(tn, prevSmemsLookup, tnms.otherPmems, wm, ExistingPathStrategy.REMOVE_STRATEGY);
notifySegments(smemsToNotify, wm);
}
}
if (tnms.subjectPmem != null && tnms.subjectPmem.isInitialized() && tnms.subjectPmem.getRuleAgendaItem().isQueued()) {
// SubjectPmem can be null, if it was never initialized
tnms.subjectPmem.getRuleAgendaItem().dequeue();
}
}
}
use of org.drools.core.definitions.rule.impl.RuleImpl in project drools by kiegroup.
the class AddRemoveRule method addRule.
/**
* This method is called after the rule nodes have been added to the network
* For add tuples are processed after the segments and pmems have been adjusted
*/
public static void addRule(TerminalNode tn, InternalWorkingMemory[] wms, InternalKnowledgeBase kBase) {
if (log.isTraceEnabled()) {
log.trace("Adding Rule {}", tn.getRule().getName());
}
boolean hasProtos = kBase.hasSegmentPrototypes();
boolean hasWms = wms.length > 0;
if (!hasProtos && !hasWms) {
return;
}
RuleImpl rule = tn.getRule();
LeftTupleNode firstSplit = getNetworkSplitPoint(tn);
PathEndNodes pathEndNodes = getPathEndNodes(kBase, firstSplit, tn, rule, hasProtos, hasWms);
for (InternalWorkingMemory wm : wms) {
wm.flushPropagations();
if (NodeTypeEnums.LeftInputAdapterNode == firstSplit.getType() && firstSplit.getAssociationsSize() == 1) {
// rule added with no sharing
insertLiaFacts(firstSplit, wm);
} else {
PathEndNodeMemories tnms = getPathEndMemories(wm, pathEndNodes);
if (tnms.subjectPmem == null) {
// If the existing PathMemories are not yet initialized there are no Segments or tuples to process
continue;
}
Map<PathMemory, SegmentMemory[]> prevSmemsLookup = reInitPathMemories(tnms.otherPmems, null);
// must collect all visited SegmentMemories, for link notification
Set<SegmentMemory> smemsToNotify = handleExistingPaths(tn, prevSmemsLookup, tnms.otherPmems, wm, ExistingPathStrategy.ADD_STRATEGY);
addNewPaths(wm, smemsToNotify, tnms.subjectPmems);
processLeftTuples(firstSplit, wm, true, rule);
notifySegments(smemsToNotify, wm);
}
}
if (hasWms) {
insertFacts(pathEndNodes, wms);
} else {
for (PathEndNode node : pathEndNodes.otherEndNodes) {
node.resetPathMemSpec(null);
}
}
}
use of org.drools.core.definitions.rule.impl.RuleImpl in project drools by kiegroup.
the class KnowledgeBaseImpl method removeRule.
public void removeRule(final String packageName, final String ruleName) {
enqueueModification(() -> {
final InternalKnowledgePackage pkg = pkgs.get(packageName);
if (pkg == null) {
throw new IllegalArgumentException("Package name '" + packageName + "' does not exist for this Rule Base.");
}
RuleImpl rule = pkg.getRule(ruleName);
if (rule == null) {
throw new IllegalArgumentException("Rule name '" + ruleName + "' does not exist in the Package '" + packageName + "'.");
}
this.eventSupport.fireBeforeRuleRemoved(rule);
this.reteooBuilder.removeRules(Collections.singletonList(rule));
this.eventSupport.fireAfterRuleRemoved(rule);
pkg.removeRule(rule);
addReloadDialectDatas(pkg.getDialectRuntimeRegistry());
});
}
use of org.drools.core.definitions.rule.impl.RuleImpl in project drools by kiegroup.
the class KnowledgeBaseImpl method mergePackage.
/**
* Merge a new package with an existing package.
* Most of the work is done by the concrete implementations,
* but this class does some work (including combining imports, compilation data, globals,
* and the actual Rule objects into the package).
*/
private void mergePackage(InternalKnowledgePackage pkg, InternalKnowledgePackage newPkg) {
// Merge imports
final Map<String, ImportDeclaration> imports = pkg.getImports();
imports.putAll(newPkg.getImports());
// Merge static imports
for (String staticImport : newPkg.getStaticImports()) {
pkg.addStaticImport(staticImport);
}
String lastIdent = null;
String lastType = null;
try {
// merge globals
if (newPkg.getGlobals() != null && newPkg.getGlobals() != Collections.EMPTY_MAP) {
Map<String, String> globals = pkg.getGlobals();
// Add globals
for (final Map.Entry<String, String> entry : newPkg.getGlobals().entrySet()) {
final String identifier = entry.getKey();
final String type = entry.getValue();
lastIdent = identifier;
lastType = type;
if (globals.containsKey(identifier) && !globals.get(identifier).equals(type)) {
throw new RuntimeException(pkg.getName() + " cannot be integrated");
} else {
pkg.addGlobal(identifier, this.rootClassLoader.loadClass(type));
// this isn't a package merge, it's adding to the rulebase, but I've put it here for convienience
addGlobal(identifier, this.rootClassLoader.loadClass(type));
}
}
}
} catch (ClassNotFoundException e) {
throw new RuntimeException("Unable to resolve class '" + lastType + "' for global '" + lastIdent + "'");
}
// merge entry point declarations
if (newPkg.getEntryPointIds() != null) {
for (String ep : newPkg.getEntryPointIds()) {
pkg.addEntryPointId(ep);
}
}
// merge the type declarations
if (newPkg.getTypeDeclarations() != null) {
// add type declarations
for (TypeDeclaration type : newPkg.getTypeDeclarations().values()) {
// @TODO should we allow overrides? only if the class is not in use.
if (!pkg.getTypeDeclarations().containsKey(type.getTypeName())) {
// add to package list of type declarations
pkg.addTypeDeclaration(type);
}
}
}
// merge window declarations
if (newPkg.getWindowDeclarations() != null) {
// add window declarations
for (WindowDeclaration window : newPkg.getWindowDeclarations().values()) {
if (!pkg.getWindowDeclarations().containsKey(window.getName()) || pkg.getWindowDeclarations().get(window.getName()).equals(window)) {
pkg.addWindowDeclaration(window);
} else {
throw new RuntimeException("Unable to merge two conflicting window declarations for window named: " + window.getName());
}
}
}
// Merge rules into the RuleBase package
// as this is needed for individual rule removal later on
List<RuleImpl> rulesToBeRemoved = new ArrayList<RuleImpl>();
for (Rule newRule : newPkg.getRules()) {
// remove the rule if it already exists
RuleImpl oldRule = pkg.getRule(newRule.getName());
if (oldRule != null) {
rulesToBeRemoved.add(oldRule);
}
}
if (!rulesToBeRemoved.isEmpty()) {
removeRules(rulesToBeRemoved);
}
for (Rule newRule : newPkg.getRules()) {
pkg.addRule((RuleImpl) newRule);
}
// Merge The Rule Flows
if (newPkg.getRuleFlows() != null) {
for (Process flow : newPkg.getRuleFlows().values()) {
pkg.addProcess(flow);
}
}
if (!newPkg.getResourceTypePackages().isEmpty()) {
for (ResourceTypePackage rtkKpg : newPkg.getResourceTypePackages().values()) {
ResourceType rt = rtkKpg.getResourceType();
KieWeavers weavers = ServiceRegistry.getInstance().get(KieWeavers.class);
KieWeaverService weaver = weavers.getWeavers().get(rt);
weaver.merge(this, pkg, rtkKpg);
}
}
}
Aggregations