Skip to content

Commit

Permalink
[DROOLS-141][BZ-999491] register custom listners on StatelessKieSessi…
Browse files Browse the repository at this point in the history
…on at each execution
  • Loading branch information
mariofusco committed Aug 23, 2013
1 parent 59fc7ab commit 770d130
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 35 deletions.
Expand Up @@ -41,6 +41,7 @@
import org.kie.api.definition.type.Position;
import org.kie.api.runtime.KieSession;
import org.kie.api.KieBaseConfiguration;
import org.kie.api.runtime.StatelessKieSession;
import org.kie.internal.KnowledgeBase;
import org.kie.internal.KnowledgeBaseFactory;
import org.kie.internal.builder.KnowledgeBuilder;
Expand Down Expand Up @@ -2567,4 +2568,66 @@ public void testAutomaticallySwitchFromReteOOToPhreak() {
KieSession ksession = kbase.newKieSession();
ksession.fireAllRules();
}

@Test
public void testListnersOnStatlessKieSession() {
// DROOLS-141
// BZ-999491
String str =
"rule R when\n" +
" String()\n" +
"then\n" +
"end\n";

KnowledgeBase kbase = loadKnowledgeBaseFromString(str);
StatelessKieSession ksession = kbase.newStatelessKnowledgeSession();

final List<String> firings = new ArrayList<String>();

AgendaEventListener agendaEventListener = new AgendaEventListener() {
public void matchCreated(org.kie.api.event.rule.MatchCreatedEvent event) {
}

public void matchCancelled(org.kie.api.event.rule.MatchCancelledEvent event) {
}

public void beforeMatchFired(org.kie.api.event.rule.BeforeMatchFiredEvent event) {
}

public void afterMatchFired(org.kie.api.event.rule.AfterMatchFiredEvent event) {
firings.add("Fired!");
}

public void agendaGroupPopped(org.kie.api.event.rule.AgendaGroupPoppedEvent event) {
}

public void agendaGroupPushed(org.kie.api.event.rule.AgendaGroupPushedEvent event) {
}

public void beforeRuleFlowGroupActivated(org.kie.api.event.rule.RuleFlowGroupActivatedEvent event) {
}

public void afterRuleFlowGroupActivated(org.kie.api.event.rule.RuleFlowGroupActivatedEvent event) {
}

public void beforeRuleFlowGroupDeactivated(org.kie.api.event.rule.RuleFlowGroupDeactivatedEvent event) {
}

public void afterRuleFlowGroupDeactivated(org.kie.api.event.rule.RuleFlowGroupDeactivatedEvent event) {
}
};

ksession.addEventListener(agendaEventListener);

ksession.execute("1");
ksession.execute("2");

assertEquals(2, firings.size());

ksession.removeEventListener(agendaEventListener);

ksession.execute("3");

assertEquals(2, firings.size());
}
}
Expand Up @@ -19,8 +19,10 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;

import org.drools.core.SessionConfiguration;
import org.drools.core.base.MapGlobalResolver;
Expand Down Expand Up @@ -71,6 +73,7 @@ public class StatelessKnowledgeSessionImpl
/** The event mapping */
public Map<WorkingMemoryEventListener, WorkingMemoryEventListenerWrapper> mappedWorkingMemoryListeners;
public Map<AgendaEventListener, AgendaEventListenerWrapper> mappedAgendaListeners;
public Set<ProcessEventListener> cachedProcessEventListener;

/** The event support */
public AgendaEventSupport agendaEventSupport = new AgendaEventSupport();
Expand Down Expand Up @@ -131,18 +134,8 @@ public StatefulKnowledgeSession newWorkingMemory() {
((Globals) wm.getGlobalResolver()).setDelegate(this.sessionGlobals);
if (!initialized) {
// copy over the default generated listeners that are used for internal stuff once
for (org.drools.core.event.AgendaEventListener listener : wm.getAgendaEventSupport().getEventListeners()) {
this.agendaEventSupport.addEventListener(listener);
}
for (org.drools.core.event.WorkingMemoryEventListener listener : wm.getWorkingMemoryEventSupport().getEventListeners()) {
this.workingMemoryEventSupport.addEventListener(listener);
}
InternalProcessRuntime processRuntime = wm.getProcessRuntime();
if ( processRuntime != null ) {
for ( ProcessEventListener listener : processRuntime.getProcessEventListeners() ) {
this.processEventSupport.addEventListener( listener );
}
}
registerSystemListeners(wm);
registerCustomListeners();
initialized = true;
}
wm.setAgendaEventSupport( this.agendaEventSupport );
Expand Down Expand Up @@ -173,15 +166,46 @@ public StatefulKnowledgeSession newWorkingMemory() {
}
}

private void registerSystemListeners(AbstractWorkingMemory wm) {
for (org.drools.core.event.AgendaEventListener listener : wm.getAgendaEventSupport().getEventListeners()) {
this.agendaEventSupport.addEventListener(listener);
}
for (org.drools.core.event.WorkingMemoryEventListener listener : wm.getWorkingMemoryEventSupport().getEventListeners()) {
this.workingMemoryEventSupport.addEventListener(listener);
}
InternalProcessRuntime processRuntime = wm.getProcessRuntime();
if ( processRuntime != null ) {
for ( ProcessEventListener listener : processRuntime.getProcessEventListeners() ) {
this.processEventSupport.addEventListener( listener );
}
}
}

private void registerCustomListeners() {
if ( mappedAgendaListeners != null ) {
for (AgendaEventListenerWrapper agendaListener : mappedAgendaListeners.values()) {
this.agendaEventSupport.addEventListener( agendaListener );
}
}
if ( mappedWorkingMemoryListeners != null ) {
for (WorkingMemoryEventListenerWrapper wmListener : mappedWorkingMemoryListeners.values()) {
this.workingMemoryEventSupport.addEventListener( wmListener );
}
}
if ( cachedProcessEventListener != null ) {
for (ProcessEventListener processListener : cachedProcessEventListener) {
this.processEventSupport.addEventListener( processListener );
}
}
}

public void addEventListener(AgendaEventListener listener) {
if ( this.mappedAgendaListeners == null ) {
this.mappedAgendaListeners = new IdentityHashMap<AgendaEventListener, AgendaEventListenerWrapper>();
}

AgendaEventListenerWrapper wrapper = new AgendaEventListenerWrapper( listener );
this.mappedAgendaListeners.put( listener,
wrapper );
this.agendaEventSupport.addEventListener( wrapper );
this.mappedAgendaListeners.put(listener, wrapper);
}

public Collection<AgendaEventListener> getAgendaEventListeners() {
Expand All @@ -193,12 +217,10 @@ public Collection<AgendaEventListener> getAgendaEventListeners() {
}

public void removeEventListener(AgendaEventListener listener) {
if ( this.mappedAgendaListeners == null ) {
this.mappedAgendaListeners = new IdentityHashMap<AgendaEventListener, AgendaEventListenerWrapper>();
if ( this.mappedAgendaListeners != null ) {
AgendaEventListenerWrapper wrapper = this.mappedAgendaListeners.remove( listener );
this.agendaEventSupport.removeEventListener( wrapper );
}

AgendaEventListenerWrapper wrapper = this.mappedAgendaListeners.remove( listener );
this.agendaEventSupport.removeEventListener( wrapper );
}

public void addEventListener(WorkingMemoryEventListener listener) {
Expand All @@ -207,18 +229,14 @@ public void addEventListener(WorkingMemoryEventListener listener) {
}

WorkingMemoryEventListenerWrapper wrapper = new WorkingMemoryEventListenerWrapper( listener );
this.mappedWorkingMemoryListeners.put( listener,
wrapper );
this.workingMemoryEventSupport.addEventListener( wrapper );
this.mappedWorkingMemoryListeners.put( listener, wrapper );
}

public void removeEventListener(WorkingMemoryEventListener listener) {
if ( this.mappedWorkingMemoryListeners == null ) {
this.mappedWorkingMemoryListeners = new IdentityHashMap<WorkingMemoryEventListener, WorkingMemoryEventListenerWrapper>();
if ( this.mappedWorkingMemoryListeners != null ) {
WorkingMemoryEventListenerWrapper wrapper = this.mappedWorkingMemoryListeners.remove( listener );
this.workingMemoryEventSupport.removeEventListener( wrapper );
}

WorkingMemoryEventListenerWrapper wrapper = this.mappedWorkingMemoryListeners.remove( listener );
this.workingMemoryEventSupport.removeEventListener( wrapper );
}

public Collection<WorkingMemoryEventListener> getWorkingMemoryEventListeners() {
Expand All @@ -230,14 +248,20 @@ public Collection<WorkingMemoryEventListener> getWorkingMemoryEventListeners() {
}

public void addEventListener(ProcessEventListener listener) {
this.processEventSupport.addEventListener( listener );
if ( this.cachedProcessEventListener == null ) {
this.cachedProcessEventListener = new HashSet<ProcessEventListener>();
}
this.cachedProcessEventListener.add(listener);
}

public Collection<ProcessEventListener> getProcessEventListeners() {
return this.processEventSupport.getEventListeners();
}

public void removeEventListener(ProcessEventListener listener) {
if (this.cachedProcessEventListener != null) {
this.cachedProcessEventListener.remove(listener);
}
this.processEventSupport.removeEventListener( listener );

This comment has been minimized.

Copy link
@etirelli

etirelli Aug 26, 2013

Contributor

Mario, is this correct? This method is not symmetric to the other removeEventListener() methods... looks odd...

This comment has been minimized.

Copy link
@mariofusco

mariofusco Aug 26, 2013

Author Contributor

Yes, I think this should be correct. The WorkingMemory and the Agenda EventListener are wrapped in an adapter and indexes in 2 Maps having as keys the original listeners. Conversely the ProcessEventListeners don't need to be adapted so they weren't stored at all. I added a Set to keep track of them and here I am just removing one of them from that Set when it is deregistered. Am I missing something?

}

Expand Down Expand Up @@ -309,8 +333,7 @@ public <T> T execute(Command<T> command) {
}
} finally {
((StatefulKnowledgeSessionImpl) ksession).session.endBatchExecution();
ksession.dispose();
ksession = null;
dispose();
}
}

Expand All @@ -320,8 +343,7 @@ public void execute(Object object) {
ksession.insert( object );
ksession.fireAllRules();
} finally {
ksession.dispose();
ksession = null;
dispose();
}
}

Expand All @@ -333,13 +355,31 @@ public void execute(Iterable objects) {
}
ksession.fireAllRules();
} finally {
ksession.dispose();
ksession = null;
dispose();
}
}

public Environment getEnvironment() {
return environment;
}

protected void dispose( ) {
AbstractWorkingMemory wm = (AbstractWorkingMemory) ((StatefulKnowledgeSessionImpl) ksession).getInternalWorkingMemory();

for ( org.drools.core.event.AgendaEventListener listener : wm.getAgendaEventSupport().getEventListeners() ) {
this.agendaEventSupport.removeEventListener( listener );
}
for ( org.drools.core.event.WorkingMemoryEventListener listener: wm.getWorkingMemoryEventSupport().getEventListeners() ) {
this.workingMemoryEventSupport.removeEventListener( listener );
}
InternalProcessRuntime processRuntime = wm.getProcessRuntime();
if ( processRuntime != null ) {
for ( ProcessEventListener listener: processRuntime.getProcessEventListeners() ) {
this.processEventSupport.removeEventListener( listener );
}
}
initialized = false;
ksession.dispose();
ksession = null;
}
}

0 comments on commit 770d130

Please sign in to comment.