All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jadex.bdibpmn.BpmnPlanBodyInstance Maven / Gradle / Ivy

Go to download

The Jadex BDI-BPMN kernel allows to use BPMN workflow descriptions as alternative description for BDI agent plans.

There is a newer version: 2.4
Show newest version
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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy