Drools-Connection


Quelle : https://www.jboss.org

Der eigentliche Kern von Drools ist die Rules-Engine, Drools-Expert genannt. Damit kann man die eigentlichen Regeln schreiben und anwenden. Bis Version 4 gab es hier die RuleBase, die man angewendet hat, um eine Art Container zu bauen, in welchem verschiedene Regel-Packages liegen. Ab Version 5 sieht die Erstellung einer KnowledgeBase und deren Anbindung ein wenig anders aus:

 private KnowledgeBase createKnowledgeBase() {
        KnowledgeBuilder kBuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
        kBuilder.add(ResourceFactory.newFileResource("x:\myRule.drl"), ResourceType.DRL);
        KnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase();
        kBase.addKnowledgePackages(kBuilder.getKnowledgePackages());
        return kBase;
 }

Es wird also eine Base erstellt, welche nur eine einzelne drl-Datei einbindet: myRule.drl Als nächster Schritt wird die Base benutzt, um daraus eine Session zu erstellen, welche dann den execute-Aufruf bekommt. Ich beschränke mich hierbei einfach auf die Stateless-Session :

The StatelessSession wraps the WorkingMemory, instead of extending it, its main focus is on decision service type scenarios. The api is reduced for the problem domain and is thus much simpler; which in turn can make maintenance of those services easier. The RuleBase never retains a reference to the StatelessSession, thus dispose() is not needed, and they only have an execute() method that takes an object, an array of objects or a collection of objects – there is no insert or fireAllRules. The execute method iterates the objects inserting each and calling fireAllRules() at the end; session finished. Should the session need access to any results information they can use the executeWithResults method, which returns a StatelessSessionResult. The reason for this is in remoting situations you do not always want the return payload, so this way its optional.

 

public void executeMyRulesOnObjectList(List<object> objects) throws DroolsParserException, IOException {
        KnowledgeBase kBase = createKnowledgeBase();
        StatelessKnowledgeSession session = kBase.newStatelessKnowledgeSession();
        session.addEventListener(getCustomWorkingMemoryListener());
        session.execute(objects);
    }

In meiner Regel möchte ich ein neues Fact per Insert einfügen und da es sich hierbei um eine stateless Session handelt, müssen wir den Working-Memory, welcher durch die Session nur gewrapped wird, durch einen eigenen Listener überwachen:

private WorkingMemoryEventListener getCustomWorkingMemoryListener() {
        WorkingMemoryEventListener listener = new WorkingMemoryEventListener() {

            public void objectUpdated(ObjectUpdatedEvent event) {
                // Do sth. with the updated object : event.getObject();
            }

            public void objectRetracted(ObjectRetractedEvent event) {
                // Do sth. with the retracted object : event.getObject();
            }

            public void objectInserted(ObjectInsertedEvent event) {
                // Do sth. with the inserted object : event.getObject();
            }
        };
        return listener;
    }

Dabei muss das zu bearbeitende Object ein Feld in der umgebenden Klasse sein!