Search in sources :

Example 11 with ReteEvaluator

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);
}
Also used : ReteEvaluator(org.drools.core.common.ReteEvaluator) ArrayList(java.util.ArrayList) RuleImpl(org.drools.core.definitions.rule.impl.RuleImpl) Activation(org.drools.core.spi.Activation) FactWithString(org.drools.mvel.integrationtests.facts.FactWithString) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) KieBase(org.kie.api.KieBase) Salience(org.drools.core.spi.Salience) KieSession(org.kie.api.runtime.KieSession) StatelessKieSession(org.kie.api.runtime.StatelessKieSession) Rule(org.kie.api.definition.rule.Rule) InternalFactHandle(org.drools.core.common.InternalFactHandle) Person(org.drools.mvel.compiler.Person) Test(org.junit.Test)

Example 12 with ReteEvaluator

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.");
    }
}
Also used : ReteEvaluator(org.drools.core.common.ReteEvaluator) Command(org.kie.api.command.Command) Consequence(org.drools.core.spi.Consequence) RuleImpl(org.drools.core.definitions.rule.impl.RuleImpl) KnowledgeHelper(org.drools.core.spi.KnowledgeHelper) KieSession(org.kie.api.runtime.KieSession) JavaDialectRuntimeData(org.drools.core.rule.JavaDialectRuntimeData) InternalKnowledgeBase(org.drools.kiesession.rulebase.InternalKnowledgeBase) InternalKnowledgePackage(org.drools.core.definitions.InternalKnowledgePackage) Test(org.junit.Test)

Example 13 with ReteEvaluator

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());
}
Also used : ReteEvaluator(org.drools.core.common.ReteEvaluator) InternalFactHandle(org.drools.core.common.InternalFactHandle) FactHandle(org.kie.api.runtime.rule.FactHandle) WorkingMemory(org.drools.core.WorkingMemory) Activation(org.drools.core.spi.Activation) DeclarationMatcher(org.drools.mvel.asm.GeneratorHelper.DeclarationMatcher) LeftTuple(org.drools.core.reteoo.LeftTuple) MethodVisitor(org.mvel2.asm.MethodVisitor) GeneratorHelper.createInvokerClassGenerator(org.drools.mvel.asm.GeneratorHelper.createInvokerClassGenerator) Sink(org.drools.core.reteoo.Sink) KnowledgeHelper(org.drools.core.spi.KnowledgeHelper) Declaration(org.drools.core.rule.Declaration) InternalFactHandle(org.drools.core.common.InternalFactHandle) GeneratorHelper.matchDeclarationsToTuple(org.drools.mvel.asm.GeneratorHelper.matchDeclarationsToTuple) LeftTuple(org.drools.core.reteoo.LeftTuple) Tuple(org.drools.core.spi.Tuple) RuleTerminalNode(org.drools.core.reteoo.RuleTerminalNode)

Example 14 with ReteEvaluator

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);
    }
}
Also used : ReteEvaluator(org.drools.core.common.ReteEvaluator) InternalAgendaGroup(org.drools.core.common.InternalAgendaGroup) PropagationContext(org.drools.core.spi.PropagationContext) RuleTerminalNodeLeftTuple(org.drools.core.reteoo.RuleTerminalNodeLeftTuple)

Example 15 with ReteEvaluator

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);
    }
}
Also used : ReteEvaluator(org.drools.core.common.ReteEvaluator) InternalAgendaGroup(org.drools.core.common.InternalAgendaGroup) PropagationContext(org.drools.core.spi.PropagationContext) RuleTerminalNodeLeftTuple(org.drools.core.reteoo.RuleTerminalNodeLeftTuple)

Aggregations

ReteEvaluator (org.drools.core.common.ReteEvaluator)22 RuleImpl (org.drools.core.definitions.rule.impl.RuleImpl)9 KnowledgeHelper (org.drools.core.spi.KnowledgeHelper)8 InternalFactHandle (org.drools.core.common.InternalFactHandle)7 Consequence (org.drools.core.spi.Consequence)7 Tuple (org.drools.core.spi.Tuple)7 Test (org.junit.Test)7 ObjectInput (java.io.ObjectInput)5 ObjectOutput (java.io.ObjectOutput)5 ClassObjectType (org.drools.core.base.ClassObjectType)5 LeftTuple (org.drools.core.reteoo.LeftTuple)5 Pattern (org.drools.core.rule.Pattern)5 IOException (java.io.IOException)4 ArrayList (java.util.ArrayList)4 InternalKnowledgeBase (org.drools.kiesession.rulebase.InternalKnowledgeBase)4 DeclarationMatcher (org.drools.mvel.asm.GeneratorHelper.DeclarationMatcher)4 GeneratorHelper.createInvokerClassGenerator (org.drools.mvel.asm.GeneratorHelper.createInvokerClassGenerator)4 RuleTerminalNode (org.drools.core.reteoo.RuleTerminalNode)3 RuleTerminalNodeLeftTuple (org.drools.core.reteoo.RuleTerminalNodeLeftTuple)3 Declaration (org.drools.core.rule.Declaration)3