jadex.bdibpmn.BpmnPlanBodyInstance Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jadex-kernel-bdibpmn Show documentation
Show all versions of jadex-kernel-bdibpmn Show documentation
The Jadex BDI-BPMN kernel allows to use BPMN
workflow descriptions as alternative
description for BDI agent plans.
package jadex.bdibpmn;
import jadex.bdi.model.OAVBDIMetaModel;
import jadex.bdi.runtime.IBeliefbase;
import jadex.bdi.runtime.ICapability;
import jadex.bdi.runtime.IElement;
import jadex.bdi.runtime.IEventbase;
import jadex.bdi.runtime.IExpression;
import jadex.bdi.runtime.IExpressionbase;
import jadex.bdi.runtime.IGoal;
import jadex.bdi.runtime.IGoalbase;
import jadex.bdi.runtime.IInternalEvent;
import jadex.bdi.runtime.IMessageEvent;
import jadex.bdi.runtime.IParameter;
import jadex.bdi.runtime.IParameterSet;
import jadex.bdi.runtime.IPlan;
import jadex.bdi.runtime.IPlanListener;
import jadex.bdi.runtime.IPlanbase;
import jadex.bdi.runtime.IWaitqueue;
import jadex.bdi.runtime.PlanFailureException;
import jadex.bdi.runtime.impl.SFlyweightFunctionality;
import jadex.bdi.runtime.impl.flyweights.BeliefbaseFlyweight;
import jadex.bdi.runtime.impl.flyweights.CapabilityFlyweight;
import jadex.bdi.runtime.impl.flyweights.ElementFlyweight;
import jadex.bdi.runtime.impl.flyweights.EventbaseFlyweight;
import jadex.bdi.runtime.impl.flyweights.ExpressionFlyweight;
import jadex.bdi.runtime.impl.flyweights.ExpressionNoModel;
import jadex.bdi.runtime.impl.flyweights.ExpressionbaseFlyweight;
import jadex.bdi.runtime.impl.flyweights.ExternalAccessFlyweight;
import jadex.bdi.runtime.impl.flyweights.GoalFlyweight;
import jadex.bdi.runtime.impl.flyweights.GoalbaseFlyweight;
import jadex.bdi.runtime.impl.flyweights.InternalEventFlyweight;
import jadex.bdi.runtime.impl.flyweights.MessageEventFlyweight;
import jadex.bdi.runtime.impl.flyweights.ParameterFlyweight;
import jadex.bdi.runtime.impl.flyweights.ParameterSetFlyweight;
import jadex.bdi.runtime.impl.flyweights.PlanFlyweight;
import jadex.bdi.runtime.impl.flyweights.PlanbaseFlyweight;
import jadex.bdi.runtime.impl.flyweights.WaitqueueFlyweight;
import jadex.bdi.runtime.interpreter.BDIInterpreter;
import jadex.bdi.runtime.interpreter.GoalLifecycleRules;
import jadex.bdi.runtime.interpreter.InternalEventRules;
import jadex.bdi.runtime.interpreter.MessageEventRules;
import jadex.bdi.runtime.interpreter.OAVBDIFetcher;
import jadex.bdi.runtime.interpreter.OAVBDIRuntimeModel;
import jadex.bdibpmn.handler.EventIntermediateMessageActivityHandler;
import jadex.bdibpmn.handler.EventIntermediateRuleActicityHandler;
import jadex.bdibpmn.handler.EventIntermediateSignalActivityHandler;
import jadex.bdibpmn.handler.EventIntermediateTimerActivityHandler;
import jadex.bpmn.model.MActivity;
import jadex.bpmn.model.MBpmnModel;
import jadex.bpmn.model.MPool;
import jadex.bpmn.model.MSequenceEdge;
import jadex.bpmn.runtime.BpmnInterpreter;
import jadex.bpmn.runtime.ProcessThread;
import jadex.bpmn.runtime.handler.AbstractEventIntermediateTimerActivityHandler;
import jadex.bridge.IComponentIdentifier;
import jadex.bridge.IComponentListener;
import jadex.bridge.IComponentStep;
import jadex.bridge.IExternalAccess;
import jadex.bridge.service.IServiceContainer;
import jadex.bridge.service.IServiceProvider;
import jadex.bridge.service.types.clock.IClockService;
import jadex.commons.future.IFuture;
import jadex.javaparser.IExpressionParser;
import jadex.javaparser.IParsedExpression;
import jadex.javaparser.javaccimpl.JavaCCExpressionParser;
import jadex.rules.state.IOAVState;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
/**
* A BPMN instance that is executed as a plan body.
*/
public class BpmnPlanBodyInstance extends BpmnInterpreter
{
//-------- static part --------
/** Identifier for an undefined pool (e.g. when no 'aborted' pool is specified). */
protected static String POOL_UNDEFINED = "undefined-pool";
/** The activity execution handlers (activity type -> handler). */
public static final Map PLAN_ACTIVITY_HANDLERS;
static
{
Map defhandlers = new HashMap(BpmnInterpreter.DEFAULT_ACTIVITY_HANDLERS);
defhandlers.put(MBpmnModel.EVENT_START_TIMER, new EventIntermediateTimerActivityHandler());
defhandlers.put(MBpmnModel.EVENT_INTERMEDIATE_TIMER, new EventIntermediateTimerActivityHandler());
defhandlers.put(MBpmnModel.EVENT_INTERMEDIATE_MESSAGE, new EventIntermediateMessageActivityHandler());
defhandlers.put(MBpmnModel.EVENT_INTERMEDIATE_RULE, new EventIntermediateRuleActicityHandler());
defhandlers.put(MBpmnModel.EVENT_INTERMEDIATE_SIGNAL, new EventIntermediateSignalActivityHandler());
PLAN_ACTIVITY_HANDLERS = Collections.unmodifiableMap(defhandlers);
}
//-------- attributes --------
/** The bdi interpreter. */
protected BDIInterpreter interpreter;
/** The last plan lifecycle state. */
protected String lifecyclestate;
/** The wait times of waiting threads (thread -> absolute timepoint). */
protected Map waittimes;
/** The runtime plan element. */
protected Object rplan;
/** The runtime capability. */
protected Object rcapa ;
/** The state. */
protected IOAVState state;
//-------- constructors --------
/**
* Create a new BPMN process instance using default handler.
* @param model The BMPN process model.
*/
public BpmnPlanBodyInstance(MBpmnModel model, final BDIInterpreter interpreter,
final Object rcapa, final Object rplan)
{
super(interpreter.getAgentAdapter(), model, null, null, interpreter.getParent(), PLAN_ACTIVITY_HANDLERS,
null, new OAVBDIFetcher(interpreter.getState(), rcapa, rplan),
interpreter.getCMS(), interpreter.getClockService(), interpreter.getMessageService(),
interpreter.getServiceContainer());
this.interpreter = interpreter;
this.state = interpreter.getState();
this.rcapa = rcapa;
this.rplan = rplan;
// this.creationtime = interpreter.getCreationTime();
// todo:
// this.setAdapter(new IBpmnExecutor()
// {
// public void wakeUp()
// {
// if(interpreter.isExternalThread())
// {
//// Thread.dumpStack();
// interpreter.invokeLater(new Runnable()
// {
// public void run()
// {
// if(state.containsObject(rplan) && !OAVBDIRuntimeModel.PLANPROCESSINGTATE_FINISHED.equals(state.getAttributeValue(rplan, OAVBDIRuntimeModel.plan_has_processingstate)))
// {
// String lane = getLane(getLastState());
// if(!LANE_UNDEFINED.equals(lane) && isReady(null, lane))
// {
// // todo: event?!
// EventProcessingRules.schedulePlanInstanceCandidate(state, null, rplan, rcapa);
//// state.setAttributeValue(rplan, OAVBDIRuntimeModel.plan_has_processingstate, OAVBDIRuntimeModel.PLANPROCESSINGTATE_READY);
// }
// }
// }
// });
// }
// else
// {
// if(state.containsObject(rplan) && !OAVBDIRuntimeModel.PLANPROCESSINGTATE_FINISHED.equals(state.getAttributeValue(rplan, OAVBDIRuntimeModel.plan_has_processingstate)))
// {
// String lane = getLane(getLastState());
// if(!LANE_UNDEFINED.equals(lane) && isReady(null, lane))
// {
// // todo: event?!
// EventProcessingRules.schedulePlanInstanceCandidate(state, null, rplan, rcapa);
//// state.setAttributeValue(rplan, OAVBDIRuntimeModel.plan_has_processingstate, OAVBDIRuntimeModel.PLANPROCESSINGTATE_READY);
// }
// }
// }
// }
// });
}
//-------- methods --------
/**
* Get the last plan lifecycle state.
* @return The plan lifecycle state.
*/
public String getLastState()
{
return lifecyclestate;
}
/**
* Set the plan lifecycle state.
* @param state The plan lifecycle state.
*/
public void setLastState(String state)
{
this.lifecyclestate = state;
}
/**
* Add a timer for a thread.
* @param thread The process thread that should wait.
* @param duration The duration to wait for.
*/
public void addTimer(final ProcessThread thread, final long duration)
{
assert duration==EventIntermediateTimerActivityHandler.TICK_TIMER || duration>=0;
if(waittimes==null)
waittimes = new HashMap();
// how to support tick timer?
if(duration==EventIntermediateTimerActivityHandler.TICK_TIMER)
throw new UnsupportedOperationException("Tick timers for bdi-bpmn have to be implemented.");
// todo: check if asynchronous handling of waittimes is a problem?
IClockService clock = interpreter.getClockService();
Long ret = new Long(clock.getTime()+duration);
waittimes.put(thread, ret);
// SServiceProvider.getService(interpreter.getServiceProvider(), IClockService.class)
// .addResultListener(interpreter.createResultListener(new DefaultResultListener()
// {
// public void resultAvailable(Object source, Object result)
// {
// IClockService clock = (IClockService)result;
// Long ret = new Long(clock.getTime()+duration);
// waittimes.put(thread, ret);
// }
// }));
}
/**
* Remove a timer for a thread.
* @param thread The process thread that should wait.
* @param duration The duration to wait for.
*/
public void removeTimer(ProcessThread thread)
{
if(waittimes!=null)
waittimes.remove(thread);
}
/**
* Update the waiting threads according to the wakeup reason (dispatched element).
* The corresponding waiting activity/thread is notified.
*/
public void updateWaitingThreads()
{
if(waittimes!=null)
{
// IClockService clock = (IClockService)interpreter.getServiceProvider().getService(IClockService.class);
IClockService clock = interpreter.getClockService();
for(Iterator it=waittimes.keySet().iterator(); it.hasNext(); )
{
ProcessThread thread = (ProcessThread)it.next();
if(((Number)waittimes.get(thread)).longValue()<=clock.getTime())
{
it.remove();
assert thread.isWaiting();
BpmnPlanBodyInstance.this.notify(thread.getActivity(), thread, AbstractEventIntermediateTimerActivityHandler.TIMER_EVENT);
}
}
}
Object dispelem = state.getAttributeValue(rplan, OAVBDIRuntimeModel.plan_has_dispatchedelement);
// System.out.println("dispatched: "+dispelem);
if(dispelem!=null)
{
for(Iterator it=context.getAllThreads().iterator(); it.hasNext(); )
{
ProcessThread thread = (ProcessThread)it.next();
try
{
if(thread.isWaiting() && thread.getWaitFilter().filter(dispelem))
{
BpmnPlanBodyInstance.this.notify(thread.getActivity(), thread, getFlyweight(dispelem));
}
}
catch(Exception e)
{
// just catch filter exceptions.
}
}
}
}
/**
* Get the current timeout of the process, i.e. the
* remaining time of the closest due intermediate timer event.
* @return The current timeout or -1 for no timeout.
*/
public long getTimeout()
{
long mindur = -1;
if(waittimes!=null)
{
String pool = getPool(getLastState());
if(!POOL_UNDEFINED.equals(pool))
{
IClockService clock = interpreter.getClockService();
// IClockService clock = (IClockService)interpreter.getServiceProvider().getService(IClockService.class);
for(Iterator it=waittimes.keySet().iterator(); it.hasNext(); )
{
ProcessThread thread = (ProcessThread) it.next();
if(thread.belongsTo(pool, null))
{
long time = Math.max(((Number)waittimes.get(thread)).longValue()-clock.getTime(), 0);
mindur = mindur==-1 ? time : time