use of org.drools.core.common.ReteEvaluator in project drools by kiegroup.
the class Misc2Test method testCustomDynamicSalience.
@Test
public void testCustomDynamicSalience() {
String drl = "package org.drools.test; " + "import " + Person.class.getName() + "; " + "global java.util.List list; " + "rule A " + "when " + " $person : Person( name == 'a' ) " + "then" + " list.add( $person.getAge() ); " + "end " + "rule B " + "when " + " $person : Person( name == 'b' ) " + "then" + " list.add( $person.getAge() ); " + "end " + "";
KieBase kbase = KieBaseUtil.getKieBaseFromKieModuleFromDrl("test", kieBaseTestConfiguration, drl);
KieSession session = kbase.newKieSession();
List<Integer> list = new ArrayList<>();
session.setGlobal("list", list);
for (Rule r : session.getKieBase().getKiePackage("org.drools.test").getRules()) {
((RuleImpl) r).setSalience(new Salience() {
@Override
public int getValue(Activation activation, Rule rule, ReteEvaluator reteEvaluator) {
if (activation == null) {
return 0;
}
InternalFactHandle h = (InternalFactHandle) activation.getFactHandles().get(0);
return ((Person) h.getObject()).getAge();
}
@Override
public int getValue() {
throw new IllegalStateException("Should not have been called...");
}
@Override
public boolean isDynamic() {
return true;
}
});
}
session.insert(new Person("a", 1));
session.insert(new Person("a", 5));
session.insert(new Person("a", 3));
session.insert(new Person("b", 4));
session.insert(new Person("b", 2));
session.insert(new Person("b", 6));
session.fireAllRules();
assertEquals(Arrays.asList(6, 5, 4, 3, 2, 1), list);
}
use of org.drools.core.common.ReteEvaluator in project drools by kiegroup.
the class DisposeCommandPublicAPITest method testDisposeCommand.
@Test
public void testDisposeCommand() {
InternalKnowledgeBase kBase;
RuleImpl rule;
InternalKnowledgePackage pkg;
kBase = KnowledgeBaseFactory.newKnowledgeBase();
pkg = CoreComponentFactory.get().createKnowledgePackage("org.droos.test");
pkg.setClassLoader(Thread.currentThread().getContextClassLoader());
JavaDialectRuntimeData data = new JavaDialectRuntimeData();
data.onAdd(pkg.getDialectRuntimeRegistry(), kBase.getRootClassLoader());
pkg.getDialectRuntimeRegistry().setDialectData("java", data);
rule = new RuleImpl("Test");
rule.setDialect("java");
rule.setConsequence(new Consequence() {
public void evaluate(KnowledgeHelper knowledgeHelper, ReteEvaluator reteEvaluator) throws Exception {
}
public String getName() {
return "default";
}
});
pkg.addRule(rule);
kBase.addPackage(pkg);
KieSession session = kBase.newKieSession();
Command dispose = KieServices.Factory.get().getCommands().newDispose();
session.insert("whatever");
session.fireAllRules();
session.execute(dispose);
try {
session.insert("whatever");
} catch (Exception e) {
Assert.assertEquals(e.getMessage(), "Illegal method call. This session was previously disposed.");
}
}
use of org.drools.core.common.ReteEvaluator in project drools by kiegroup.
the class ConsequenceGenerator method generate.
public static void generate(final ConsequenceStub stub, KnowledgeHelper knowledgeHelper, ReteEvaluator reteEvaluator) {
RuleTerminalNode rtn = knowledgeHelper.getMatch().getTuple().getTupleSink();
final Declaration[] declarations = rtn.getRequiredDeclarations();
final Tuple tuple = knowledgeHelper.getTuple();
// Sort declarations based on their offset, so it can ascend the tuple's parents stack only once
final List<DeclarationMatcher> declarationMatchers = matchDeclarationsToTuple(declarations);
final ClassGenerator generator = createInvokerClassGenerator(stub, reteEvaluator).setInterfaces(Consequence.class, CompiledInvoker.class);
generator.addMethod(ACC_PUBLIC, "getName", generator.methodDescr(String.class), new ClassGenerator.MethodBody() {
public void body(MethodVisitor mv) {
push(stub.getGeneratedInvokerClassName());
mv.visitInsn(ARETURN);
}
}).addMethod(ACC_PUBLIC, "evaluate", generator.methodDescr(null, KnowledgeHelper.class, ReteEvaluator.class), new String[] { "java/lang/Exception" }, new GeneratorHelper.EvaluateMethod() {
public void body(MethodVisitor mv) {
// Tuple tuple = knowledgeHelper.getTuple();
mv.visitVarInsn(ALOAD, 1);
invokeInterface(KnowledgeHelper.class, "getTuple", Tuple.class);
cast(LeftTuple.class);
// LeftTuple
mv.visitVarInsn(ASTORE, 3);
// Declaration[] declarations = ((RuleTerminalNode)knowledgeHelper.getMatch().getTuple().getTupleSink()).getDeclarations();
mv.visitVarInsn(ALOAD, 1);
invokeInterface(KnowledgeHelper.class, "getMatch", Activation.class);
invokeInterface(Activation.class, "getTuple", Tuple.class);
invokeInterface(Tuple.class, "getTupleSink", Sink.class);
cast(RuleTerminalNode.class);
invokeVirtual(RuleTerminalNode.class, "getRequiredDeclarations", Declaration[].class);
mv.visitVarInsn(ASTORE, 4);
Tuple currentTuple = tuple;
// astore start position for objects to store in loop
objAstorePos = 6;
int[] paramsPos = new int[declarations.length];
// declarationMatchers is already sorted by offset with tip declarations now first
for (DeclarationMatcher matcher : declarationMatchers) {
// original index refers to the array position with RuleTerminalNode.getDeclarations()
int i = matcher.getMatcherIndex();
int handlePos = objAstorePos;
int objPos = ++objAstorePos;
paramsPos[i] = handlePos;
currentTuple = traverseTuplesUntilDeclaration(currentTuple, matcher.getTupleIndex(), 3);
// handle = tuple.getFactHandle()
mv.visitVarInsn(ALOAD, 3);
invokeInterface(Tuple.class, "getOriginalFactHandle", InternalFactHandle.class);
mv.visitVarInsn(ASTORE, handlePos);
String declarationType = declarations[i].getTypeName();
if (stub.getNotPatterns()[i]) {
// notPattern indexes field declarations
// declarations[i].getValue(reteEvaluator, fact[i].getObject());
// org.kie.rule.Declaration[]
mv.visitVarInsn(ALOAD, 4);
// i
push(i);
// declarations[i]
mv.visitInsn(AALOAD);
// WorkingMemory
mv.visitVarInsn(ALOAD, 2);
// handle[i]
mv.visitVarInsn(ALOAD, handlePos);
invokeInterface(InternalFactHandle.class, "getObject", Object.class);
storeObjectFromDeclaration(declarations[i], declarationType);
// The facthandle should be set to that of the field, if it's an object, otherwise this will return null
// fact[i] = (InternalFactHandle)reteEvaluator.getFactHandle(obj);
mv.visitVarInsn(ALOAD, 2);
loadAsObject(objPos);
invokeInterface(WorkingMemory.class, "getFactHandle", FactHandle.class, Object.class);
cast(InternalFactHandle.class);
mv.visitVarInsn(ASTORE, handlePos);
} else {
// handle[i]
mv.visitVarInsn(ALOAD, handlePos);
invokeInterface(InternalFactHandle.class, "getObject", Object.class);
mv.visitTypeInsn(CHECKCAST, internalName(declarationType));
// obj[i]
objAstorePos += store(objPos, declarationType);
}
}
// @{ruleClassName}.@{methodName}(KnowledgeHelper, @foreach{declr : declarations} Object, FactHandle @end)
StringBuilder consequenceMethodDescr = new StringBuilder("(L" + KnowledgeHelper.class.getName().replace('.', '/') + ";");
// KnowledgeHelper
mv.visitVarInsn(ALOAD, 1);
for (int i = 0; i < declarations.length; i++) {
// obj[i]
load(paramsPos[i] + 1);
// handle[i]
mv.visitVarInsn(ALOAD, paramsPos[i]);
consequenceMethodDescr.append(typeDescr(declarations[i].getTypeName())).append("L" + FactHandle.class.getName().replace('.', '/') + ";");
}
// @foreach{type : globalTypes, identifier : globals} @{type} @{identifier} = ( @{type} ) workingMemory.getGlobal( "@{identifier}" );
parseGlobals(stub.getGlobals(), stub.getGlobalTypes(), 2, consequenceMethodDescr);
consequenceMethodDescr.append(")V");
mv.visitMethodInsn(INVOKESTATIC, stub.getInternalRuleClassName(), stub.getMethodName(), consequenceMethodDescr.toString());
mv.visitInsn(RETURN);
}
});
stub.setConsequence(generator.<Consequence>newInstance());
}
use of org.drools.core.common.ReteEvaluator in project drools by kiegroup.
the class PhreakRuleTerminalNode method doLeftTupleUpdate.
public static void doLeftTupleUpdate(TerminalNode rtnNode, RuleExecutor executor, ActivationsManager activationsManager, LeftTuple leftTuple) {
RuleTerminalNodeLeftTuple rtnLeftTuple = (RuleTerminalNodeLeftTuple) leftTuple;
ReteEvaluator reteEvaluator = activationsManager.getReteEvaluator();
if (reteEvaluator.getSessionConfiguration().isDirectFiring()) {
if (!rtnLeftTuple.isQueued()) {
executor.addLeftTuple(leftTuple);
reteEvaluator.getRuleEventSupport().onUpdateMatch(rtnLeftTuple);
}
return;
}
PropagationContext pctx = leftTuple.findMostRecentPropagationContext();
boolean blocked = false;
if (executor.isDeclarativeAgendaEnabled()) {
if (rtnLeftTuple.hasBlockers()) {
// declarativeAgenda still blocking LeftTuple, so don't add back ot list
blocked = true;
}
} else {
blocked = rtnNode.getRule().isNoLoop() && rtnNode.equals(pctx.getTerminalNodeOrigin());
}
int salienceInt = getSalienceValue(rtnNode, executor.getRuleAgendaItem(), (AgendaItem) leftTuple, reteEvaluator);
if (activationsManager.getActivationsFilter() != null && !activationsManager.getActivationsFilter().accept(rtnLeftTuple, reteEvaluator, rtnNode)) {
// only relevant for serialization, to not re-fire Matches already fired
return;
}
if (!blocked) {
boolean addToExector = true;
if (rtnNode.getRule().isLockOnActive() && pctx.getType() != PropagationContext.Type.RULE_ADDITION) {
InternalAgendaGroup agendaGroup = executor.getRuleAgendaItem().getAgendaGroup();
if (blockedByLockOnActive(rtnNode.getRule(), pctx, agendaGroup)) {
addToExector = false;
}
}
if (addToExector) {
if (!rtnLeftTuple.isQueued()) {
// not queued, so already fired, so it's effectively recreated
activationsManager.getAgendaEventSupport().fireActivationCreated(rtnLeftTuple, reteEvaluator);
rtnLeftTuple.update(salienceInt, pctx);
executor.addLeftTuple(leftTuple);
reteEvaluator.getRuleEventSupport().onUpdateMatch(rtnLeftTuple);
}
}
} else {
// LeftTuple is blocked, and thus not queued, so just update it's values
rtnLeftTuple.update(salienceInt, pctx);
}
if (!rtnNode.isFireDirect() && executor.isDeclarativeAgendaEnabled()) {
modifyActivation(reteEvaluator, rtnLeftTuple);
}
}
use of org.drools.core.common.ReteEvaluator in project drools by kiegroup.
the class PhreakRuleTerminalNode method doLeftTupleInsert.
public static void doLeftTupleInsert(TerminalNode rtnNode, RuleExecutor executor, ActivationsManager activationsManager, RuleAgendaItem ruleAgendaItem, LeftTuple leftTuple) {
ReteEvaluator reteEvaluator = activationsManager.getReteEvaluator();
if (reteEvaluator.getSessionConfiguration().isDirectFiring()) {
executor.addLeftTuple(leftTuple);
return;
}
PropagationContext pctx = leftTuple.findMostRecentPropagationContext();
if (rtnNode.getRule().isNoLoop() && rtnNode.equals(pctx.getTerminalNodeOrigin())) {
return;
}
int salienceInt = getSalienceValue(rtnNode, ruleAgendaItem, (AgendaItem) leftTuple, reteEvaluator);
RuleTerminalNodeLeftTuple rtnLeftTuple = (RuleTerminalNodeLeftTuple) leftTuple;
activationsManager.createAgendaItem(rtnLeftTuple, salienceInt, pctx, ruleAgendaItem, ruleAgendaItem.getAgendaGroup());
activationsManager.getAgendaEventSupport().fireActivationCreated(rtnLeftTuple, activationsManager.getReteEvaluator());
if (rtnNode.getRule().isLockOnActive() && leftTuple.getPropagationContext().getType() != PropagationContext.Type.RULE_ADDITION) {
InternalAgendaGroup agendaGroup = executor.getRuleAgendaItem().getAgendaGroup();
if (blockedByLockOnActive(rtnNode.getRule(), pctx, agendaGroup)) {
activationsManager.getAgendaEventSupport().fireActivationCancelled(rtnLeftTuple, reteEvaluator, MatchCancelledCause.FILTER);
return;
}
}
if (activationsManager.getActivationsFilter() != null && !activationsManager.getActivationsFilter().accept(rtnLeftTuple, reteEvaluator, rtnNode)) {
// only relevant for seralization, to not refire Matches already fired
return;
}
executor.addLeftTuple(leftTuple);
// increased here, decreased in Agenda's cancelActivation and fireActivation
leftTuple.increaseActivationCountForEvents();
activationsManager.addItemToActivationGroup(rtnLeftTuple);
if (!rtnNode.isFireDirect() && executor.isDeclarativeAgendaEnabled()) {
insertAndStageActivation(reteEvaluator, rtnLeftTuple);
}
}
Aggregations