if (statefulSession != null && !continueState)
{
final String ssid = getId(statefulSession, statefulSessionCount);
final StatefulKnowledgeSession disposedStatefulSession = statefulSession;
final Thread haltedStatefulFireUntilHaltThread = statefulFireUntilHaltThread;
final KnowledgeRuntimeLogger closedStatefulRuntimeLogger = statefulRuntimeLogger;
statefulSession = null;
statefulFireUntilHaltThread = null;
statefulRuntimeLogger = null;
// Maybe halt the session
if (haltedStatefulFireUntilHaltThread != null)
{
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("calling halt on stateful session [" + ssid + "] - no continue set");
}
disposedStatefulSession.halt();
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("joining thread [" + haltedStatefulFireUntilHaltThread.getName() + "] for stateful session [" + ssid + "]");
}
try
{
haltedStatefulFireUntilHaltThread.join();
}
catch (InterruptedException ie)
{
LOGGER.error("interrupted thread [" + haltedStatefulFireUntilHaltThread.getName() + "] for stateful session [" + ssid + "]", ie);
}
}
// Always dispose the session
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("calling dispose() on stateful session [" + ssid + "] - no continue set");
}
disposedStatefulSession.dispose();
// Maybe close the logger
if (closedStatefulRuntimeLogger != null)
{
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("calling close() on runtime logger [" + getId(closedStatefulRuntimeLogger, statefulSessionCount) + "] - no continue set");
}
closedStatefulRuntimeLogger.close();
}
}
final String ssid;
final boolean isStatefulSessionNew;
if (statefulSession == null)
{
isStatefulSessionNew = true;
KnowledgeSessionConfiguration statefulSessionConfiguration = KnowledgeBaseFactory.newKnowledgeSessionConfiguration();
setClockType(ruleInfo, statefulSessionConfiguration);
statefulSession = ruleBase.newStatefulKnowledgeSession(statefulSessionConfiguration, EnvironmentFactory.newEnvironment());
ssid = getId(statefulSession, statefulSessionCount);
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("created new stateful session [" + ssid + "]");
}
setChannels(ruleInfo, statefulSession);
statefulRuntimeLogger = getRuntimeLogger(ruleInfo, statefulSession);
if (statefulRuntimeLogger != null && LOGGER.isDebugEnabled())
{
LOGGER.debug("created new runtime logger [" + getId(statefulRuntimeLogger, statefulSessionCount) + "]");
}
}
else
{
isStatefulSessionNew = false;
ssid = getId(statefulSession, statefulSessionCount);
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("reusing old stateful session [" + ssid + "]");
}
}
try
{
final Map<String, Object> globals = ruleInfo.getGlobals();
if (globals != null)
{
if (LOGGER.isTraceEnabled())
{
LOGGER.trace("calling setGlobal(String,Object) on stateful session [" + ssid + "] for each global");
}
final Set<Entry<String, Object>> entrySet = globals.entrySet();
for(Entry<String, Object> entry : entrySet)
{
statefulSession.setGlobal( entry.getKey(), entry.getValue() );
}
}
if (LOGGER.isTraceEnabled())
{
LOGGER.trace("inserting Message on stateful session [" + ssid + "]");
}
// Always insert the ESB Message object.
InternalFactHandle handle = (InternalFactHandle)statefulSession.insert(message);
if (handle.isEvent() && LOGGER.isDebugEnabled())
{
EventFactHandle ef = (EventFactHandle)handle;
LOGGER.debug("event [" + ef.getObject().getClass().getName() + "], startTimeStamp [" + ef.getStartTimestamp() + "]");
}
// Always insert the default facts (into the main WorkingMemory; no entry-point specified)
final List<Object> defaultFacts = ruleInfo.getDefaultFacts();
if (defaultFacts != null)
{
if (LOGGER.isTraceEnabled())
{
LOGGER.trace("calling insert(Object) on stateful session [" + ssid + "] for each default fact");
}
for(Object object : defaultFacts)
{
statefulSession.insert(object);
}
}
// Maybe insert entry point facts (into a named WorkingMemoryEntryPoint)
final Map<String,List<Object>> facts = ruleInfo.getFacts();
if (facts != null)
{
if (LOGGER.isTraceEnabled())
{
LOGGER.trace("calling insert(Object) on stateful session [" + ssid + "] for each entry point fact");
}
for(Entry<String, List<Object>> entry : facts.entrySet())
{
String entryPointName = entry.getKey();
// Insert objects that have explicitly specified an entry-point.
WorkingMemoryEntryPoint wmep = statefulSession.getWorkingMemoryEntryPoint(entryPointName);
if (wmep == null)
{
throw new RuleServiceException("The entry-point '" + entryPointName + "' was not found in the current stateful session. Please double check your rules source");
}
for(Object fact : entry.getValue())
{
wmep.insert(fact);
}
}
}
// Fire stateful rules.
if (!fireUntilHalt)
{
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("calling fireAllRules() on stateful session [" + ssid + "]");
}
statefulSession.fireAllRules();
}
else if (isStatefulSessionNew)
{
final String threadName = new StringBuilder()
.append(getClass().getSimpleName())
.append(":fireUntilHalt(")
.append(ssid)
.append(")")
.toString();
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("spawning fireUntilHalt() on stateful session [" + ssid + "] in thread [" + threadName + "]");
}
final ClassLoader goodClassLoader = Thread.currentThread().getContextClassLoader();
statefulFireUntilHaltThread = new Thread(new Runnable() {
public void run() {
Thread thread = Thread.currentThread();
ClassLoader origClassLoader = thread.getContextClassLoader();
thread.setContextClassLoader(goodClassLoader);
try {
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("calling fireUntilHalt() on stateful session [" + ssid + "] in thread [" + threadName + "]");
}
statefulSession.fireUntilHalt();
} catch (NullPointerException npe) {
LOGGER.warn("fireUntilHalt() not called on stateful session [" + ssid + "] in thread [" + threadName + "] - already halt()ed and dispose()d: " + npe.getMessage());
} finally {
thread.setContextClassLoader(origClassLoader);
}
}
});
statefulFireUntilHaltThread.setName(threadName);
statefulFireUntilHaltThread.setDaemon(true);
statefulFireUntilHaltThread.start();
}
else if (LOGGER.isDebugEnabled())
{
LOGGER.debug("rule firing unnecessary on stateful session [" + ssid + "] - was initially fireUntilHalt()");
}
}
finally
{
if (dispose)
{
final StatefulKnowledgeSession disposedStatefulSession = statefulSession;
final Thread haltedStatefulFireUntilHaltThread = statefulFireUntilHaltThread;
final KnowledgeRuntimeLogger closedStatefulRuntimeLogger = statefulRuntimeLogger;
statefulSession = null;
statefulFireUntilHaltThread = null;
statefulRuntimeLogger = null;
// Maybe halt the session
if (haltedStatefulFireUntilHaltThread != null)
{
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("calling halt() on stateful session [" + ssid + "]");
}
disposedStatefulSession.halt();
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("joining thread [" + haltedStatefulFireUntilHaltThread.getName() + "] for stateful session [" + ssid + "]");
}
try
{
haltedStatefulFireUntilHaltThread.join();
}
catch (InterruptedException ie)
{
LOGGER.error("interrupted thread [" + haltedStatefulFireUntilHaltThread.getName() + "] for stateful session [" + ssid + "]", ie);
}
}
// Always dispose the session
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("calling dispose() on stateful session [" + ssid + "]");
}
disposedStatefulSession.dispose();
// Maybe close the logger
if (closedStatefulRuntimeLogger != null)
{
if (LOGGER.isDebugEnabled())
{
LOGGER.debug("calling close() on runtime logger [" + getId(closedStatefulRuntimeLogger, statefulSessionCount) + "]");
}
closedStatefulRuntimeLogger.close();
}
}
}
}
finally