package org.jboss.seam.drools;
import java.io.Serializable;
import org.drools.RuleBase;
import org.drools.StatefulSession;
import org.drools.spi.GlobalResolver;
import org.drools.event.AgendaEventListener;
import org.drools.event.RuleFlowEventListener;
import org.drools.event.WorkingMemoryEventListener;
import org.jboss.seam.Component;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Destroy;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Unwrap;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.core.Mutable;
import org.jboss.seam.core.Expressions.ValueExpression;
import org.jboss.seam.log.LogProvider;
import org.jboss.seam.log.Logging;
/**
* A conversation-scoped Drools WorkingMemory for a named RuleBase
*
* @author Gavin King
* @author Tihomir Surdilovic
*
*/
@Scope(ScopeType.CONVERSATION)
@BypassInterceptors
public class ManagedWorkingMemory implements Mutable, Serializable
{
private static final long serialVersionUID = -1746942080571374743L;
private static final LogProvider log = Logging.getLogProvider(ManagedWorkingMemory.class);
private String ruleBaseName;
private String[] eventListeners;
private StatefulSession statefulSession;
private ValueExpression<RuleBase> ruleBase;
public boolean clearDirty()
{
return true;
}
/**
* The name of a Seam context variable holding an
* instance of org.drools.RuleBase
*
* @return a context variable name
* @deprecated
*/
public String getRuleBaseName()
{
return ruleBaseName;
}
/**
* The name of a Seam context variable holding an
* instance of org.drools.RuleBase
*
* @param ruleBaseName a context variable name
* @deprecated
*/
public void setRuleBaseName(String ruleBaseName)
{
this.ruleBaseName = ruleBaseName;
}
@Unwrap
public StatefulSession getStatefulSession()
{
if (statefulSession==null)
{
statefulSession = getRuleBaseFromValueBinding().newStatefulSession();
statefulSession.setGlobalResolver( createGlobalResolver( statefulSession.getGlobalResolver() ) );
if(eventListeners != null) {
setEventListeners(statefulSession);
}
}
return statefulSession;
}
private void setEventListeners(StatefulSession statefulSession)
{
if(eventListeners != null) {
for(String eventListener : eventListeners)
{
log.debug("adding eventListener: " + eventListener);
try
{
Class eventListenerClass = Class.forName(eventListener);
Object eventListenerObject = eventListenerClass.newInstance();
if(eventListenerObject instanceof WorkingMemoryEventListener)
{
statefulSession.addEventListener((WorkingMemoryEventListener) eventListenerObject);
}
else if(eventListenerObject instanceof AgendaEventListener)
{
statefulSession.addEventListener((AgendaEventListener) eventListenerObject);
}
else if(eventListenerObject instanceof RuleFlowEventListener)
{
statefulSession.addEventListener((RuleFlowEventListener) eventListenerObject);
}
else
{
log.debug("event Listener " + eventListener + " is not of valid type - bypassing.");
}
}
catch (Exception e)
{
log.error("error adding event listener " + eventListener + " - bypassing.");
}
}
}
}
protected RuleBase getRuleBaseFromValueBinding()
{
RuleBase ruleBase;
if (this.ruleBase!=null)
{
ruleBase = this.ruleBase.getValue();
}
else if (ruleBaseName!=null)
{
//deprecated stuff
ruleBase = (RuleBase) Component.getInstance(ruleBaseName, true);
}
else
{
throw new IllegalStateException("No RuleBase");
}
if (ruleBase==null)
{
throw new IllegalStateException("RuleBase not found: " + ruleBaseName);
}
return ruleBase;
}
protected GlobalResolver createGlobalResolver(GlobalResolver delegate)
{
return new SeamGlobalResolver(delegate);
}
@Destroy
public void destroy()
{
statefulSession.dispose();
}
public ValueExpression<RuleBase> getRuleBase()
{
return ruleBase;
}
public void setRuleBase(ValueExpression<RuleBase> ruleBase)
{
this.ruleBase = ruleBase;
}
public String[] getEventListeners()
{
return eventListeners;
}
public void setEventListeners(String[] eventListeners)
{
this.eventListeners = eventListeners;
}
}