Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
jadex.bdiv3.runtime.impl.RPlan Maven / Gradle / Ivy
Go to download
BDIV3 Kernel that supports annotated POJOs and uses byte code manipulation for performance improvements.
package jadex.bdiv3.runtime.impl;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jadex.bdiv3.actions.AdoptGoalAction;
import jadex.bdiv3.actions.ExecutePlanStepAction;
import jadex.bdiv3.annotation.Plan;
import jadex.bdiv3.features.impl.IInternalBDIAgentFeature;
import jadex.bdiv3.model.IBDIModel;
import jadex.bdiv3.model.MBody;
import jadex.bdiv3.model.MCapability;
import jadex.bdiv3.model.MConfigParameterElement;
import jadex.bdiv3.model.MGoal;
import jadex.bdiv3.model.MInternalEvent;
import jadex.bdiv3.model.MMessageEvent;
import jadex.bdiv3.model.MParameter;
import jadex.bdiv3.model.MPlan;
import jadex.bdiv3.model.MPlanParameter;
import jadex.bdiv3.model.MTrigger;
import jadex.bdiv3.runtime.ChangeEvent;
import jadex.bdiv3.runtime.IGoal;
import jadex.bdiv3.runtime.IGoal.GoalProcessingState;
import jadex.bdiv3.runtime.IPlan;
import jadex.bdiv3.runtime.WaitAbstraction;
import jadex.bdiv3x.runtime.ICandidateInfo;
import jadex.bdiv3x.runtime.IElement;
import jadex.bdiv3x.runtime.RInternalEvent;
import jadex.bdiv3x.runtime.RMessageEvent;
import jadex.bridge.IComponentStep;
import jadex.bridge.IConditionalComponentStep;
import jadex.bridge.IInternalAccess;
import jadex.bridge.component.IExecutionFeature;
import jadex.bridge.component.IMonitoringComponentFeature;
import jadex.bridge.service.RequiredServiceInfo;
import jadex.bridge.service.component.ComponentSuspendable;
import jadex.bridge.service.search.SServiceProvider;
import jadex.bridge.service.types.clock.IClockService;
import jadex.bridge.service.types.clock.ITimedObject;
import jadex.bridge.service.types.clock.ITimer;
import jadex.bridge.service.types.monitoring.IMonitoringEvent;
import jadex.bridge.service.types.monitoring.IMonitoringService.PublishEventLevel;
import jadex.bridge.service.types.monitoring.IMonitoringService.PublishTarget;
import jadex.bridge.service.types.monitoring.MonitoringEvent;
import jadex.commons.ICommand;
import jadex.commons.IFilter;
import jadex.commons.IValueFetcher;
import jadex.commons.SUtil;
import jadex.commons.Tuple2;
import jadex.commons.concurrent.TimeoutException;
import jadex.commons.future.DefaultResultListener;
import jadex.commons.future.DelegationResultListener;
import jadex.commons.future.Future;
import jadex.commons.future.IFuture;
import jadex.commons.future.IResultListener;
import jadex.commons.future.ITerminableFuture;
import jadex.javaparser.SimpleValueFetcher;
import jadex.micro.annotation.Agent;
import jadex.rules.eca.ChangeInfo;
import jadex.rules.eca.Event;
import jadex.rules.eca.EventType;
import jadex.rules.eca.IAction;
import jadex.rules.eca.ICondition;
import jadex.rules.eca.IEvent;
import jadex.rules.eca.IRule;
import jadex.rules.eca.Rule;
/**
* Runtime element of a plan.
*/
public class RPlan extends RParameterElement implements IPlan, IInternalPlan
{
/** The rplans for plan threads. */
public static final ThreadLocal RPLANS = new ThreadLocal();
//-------- plan states --------
public static enum PlanProcessingState
{
READY,
RUNNING,
WAITING,
// GOALCLEANUP,
// FINISHED,
};
public static enum PlanLifecycleState
{
NEW,
BODY,
PASSING,
FAILING,
ABORTING,
PASSED,
FAILED,
ABORTED,
};
/** The plan has a reason. */
protected Object reason;
/** The plan has a dispatched element (current goal/event). */
protected Object dispatchedelement;
/** The plan has subgoals attribute (hack!!! redundancy to goal_has_parentplan). */
protected List subgoals;
/** The plan has a wait abstraction attribute. */
protected WaitAbstraction waitabstraction;
/** The plan has a waitqueue wait abstraction attribute. */
protected WaitAbstraction waitqueuewa;
/** The waitqueue. */
protected Waitqueue waitqueue;
/** The wait future (to resume execution). */
// protected Future> waitfuture;
// protected ICommand resumecommand;
/** The blocking resume. */
protected ICommand resumecommand;
/** The non-blocking resumes. */
protected List> resumecommands;
/** The plan has exception attribute. */
protected Exception exception;
/** The result. */
protected Object result;
/** The plan has lifecycle state attribute. */
protected PlanLifecycleState lifecyclestate;
/** The plan has processing state attribute (ready or waiting). */
protected PlanProcessingState processingstate;
// /** The plan has a timer attribute (when waiting). */
// protected static ? plan_has_timer;
/** The plan body. */
protected IPlanBody body;
/** The candidate from which this plan was created. Used for tried plans in proc elem. */
protected ICandidateInfo candidate;
// // hack?
// /** The internal access. */
// protected IInternalAccess ia;
/** The plan listeners. */
// protected List> listeners;
protected List> listeners;
/** The wait cnt for rule names. */
protected int cnt;
/** The atomic flag. */
protected boolean atomic;
/** The finished future (if finishing or finished). */
public Future finished;
/**
* Create a new rplan based on an mplan.
*
* Reason is Object (not RProcessableElement) because it can be also ChangeEvent
*/
public static RPlan createRPlan(MPlan mplan, ICandidateInfo candidate, Object reason, IInternalAccess ia, Map binding, MConfigParameterElement config)
{
// Find parameter mappings for xml agents
Map mappingvals = binding;
// Todo: service call mappings?
if(reason instanceof RParameterElement && mplan.getParameters()!=null && mplan.getParameters().size()>0)
{
RParameterElement rpe = (RParameterElement)reason;
for(MParameter mparam: mplan.getParameters())
{
if(MParameter.Direction.IN.equals(mparam.getDirection()) || MParameter.Direction.INOUT.equals(mparam.getDirection()))
{
List mappings = rpe instanceof RGoal ? ((MPlanParameter)mparam).getGoalMappings()
: rpe instanceof RMessageEvent ? ((MPlanParameter)mparam).getMessageEventMappings() : ((MPlanParameter)mparam).getInternalEventMappings();
if(mappings!=null)
{
for(String mapping: mappings)
{
MCapability capa = ((IBDIModel)ia.getModel()).getCapability();
String sourceelm = mapping.substring(0, mapping.indexOf("."));
String sourcepara = mapping.substring(mapping.indexOf(".")+1);
if(rpe instanceof RGoal && capa.getGoalReferences().containsKey(sourceelm))
{
sourceelm = capa.getGoalReferences().get(sourceelm);
}
else if((rpe instanceof RMessageEvent || rpe instanceof RInternalEvent) && capa.getEventReferences().containsKey(sourceelm))
{
sourceelm = capa.getEventReferences().get(sourceelm);
}
if(rpe.getModelElement().getName().equals(sourceelm))
{
if(mappingvals==null)
mappingvals = new HashMap();
if(mparam.isMulti(null))
{
mappingvals.put(mparam.getName(), rpe.getParameterSet(sourcepara).getValues());
}
else
{
mappingvals.put(mparam.getName(), rpe.getParameter(sourcepara).getValue());
}
break;
}
}
}
}
}
}
final RPlan rplan = new RPlan(mplan, candidate, reason, ia, mappingvals, config); //mappingvals==null? new RPlan(mplan, candidate, ia):
// rplan.setInternalAccess(ia);
rplan.setDispatchedElement(reason);
MBody mbody = mplan.getBody();
IPlanBody body = null;
if(candidate.getRawCandidate().getClass().isAnnotationPresent(Plan.class))
{
body = new ClassPlanBody(ia, rplan, candidate.getRawCandidate());
}
else if(mbody.getClazz()!=null && mbody.getServiceName()==null)
{
Class> clazz0 = (Class>)mbody.getClazz().getType(ia.getClassLoader());
Class> clazz = clazz0;
while(body==null && !Object.class.equals(clazz))
{
if(clazz.isAnnotationPresent(Plan.class))
{
body = new ClassPlanBody(ia, rplan, clazz0);
}
else if(clazz.isAnnotationPresent(Agent.class))
{
body = new ComponentPlanBody(clazz0.getName()+".class", ia, rplan);
}
else
{
clazz = clazz.getSuperclass();
}
}
if(body==null)
{
throw new RuntimeException("Neither @Plan nor @Agent annotation on plan body class: "+clazz);
}
}
else if(mbody.getMethod()!=null)
{
Method met = mbody.getMethod().getMethod(ia.getClassLoader());
body = new MethodPlanBody(ia, rplan, met);
}
else if(mbody.getServiceName()!=null)
{
try
{
IServiceParameterMapper mapper;
if(mbody.getMapperClass()!=null)
{
mapper = (IServiceParameterMapper)mbody.getMapperClass().getType(ia.getClassLoader()).newInstance();
}
else
{
// final BDIAgentInterpreter ip = (BDIAgentInterpreter)((BDIAgent)ia).getInterpreter();
mapper = new DefaultAnnotationMapper(mbody.getServiceName(), ia);
}
Object plan = new ServiceCallPlan(ia, mbody.getServiceName(), mbody.getServiceMethodName(), mapper, rplan);
body = new ClassPlanBody(ia, rplan, plan);
}
catch(Exception e)
{
throw new RuntimeException(e);
}
}
else if(mbody.getComponent()!=null)
{
body = new ComponentPlanBody(mbody.getComponent(), ia, rplan);
}
if(body==null)
throw new RuntimeException("Plan body not created: "+rplan);
MTrigger wqtr = mplan.getWaitqueue();
if(wqtr!=null)
{
List events = new ArrayList();
for(String belname: SUtil.safeList(wqtr.getFactAddeds()))
{
events.add(new EventType(new String[]{ChangeEvent.FACTADDED, belname}));
}
for(String belname: SUtil.safeList(wqtr.getFactRemoveds()))
{
events.add(new EventType(new String[]{ChangeEvent.FACTREMOVED, belname}));
}
for(String belname: SUtil.safeList(wqtr.getFactChangeds()))
{
events.add(new EventType(new String[]{ChangeEvent.FACTCHANGED, belname}));
}
for(MGoal goal: SUtil.safeList(wqtr.getGoalFinisheds()))
{
events.add(new EventType(new String[]{ChangeEvent.GOALDROPPED, goal.getName()}));
}
if(!events.isEmpty())
{
//// final BDIAgentInterpreter ip = (BDIAgentInterpreter)((BDIAgent)ia).getInterpreter();
// final String rulename = rplan.getId()+"_waitqueue";
// Rule rule = new Rule(rulename, ICondition.TRUE_CONDITION, new IAction()
// {
// public IFuture execute(IEvent event, IRule rule, Object context, Object condresult)
// {
// System.out.println("Added to waitqueue: "+event);
// rplan.addToWaitqueue(new ChangeEvent(event));
// return IFuture.DONE;
// }
// });
// rule.setEvents(events);
// ia.getComponentFeature(IInternalBDIAgentFeature.class).getRuleSystem().getRulebase().addRule(rule);
rplan.internalSetupEventsRule(events);
}
for(MInternalEvent mevent: SUtil.safeList(wqtr.getInternalEvents()))
{
WaitAbstraction wa = rplan.getOrCreateWaitqueueWaitAbstraction();
wa.addModelElement(mevent);
}
for(MMessageEvent mevent: SUtil.safeList(wqtr.getMessageEvents()))
{
WaitAbstraction wa = rplan.getOrCreateWaitqueueWaitAbstraction();
wa.addModelElement(mevent);
}
// Todo: not for waitqueue, like goals...?
// for(MServiceCall mevent: SUtil.safeList(wqtr.getServices()))
// {
// WaitAbstraction wa = rplan.getOrCreateWaitqueueWaitAbstraction();
// wa.addModelElement(mevent);
// }
}
rplan.setBody(body);
// final BDIAgentInterpreter ip = (BDIAgentInterpreter)((BDIAgent)ia).getInterpreter();
// Collection pls = ip.getCapability().getPlans(mplan);
// if(pls!=null && pls.size()>0)
// {
// if(mplan.getName().indexOf("CleanUpWastePlan")!=-1)
// System.out.println("doubel plan");
// for(RPlan pl: pls)
// {
// if(pl.getReason()!=null && pl.getReason().equals(reason))
// System.out.println("double plan");
// }
// }
return rplan;
}
/**
* Add reason to fetcher.
*/
@Override
public SimpleValueFetcher wrapFetcher(IValueFetcher fetcher)
{
SimpleValueFetcher ret = super.wrapFetcher(fetcher);
if(reason instanceof RParameterElement)
{
ret.setValue(((RParameterElement)reason).getFetcherName(), reason);
}
return ret;
}
/**
* Get the pojo plan of a plan.
* @return The pojo plan.
*/
public Object getPojoPlan()
{
return body instanceof ClassPlanBody? ((ClassPlanBody)body).getPojoPlan(): null;
}
/**
* Execute a plan.
*/
public static IFuture executePlan(RPlan rplan, IInternalAccess ia)
{
Future ret = new Future();
// if(rplan.getModelElement().getName().toLowerCase().indexOf("go_home")!=-1)
// System.out.println("execute plan: "+rplan);
// executePlan(rplan, ia, null);
IConditionalComponentStep action = new ExecutePlanStepAction(rplan);
ia.getComponentFeature(IExecutionFeature.class).scheduleStep(action);
rplan.addListener(new DelegationResultListener(ret));
return ret;
}
// /**
// * Execute a plan.
// */
// public static void executePlan(RPlan rplan, IInternalAccess ia, ICommand resume)
// {
//// BDIAgentInterpreter ip = (BDIAgentInterpreter)((BDIAgent)ia).getInterpreter();
//// ip.getCapability().addPlan(rplan);
// IConditionalComponentStep action = new ExecutePlanStepAction(rplan, resume);
// ia.getExternalAccess().scheduleStep(action);
// }
// /**
// * Create a new plan.
// */
// public RPlan(MPlan mplan, Object candidate, IInternalAccess agent)
// {
// this(mplan, candidate, agent, null);
// }
/**
* Create a new plan.
*/
public RPlan(MPlan mplan, ICandidateInfo candidate, Object reason, IInternalAccess agent, Map mappingvals, MConfigParameterElement config)
{
super(mplan, agent, mappingvals, config);
this.candidate = candidate;
this.reason = reason;
setLifecycleState(PlanLifecycleState.NEW);
setProcessingState(PlanProcessingState.READY);
// Tricky, requires reason to be set before initing parameters.
super.initParameters(mappingvals, config);
}
/**
* Create the parameters from model spec.
*/
@Override
public void initParameters(Map vals, MConfigParameterElement config)
{
// do nothing in super constructor init
}
/**
* Get the name of the element in the fetcher (e.g. $goal).
* @return The element name in the fetcher name.
*/
public String getFetcherName()
{
return "$plan";
}
/**
* Get the processingState.
* @return The processingState.
*/
public PlanProcessingState getProcessingState()
{
return processingstate;
}
/**
* Set the processingState.
* @param processingState The processingState to set.
*/
// public Exception e = null;
public void setProcessingState(PlanProcessingState processingstate)
{
// if(getId().indexOf("Move")!=-1)
// {
// System.out.println("proc state: "+getId()+" "+processingstate);
// Thread.dumpStack();
// }
// if(processingstate.equals(PlanProcessingState.RUNNING))
// {
// System.out.println("proc state: "+getId()+" "+processingstate);
//// e = new RuntimeException();
// }
this.processingstate = processingstate;
publishToolPlanEvent(IMonitoringEvent.EVENT_TYPE_MODIFICATION);
}
/**
* Get the lifecycleState.
* @return The lifecycleState.
*/
public PlanLifecycleState getLifecycleState()
{
return lifecyclestate;
}
/**
* Set the lifecycleState.
* @param lifecycleState The lifecycleState to set.
*/
public void setLifecycleState(PlanLifecycleState lifecyclestate)
{
// if(lifecyclestate.equals(PlanLifecycleState.ABORTED))
// System.out.println("state: "+this+", "+lifecyclestate);
this.lifecyclestate = lifecyclestate;
if(PlanLifecycleState.BODY.equals(lifecyclestate))
{
getRuleSystem().addEvent(new Event(new EventType(new String[]{ChangeEvent.PLANADOPTED, getModelElement().getName()}), this));
publishToolPlanEvent(IMonitoringEvent.EVENT_TYPE_CREATION);
}
else if(PlanLifecycleState.PASSED.equals(lifecyclestate)
|| PlanLifecycleState.FAILED.equals(lifecyclestate)
|| PlanLifecycleState.ABORTED.equals(lifecyclestate))
{
getRuleSystem().addEvent(new Event(new EventType(new String[]{ChangeEvent.PLANFINISHED, getModelElement().getName()}), this));
publishToolPlanEvent(IMonitoringEvent.EVENT_TYPE_DISPOSAL);
}
else
{
publishToolPlanEvent(IMonitoringEvent.EVENT_TYPE_MODIFICATION);
}
if(PlanLifecycleState.PASSED.equals(lifecyclestate)
|| PlanLifecycleState.FAILED.equals(lifecyclestate)
|| PlanLifecycleState.ABORTED.equals(lifecyclestate))
{
assert finished!=null;
if(finished!=null)
{
finished.setResult(null);
}
// todo: where to notify listeners
notifyListeners();
// if(listeners!=null && listeners.size()>0)
// {
// for(IPlanListener> lis: listeners)
// {
// ((IPlanListener)lis).planFinished(getResult());
// }
// }
}
// if(PlanLifecycleState.PASSED.equals(lifecyclestate)
// || PlanLifecycleState.FAILED.equals(lifecyclestate)
// || PlanLifecycleState.ABORTED.equals(lifecyclestate))
// {
// System.out.println("plan lifecycle: "+lifecyclestate+", "+this);
// }
}
/**
* Notify the listeners.
*/
public void notifyListeners()
{
if(getListeners()!=null)
{
for(IResultListener lis: getListeners())
{
if(isSucceeded())
{
lis.resultAvailable(getResult());
}
else if(isFailed())
{
lis.exceptionOccurred(exception);
}
}
}
}
/**
* Add a new listener to get notified when the goal is finished.
* @param listener The listener.
*/
public void addListener(IResultListener listener)
{
if(listeners==null)
listeners = new ArrayList>();
if(isSucceeded())
{
listener.resultAvailable(null);
}
else if(isFailed())
{
listener.exceptionOccurred(exception);
}
else
{
listeners.add(listener);
}
}
/**
* Remove a listener.
*/
public void removeListener(IResultListener listener)
{
if(listeners!=null)
listeners.remove(listener);
}
/**
* Get the listeners.
* @return The listeners.
*/
public List> getListeners()
{
return listeners;
}
/**
* Get the reason.
* @return The reason.
*/
public Object getReason()
{
return reason;
}
/**
* Get the dispatchedelement.
* @return The dispatchedelement.
*/
public Object getDispatchedElement()
{
return dispatchedelement;
}
/**
* Set the dispatchedelement.
* @param dispatchedelement The dispatchedelement to set.
*/
public void setDispatchedElement(Object dispatchedelement)
{
this.dispatchedelement = dispatchedelement;
}
/**
* Get the exception.
* @return The exception.
*/
public Exception getException()
{
return exception;
}
/**
* Set the exception.
* @param exception The exception to set.
*/
public void setException(Exception exception)
{
// System.out.println("setting ex: "+exception+" "+this);
this.exception = exception;
}
/**
* Get the body.
* @return The body.
*/
public IPlanBody getBody()
{
return body;
}
/**
* Set the body.
* @param body The body to set.
*/
public void setBody(IPlanBody body)
{
this.body = body;
}
/**
* Get the candidate.
* @return The candidate.
*/
public ICandidateInfo getCandidate()
{
return candidate;
}
/**
* Set the candidate.
* @param candidate The candidate to set.
*/
public void setCandidate(ICandidateInfo candidate)
{
this.candidate = candidate;
}
// /**
// * Get the ia.
// * @return The ia.
// */
// public IInternalAccess getInternalAccess()
// {
// return ia;
// }
// /**
// * Set the ia.
// * @param ia The ia to set.
// */
// public void setInternalAccess(IInternalAccess ia)
// {
// this.ia = ia;
// }
/**
* Test if the plan is waiting for a process element.
*/
public boolean isWaitingFor(Object procelem)
{
return RPlan.PlanProcessingState.WAITING.equals(getProcessingState())
&& waitabstraction!=null && waitabstraction.isWaitingFor(procelem);
}
/**
* Get the waitabstraction.
* @return The waitabstraction.
*/
public WaitAbstraction getWaitAbstraction()
{
return waitabstraction;
}
/**
* Set the waitabstraction.
* @param waitabstraction The waitabstraction to set.
*/
public void setWaitAbstraction(WaitAbstraction waitabstraction)
{
this.waitabstraction = waitabstraction;
}
/**
* Test if the plan is always waiting for a process element (waitqueue wait).
*/
public boolean isWaitqueueWaitingFor(Object procelem)
{
// Do not dispatch process goals to waitqueue. (Hack? not allowed for v2, but would be easily possible for v3)
boolean processgoal = procelem instanceof RGoal && ((RGoal)procelem).getProcessingState()==GoalProcessingState.INPROCESS;
return !processgoal && waitqueuewa!=null && waitqueuewa.isWaitingFor(procelem);
}
// /**
// * Get the waitabstraction.
// * @return The waitabstraction.
// */
// public WaitAbstraction getWaitqueueWaitAbstraction()
// {
// return waitqueuewa;
// }
/**
* Get the waitabstraction.
* @return The waitabstraction.
*/
public WaitAbstraction getOrCreateWaitqueueWaitAbstraction()
{
if(waitqueuewa==null)
waitqueuewa = new WaitAbstraction();
return waitqueuewa;
}
// /**
// * Set the waitabstraction.
// * @param waitabstraction The waitabstraction to set.
// */
// public void setWaitqueueWaitAbstraction(WaitAbstraction waitabstraction)
// {
// this.waitqueuewa = waitabstraction;
// }
/**
*
*/
protected void addToWaitqueue(Object obj)
{
if(waitqueue==null)
waitqueue = new Waitqueue();
waitqueue.addElement(obj);
}
/**
*
*/
public Object getFromWaitqueue(WaitAbstraction wa)
{
return waitqueue!=null ? waitqueue.getFromWaitqueue(wa) : null;
}
/**
*
*/
public boolean isPassed()
{
return RPlan.PlanLifecycleState.PASSED.equals(lifecyclestate);
}
/**
*
*/
public boolean isFailed()
{
return RPlan.PlanLifecycleState.FAILED.equals(lifecyclestate);
}
/**
*
*/
public boolean isAborted()
{
return RPlan.PlanLifecycleState.ABORTED.equals(lifecyclestate);
}
/**
* Start the finishing of the plan.
*/
public void setFinishing()
{
assert finished==null;
assert getAgent().getComponentFeature(IExecutionFeature.class).isComponentThread();
finished = new Future();
}
/**
* Test, if the plan end state (passed/failed/aborted) is started or done.
*/
public boolean isFinishing()
{
return finished!=null;
}
/**
*
*/
public boolean isFinished()
{
return isPassed() || isFailed() || isAborted();
}
/**
*
*/
public void addSubgoal(RGoal subgoal)
{
if(subgoals==null)
{
subgoals = new ArrayList();
}
subgoals.add(subgoal);
}
/**
*
*/
public void removeSubgoal(RGoal subgoal)
{
if(subgoals!=null)
{
subgoals.remove(subgoal);
}
}
/**
*
*/
public IFuture abort()
{
// System.out.println("aborting: "+this);
if(!isFinishing())
{
setFinishing();
if(!isFinished())
{
// setLifecycleState(PLANLIFECYCLESTATE_ABORTED);
Exception ex = new PlanAbortedException();
setException(ex); // remove? // todo: BodyAborted
if(subgoals!=null)
{
for(IGoal subgoal: subgoals)
{
// Todo: wait for goals dropped?
subgoal.drop();
}
}
// Stop plan execution if any.
// System.out.println("aborting2: "+this);
body.abort();
// System.out.println("aborting3: "+this);
// If plan is waiting interrupt waiting
if(PlanProcessingState.WAITING.equals(getProcessingState()))
{
// System.out.println("aborting4: "+this);
// RPlan.executePlan(this, ia, new ICommand()
// {
// public void execute(Boolean args)
// {
// The resume command continues the blocked plan thread and
// the commands are to continue all listeners on hold
// This is not completely clean because the agent does not wait for these threads
ICommand resc = getResumeCommand();
if(resc!=null)
{
// System.out.println("aborting5: "+this+", "+resc);
resc.execute(new ResumeCommandArgs(null, null, ex));
}
List> rescoms = getResumeCommands();
if(rescoms!=null)
{
ICommand[] tmp = (ICommand[])rescoms.toArray(new ICommand[rescoms.size()]);
// System.out.println("aborting6: "+this+", "+SUtil.arrayToString(tmp));
for(ICommand rescom: tmp)
{
rescom.execute(new ResumeCommandArgs(null, null, ex));
}
}
// }
// });
}
// // Can be currently executing and being abort due to e.g. goal condition triggering
// else if(PlanProcessingState.RUNNING.equals(getProcessingState()))
// {
// it will detect the abort in beforeBlock() when next future.get() is
// called and will avoid the next wait
// }
// else if(!PlanLifecycleState.NEW.equals(getLifecycleState()))
// {
// System.out.println("Cannot abort plan: "+getId()+" "+getProcessingState()+" "+getLifecycleState());
// }
}
}
return finished;
}
// /**
// * Get the waitfuture.
// * @return The waitfuture.
// */
// public Future> getWaitFuture()
// {
// return waitfuture;
// }
//
// /**
// * Get the waitfuture.
// */
// public void setWaitFuture(Future> fut)
// {
// assert waitfuture==null;
//
// waitfuture = fut;
// }
/**
*
*/
// public void continueAfterWait(ICommand resumecommand)
// {
// if(resumecommand==null)
// {
// System.out.println("res com null: "+resumecommand);
//
// first.printStackTrace();
//
// Thread.dumpStack();
// }
// else
// {
// first = new RuntimeException();
// }
// assert resumecommand!=null;
// ICommand com = resumecommand;
// resumecommand = null;
// setProcessingState(PlanProcessingState.RUNNING);
// resumecommand.execute(null);
// }
// /**
// * Get the resumecommand.
// * @return The resumecommand.
// */
// public ICommand getResumeCommand()
// {
// return resumecommand;
// }
// Exception first = null;
// /**
// * Sets a resume command for continuing a plan.
// * Cleans dispatched element.
// * Sets processing state to WAITING.
// */
// public void setResumeCommand(ICommand com)
// {
//// if(resumecommand!=null)
//// {
//// System.out.println("res com not null: "+resumecommand+" "+com);
////
//// first.printStackTrace();
////
//// Thread.dumpStack();
//// }
//// else
//// {
//// first = new RuntimeException();
//// }
//
// assert resumecommand==null;
// setDispatchedElement(null);
// setProcessingState(PlanProcessingState.WAITING);
// resumecommand = com;
// }
/**
* Get the waitqueue.
* @return The waitqueue.
*/
public Waitqueue getWaitqueue()
{
if(waitqueue==null)
{
waitqueue = new Waitqueue();
}
return waitqueue;
}
// methods that can be called from pojo plan
// /**
// * Wait for a delay.
// */
// public IFuture waitFor(long delay)
// {
// setProcessingState(PLANPROCESSINGTATE_WAITING);
// final Future ret = new Future();
// ia.waitForDelay(delay, new IComponentStep()
// {
// public IFuture execute(IInternalAccess ia)
// {
// if(isAborted() || isFailed())
// {
// return new Future(new PlanFailureException());
// }
// else
// {
// return IFuture.DONE;
// }
// }
// }).addResultListener(new DelegationResultListener(ret));
// return ret;
// }
/**
* Wait for a delay.
*/
public IFuture waitFor(long delay)
{
final Future ret = new BDIFuture();
final ResumeCommand rescom = new ResumeCommand(ret, true);
// setResumeCommand(rescom);
addResumeCommand(rescom);
getAgent().getComponentFeature(IExecutionFeature.class).waitForDelay(delay, new IComponentStep()
{
public IFuture execute(IInternalAccess ia)
{
// if(rescom.equals(getResumeCommand()))
{
rescom.execute(null);
// RPlan.executePlan(RPlan.this, ia, rescom);
}
// if(getException()!=null)
// {
// return new Future(getException());
// }
// else
// {
// return IFuture.DONE;
// }
return IFuture.DONE;
}
}, false);//.addResultListener(new DelegationResultListener(ret, true));
return ret;
}
/**
* Dispatch a goal wait for its result.
*/
public IFuture dispatchSubgoal(final T goal)
{
return dispatchSubgoal(goal, -1);
}
/**
* Dispatch a goal wait for its result.
*/
public IFuture dispatchSubgoal(final T goal, long timeout)
{
// final BDIAgentInterpreter ip = (BDIAgentInterpreter)((BDIAgent)ia).getInterpreter();
final Future ret = new BDIFuture();
IBDIModel bdim = getAgent().getComponentFeature(IInternalBDIAgentFeature.class).getBDIModel();
final MGoal mgoal = bdim.getCapability().getGoal(goal.getClass().getName());
if(mgoal==null)
throw new RuntimeException("Unknown goal type: "+goal);
final RGoal rgoal = new RGoal(getAgent(), mgoal, goal, null, null, null, null);
rgoal.setParent(this);
final ResumeCommand rescom = new ResumeCommand(ret, false);
// setResumeCommand(rescom);
addResumeCommand(rescom);
final PlanLifecycleState lcs = getLifecycleState();
IFuture cont = createTimer(timeout, getAgent(), rescom);
cont.addResultListener(new DefaultResultListener()
{
public void resultAvailable(final ITimer timer)
{
if(lcs.equals(getLifecycleState()))
{
if(timer!=null)
rescom.setTimer(timer);
// rgoal.addGoalListener(new TimeoutResultListener(
// timeout, getAgent().getExternalAccess(), new IResultListener()
rgoal.addListener(new IResultListener()
{
public void resultAvailable(Void result)
{
if(getException()==null)
{
Object o = RGoal.getGoalResult(rgoal, getAgent().getClassLoader());
if(o==null)
o = goal;
setDispatchedElement(o);
// Non-maintain goal -> remove subgoal.
if(rgoal.isFinished())
{
removeSubgoal(rgoal);
}
// else keep maintain goal until plan is finished
// todo: allow explicit removal / redispatch
}
rescom.execute(null);
}
public void exceptionOccurred(Exception exception)
{
// if(rescom.equals(getResumeCommand()))
{
// setException(exception);
// RPlan.executePlan(RPlan.this, getAgent(), rescom);
rescom.execute(new ResumeCommandArgs(null, null, exception));
removeSubgoal(rgoal);
}
}
});
addSubgoal(rgoal);
AdoptGoalAction.adoptGoal(getAgent(), rgoal);
// getAgent().getComponentFeature(IExecutionFeature.class).scheduleStep(new AdoptGoalAction(rgoal))
// .addResultListener(new IResultListener()
// {
// public void resultAvailable(Void result)
// {
// }
// public void exceptionOccurred(Exception exception)
// {
// }
// });
}
}
});
return ret;
}
/**
* Wait for a fact change of a belief.
*/
public IFuture> waitForFactChanged(String belname)
{
return waitForFactX(belname, new String[]{ChangeEvent.FACTCHANGED}, -1, null);
}
/**
* Wait for a fact change of a belief.
*/
public IFuture> waitForFactChanged(String belname , long timeout)
{
return waitForFactX(belname, new String[]{ChangeEvent.FACTCHANGED}, timeout, null);
}
/**
* Wait for a fact being added to a belief.
*/
public IFuture> waitForFactAdded(String belname)
{
return waitForFactX(belname, new String[]{ChangeEvent.FACTADDED}, -1, null);
}
/**
* Wait for a fact being added to a belief.
*/
public IFuture> waitForFactAdded(String belname, long timeout)
{
return waitForFactX(belname, new String[]{ChangeEvent.FACTADDED}, timeout, null);
}
/**
* Wait for a fact being removed from a belief.
*/
public IFuture> waitForFactRemoved(String belname)
{
return waitForFactX(belname, new String[]{ChangeEvent.FACTREMOVED}, -1, null);
}
/**
* Wait for a fact being removed from a belief.
*/
public IFuture> waitForFactRemoved(String belname, long timeout)
{
return waitForFactX(belname, new String[]{ChangeEvent.FACTREMOVED}, timeout, null);
}
/**
* Wait for a fact being added to a belief..
*/
public IFuture> waitForFactX(String belname, String[] evtypes, long timeout, final IFilter> filter)
{
Future> ret = new Future>();
// final BDIAgentInterpreter ip = (BDIAgentInterpreter)((BDIAgent)getAgent()).getInterpreter();
// Also set waitabstraction to know what the plan is waiting for
final List ets = new ArrayList();
WaitAbstraction wa = new WaitAbstraction();
for(String evtype: evtypes)
{
EventType et = new EventType(new String[]{evtype, belname});
wa.addChangeEventType(et.toString());
ets.add(et);
}
// setWaitAbstraction(wa);
Object obj = getFromWaitqueue(wa);
if(obj!=null)
{
ret.setResult((ChangeInfo>)((ChangeEvent)obj).getValue());
// ret = new Future(obj);
}
else
{
final String rulename = getRuleName();
final ResumeCommand> rescom = new ResumeCommand>(ret, rulename, false);
// final ResumeCommand rescom = new ResumeCommand(ret, rulename, false);
// setResumeCommand(rescom);
addResumeCommand(rescom);
IFuture cont = createTimer(timeout, getAgent(), rescom);
cont.addResultListener(new DefaultResultListener()
{
public void resultAvailable(final ITimer timer)
{
if(timer!=null)
rescom.setTimer(timer);
Rule rule = new Rule(rulename, filter==null? ICondition.TRUE_CONDITION: new ICondition()
{
public IFuture> evaluate(IEvent event)
{
return new Future>(filter.filter((ChangeInfo>)event.getContent())? ICondition.TRUE: ICondition.FALSE);
}
}, new IAction()
{
public IFuture execute(IEvent event, IRule rule, Object context, Object condresult)
{
// if(rescom.equals(getResumeCommand()))
// {
setDispatchedElement(new ChangeEvent(event));
rescom.execute(null);
// RPlan.executePlan(RPlan.this, getAgent(), rescom);
// }
return IFuture.DONE;
}
});
// rule.addEvent(et);
rule.setEvents(ets);
getRuleSystem().getRulebase().addRule(rule);
}
});
}
Future> fut = new BDIFuture>();
ret.addResultListener(new DelegationResultListener>(fut)
{
public void customResultAvailable(ChangeInfo> result)
{
// ChangeEvent ce = (ChangeEvent)result;
// super.customResultAvailable(ce.getValue());
super.customResultAvailable(result);
}
});
return fut;
}
/**
* Wait for a fact being added or removed to a belief.
*/
public IFuture> waitForFactAddedOrRemoved(String belname)
{
return waitForFactAddedOrRemoved(belname, -1);
}
/**
* Wait for a fact being added or removed to a belief.
*/
public IFuture> waitForFactAddedOrRemoved(String belname, long timeout)
{
return waitForFactX(belname, new String[]{ChangeEvent.FACTADDED, ChangeEvent.FACTREMOVED}, timeout, null);
// Future> ret = new BDIFuture>();
//
// // Also set waitabstraction to know what the plan is waiting for
// WaitAbstraction wa = new WaitAbstraction();
// final EventType eta = new EventType(new String[]{ChangeEvent.FACTADDED, belname});
// final EventType etb = new EventType(new String[]{ChangeEvent.FACTREMOVED, belname});
// wa.addChangeEventType(eta.toString());
// wa.addChangeEventType(etb.toString());
//// setWaitAbstraction(wa);
//
// Object obj = getFromWaitqueue(wa);
// if(obj!=null)
// {
// ret.setResult((ChangeInfo>)((ChangeEvent)obj).getValue());
//// ret = new Future((ChangeEvent)obj);
// }
// else
// {
// final String rulename = getRuleName();
// final BDIAgentInterpreter ip = (BDIAgentInterpreter)((BDIAgent)getAgent()).getInterpreter();
//
// final ResumeCommand> rescom = new ResumeCommand>(ret, rulename, false);
//// setResumeCommand(rescom);
// addResumeCommand(rescom);
//
// IFuture cont = createTimer(timeout, ip, rescom);
// cont.addResultListener(new DefaultResultListener()
// {
// public void resultAvailable(final ITimer timer)
// {
// if(timer!=null)
// rescom.setTimer(timer);
//
// Rule rule = new Rule(rulename, ICondition.TRUE_CONDITION, new IAction()
// {
// public IFuture execute(IEvent event, IRule rule, Object context, Object condresult)
// {
//// if(rescom.equals(getResumeCommand()))
// {
// setDispatchedElement(new ChangeEvent(event));
// RPlan.executePlan(RPlan.this, getAgent(), rescom);
// }
// return IFuture.DONE;
// }
// });
// rule.addEvent(eta);
// rule.addEvent(etb);
// ip.getRuleSystem().getRulebase().addRule(rule);
// }
// });
// }
//
// return ret;
}
/**
* Wait for a collection change.
*/
public IFuture> waitForCollectionChange(String belname, long timeout, IFilter> filter)
// public IFuture> waitForCollectionChange(String belname, long timeout, IFilter> filter)
{
// buahhh :-((( how to get this generics nightmare?
IFuture fut = waitForFactX(belname, new String[]{ChangeEvent.FACTCHANGED, ChangeEvent.FACTADDED, ChangeEvent.FACTREMOVED}, timeout, (IFilter)filter);
return (IFuture>)fut;
}
/**
* Wait for a collection change.
*/
public IFuture> waitForCollectionChange(String belname, long timeout, final Object id)
{
IFuture fut = waitForFactX(belname, new String[]{ChangeEvent.FACTCHANGED, ChangeEvent.FACTADDED, ChangeEvent.FACTREMOVED}, timeout, new IFilter>()
{
public boolean filter(ChangeInfo> info)
{
boolean ret = false;
if(info.getInfo()!=null)
{
ret = info.getInfo().equals(id);
}
return ret;
}
});
return (IFuture>)fut;
}
/**
* Wait for a condition.
*/
public IFuture waitForCondition(ICondition cond, String[] events)
{
return waitForCondition(cond, events, -1);
}
/**
* Wait for a condition.
*/
public IFuture waitForCondition(final ICondition cond, final String[] events, long timeout)
{
Future ret = new BDIFuture();
// final BDIAgentInterpreter ip = (BDIAgentInterpreter)((BDIAgent)getAgent()).getInterpreter();
final String rulename = getRuleName();
final ResumeCommand rescom = new ResumeCommand(ret, rulename, false);
// setResumeCommand(rescom);
addResumeCommand(rescom);
IFuture cont = createTimer(timeout, getAgent(), rescom);
cont.addResultListener(new DefaultResultListener()
{
public void resultAvailable(final ITimer timer)
{
if(timer!=null)
rescom.setTimer(timer);
Rule rule = new Rule(rulename, cond!=null? cond: ICondition.TRUE_CONDITION, new IAction()
{
public IFuture execute(IEvent event, IRule rule, Object context, Object condresult)
{
// if(rescom.equals(getResumeCommand()))
// {
setDispatchedElement(new ChangeEvent(event));
rescom.execute(null);
// RPlan.executePlan(RPlan.this, getAgent(), rescom);
// }
return IFuture.DONE;
}
});
for(String ev: events)
{
rule.addEvent(new EventType(ev));
}
getRuleSystem().getRulebase().addRule(rule);
}
});
return ret;
}
/**
*
*/
public IFuture createTimer(long timeout, final IInternalAccess ia, final ICommand rescom)
{
final Future ret = new Future();
if(timeout>-1)
{
IClockService cs = SServiceProvider.getLocalService(ia, IClockService.class, RequiredServiceInfo.SCOPE_PLATFORM);
ITimedObject to = new ITimedObject()
{
public void timeEventOccurred(long currenttime)
{
// if(rescom.equals(getResumeCommand()))
// {
// setException(new TimeoutException());
rescom.execute(new ResumeCommandArgs(null, null, new TimeoutException()));
// RPlan.executePlan(RPlan.this, ia, rescom);
// }
}
};
ITimer timer = cs.createTimer(timeout, to);
ret.setResult(timer);
// IFuture tfut = ia.getComponentFeature(IExecutionFeature.class).waitForDelay(timeout, new IComponentStep()
// {
// public IFuture execute(IInternalAccess ia)
// {
//// if(rescom.equals(getResumeCommand()))
// {
// setException(new TimeoutException());
// RPlan.executePlan(RPlan.this, ia, rescom);
// }
// return IFuture.DONE;
// }
// });
// IFuture tfut = ((BDIAgent)ia).waitFor(timeout, new IComponentStep()
// {
// public IFuture execute(IInternalAccess ia)
// {
//// if(rescom.equals(getResumeCommand()))
// {
// setException(new TimeoutException());
// RPlan.executePlan(RPlan.this, ia, rescom);
// }
// return IFuture.DONE;
// }
// });
// tfut.addResultListener(new DefaultResultListener()
// {
// public void resultAvailable(ITimer result)
// {
// ret.setResult(result);
// }
// });
}
else
{
ret.setResult(null);
}
return ret;
}
// /**
// * Wait for some time.
// */
// public IFuture waitForDelayWithTimer(final long delay, final IComponentStep> step)
// {
// final Future ret = new Future();
//
// IClockService cs = SServiceProvider.getLocalService(getComponent(), IClockService.class, RequiredServiceInfo.SCOPE_PLATFORM);
// ITimedObject to = new ITimedObject()
// {
// public void timeEventOccurred(long currenttime)
// {
// scheduleStep(step);
// }
//
// public String toString()
// {
// return "waitForDelay("+getComponent().getComponentIdentifier()+")";
// }
// };
//
// ITimer timer = cs.createTimer(delay, to);
// ret.setResult(timer);
//
// return ret;
// }
// /**
// *
// */
// public IFuture invokeInterruptable(IResultCommand, Void> command)
// {
// final Future ret = new BDIFuture();
//
// final ICommand> rescom = new ResumeCommand(ret, null, false);
//// setResumeCommand(rescom);
// addResumeCommand(rescom);
//
// command.execute(null).addResultListener(getAgent().getComponentFeature(IExecutionFeature.class).createResultListener(new IResultListener()
// {
// public void resultAvailable(T result)
// {
//// if(rescom.equals(getResumeCommand()))
// {
// setDispatchedElement(result);
// rescom.execute(null);
//// RPlan.executePlan(RPlan.this, ia, rescom);
// }
// }
//
// public void exceptionOccurred(Exception exception)
// {
//// if(rescom.equals(getResumeCommand()))
// {
// setException(exception);
// rescom.execute(null);
//// RPlan.executePlan(RPlan.this, ia, rescom);
// }
// }
// }));
//
// return ret;
// }
/**
*
* @return
*/
protected String getRuleName()
{
return getId()+"_wait_#"+cnt++;
}
/**
* Called before blocking the component thread.
*/
public void beforeBlock()
{
testBodyAborted();
ComponentSuspendable sus = ComponentSuspendable.COMSUPS.get();
if(sus!=null && !RPlan.PlanProcessingState.WAITING.equals(getProcessingState()))
{
final ResumeCommand rescom = new ResumeCommand(sus, false);
setProcessingState(PlanProcessingState.WAITING);
// System.out.println("setting rescom: "+getId()+" "+rescom);
resumecommand = rescom;
}
}
/**
* Called after unblocking the component thread.
*/
public void afterBlock()
{
testBodyAborted();
setProcessingState(PlanProcessingState.RUNNING);
setWaitAbstraction(null);
if(resumecommand!=null)
{
// performs only cleanup without setting future
// System.out.println("afterblock rescom: "+getId()+" "+resumecommand);
resumecommand.execute(new ResumeCommandArgs(Boolean.FALSE, null, null));
// resumecommand.execute(new Tuple2(Boolean.FALSE, null));
resumecommand = null;
}
}
/**
* Check if plan is already aborted.
*/
protected void testBodyAborted()
{
// if(agent.toString().indexOf("Leaker")!=-1)
// {
// System.out.println("testBodyAborted "+this);
// }
// Throw error to exit body method of aborted plan.
if(isFinishing() && PlanLifecycleState.BODY.equals(getLifecycleState()))
{
BodyAborted ba = new BodyAborted();
// try
// {
// if(agent.toString().indexOf("Leaker")!=-1)
// {
// System.out.println("before throw BodyAborted: "+Runtime.getRuntime().freeMemory());
// }
throw ba;
// }
// finally
// {
// if(agent.toString().indexOf("Leaker")!=-1)
// {
// System.out.println("after throw BodyAborted: "+Runtime.getRuntime().freeMemory());
// }
// }
}
}
public static class ResumeCommandArgs
{
protected Boolean notify;
protected Boolean abort;
protected Exception exception;
public ResumeCommandArgs(Boolean notify, Boolean abort, Exception exception)
{
this.notify = notify;
this.abort = abort;
this.exception = exception;
}
/**
* Get the notify.
* @return the notify
*/
public Boolean getNotify()
{
return notify;
}
/**
* Get the abort.
* @return the abort
*/
public Boolean getAbort()
{
return abort;
}
/**
* Get the exception.
* @return the exception
*/
public Exception getException()
{
return exception;
}
}
/**
*
*/
public class ResumeCommand implements ICommand
{
protected ComponentSuspendable sus;
protected Future waitfuture;
protected String rulename;
protected ITimer timer;
protected boolean isvoid;
public ResumeCommand(Future waitfuture, boolean isvoid)
{
this(waitfuture, null, isvoid);
}
public ResumeCommand(Future waitfuture, String rulename, boolean isvoid)
{
// System.out.println("created: "+this+" "+RPlan.this.getId());
this.waitfuture = waitfuture;
this.rulename = rulename;
this.isvoid = isvoid;
}
public ResumeCommand(ComponentSuspendable sus, boolean isvoid)
{
this.sus = sus;
this.waitfuture = (Future)sus.getFuture();
this.isvoid = isvoid;
}
public void setTimer(ITimer timer)
{
this.timer = timer;
}
/**
* first Boolean: notify (default true)
* second Boolean: abort (default false)
*/
public void execute(ResumeCommandArgs args)
{
assert getAgent().getComponentFeature(IExecutionFeature.class).isComponentThread();
// System.out.println("exe: "+this+" "+RPlan.this.getId()+" "+this);
Exception ex = args!=null? args.getException(): null;
if(rulename!=null)
{
// System.out.println("rem rule: "+rulename);
// BDIAgentInterpreter ip = (BDIAgentInterpreter)((BDIAgent)ia).getInterpreter();
getRuleSystem().getRulebase().removeRule(rulename);
}
if(timer!=null)
{
timer.cancel();
}
waitabstraction = null;
boolean notify = args!=null && args.getNotify()!=null? args.getNotify().booleanValue(): true;
boolean abort = args!=null && args.getAbort()!=null? args.getAbort().booleanValue(): sus!=null;
if(notify && RPlan.PlanProcessingState.WAITING.equals(getProcessingState()))
{
boolean donotify = false;
if(resumecommands!=null && resumecommands.contains(this))
{
resumecommands.remove(this);
donotify = true;
}
if(this.equals(resumecommand))
{
// System.out.println("clear rescom: "+getId());
resumecommand = null;
donotify = true;
}
if(donotify)
{
if(!abort)//sus==null)
{
if(ex!=null)
{
if(waitfuture instanceof ITerminableFuture)
{
// System.out.println("notify1: "+getId());
((ITerminableFuture>)waitfuture).terminate(ex);
}
else
{
// System.out.println("notify2: "+getId());
waitfuture.setExceptionIfUndone(ex);
}
// setException(null); // Allow plan to continue when exception is catched.
}
else
{
Object o = getDispatchedElement();
if(o instanceof ChangeEvent)
{
o = ((ChangeEvent)o).getValue();
}
// System.out.println("notify3: "+getId());
waitfuture.setResultIfUndone(isvoid? null: (T)o);
}
}
else
{
// System.out.println("notify4: "+getId());
waitfuture.abortGet(sus);
}
}
}
}
/**
* Get the waitfuture.
* @return The waitfuture
*/
public Future getWaitfuture()
{
return waitfuture;
}
}
// /**
// *
// */
// public void addPlanListener(IPlanListener> listener)
// {
// if(listeners==null)
// listeners = new ArrayList>();
// listeners.add(listener);
// }
/**
*
*/
public void addResumeCommand(ICommand rescom)
{
// System.out.println("addResCom: "+this);
if(resumecommands==null)
resumecommands = new ArrayList>();
resumecommands.add(rescom);
}
/**
*
*/
public void removeResumeCommand(ICommand> rescom)
{
if(resumecommands!=null)
resumecommands.remove(rescom);
}
/**
* Get the resumecommands.
* @return The resumecommands.
*/
public List> getResumeCommands()
{
return resumecommands;
}
/**
* Get the resumecommand.
* @return The resumecommand.
*/
public ICommand getResumeCommand()
{
return resumecommand;
}
/**
* Get the result.
* @return The result.
*/
public Object getResult()
{
return result;
}
/**
* Set the result.
* @param result The result to set.
*/
public void setResult(Object result)
{
this.result = result;
}
/**
* Get the atomic.
* @return The atomic
*/
public boolean isAtomic()
{
return atomic;
}
/**
* The atomic to set.
* @param atomic The atomic to set
*/
public void setAtomic(boolean atomic)
{
this.atomic = atomic;
}
/**
* Publish a tool event.
*/
public void publishToolPlanEvent(String evtype)
{
if(getAgent().getComponentFeature0(IMonitoringComponentFeature.class)!=null
&& getAgent().getComponentFeature(IMonitoringComponentFeature.class).hasEventTargets(PublishTarget.TOSUBSCRIBERS, PublishEventLevel.FINE))
{
long time = System.currentTimeMillis();//getClockService().getTime();
MonitoringEvent mev = new MonitoringEvent();
mev.setSourceIdentifier(getAgent().getComponentIdentifier());
mev.setTime(time);
PlanInfo info = PlanInfo.createPlanInfo(this);
mev.setType(evtype+"."+IMonitoringEvent.SOURCE_CATEGORY_PLAN);
// mev.setProperty("sourcename", element.toString());
mev.setProperty("sourcetype", info.getType());
mev.setProperty("details", info);
mev.setLevel(PublishEventLevel.FINE);
getAgent().getComponentFeature(IMonitoringComponentFeature.class).publishEvent(mev, PublishTarget.TOSUBSCRIBERS);
}
}
/**
* Set up a rule for the waitque to signal to what kinds of events this plan
* in principle reacts to.
*/
public void setupEventsRule(Collection events)
{
List evs = new ArrayList();
for(String event: events)
{
evs.add(new EventType(event));
}
internalSetupEventsRule(evs);
}
/**
* Set up a rule for the waitqueue to signal to what kinds of events this plan
* in principle reacts to.
*/
public void internalSetupEventsRule(List events)
{
final String rulename = getId()+"_waitqueue";
Rule rule = new Rule(rulename, ICondition.TRUE_CONDITION, new IAction()
{
public IFuture execute(IEvent event, IRule rule, Object context, Object condresult)
{
// System.out.println("Added to waitqueue: "+event);
addToWaitqueue(new ChangeEvent(event));
return IFuture.DONE;
}
});
rule.setEvents(events);
getAgent().getComponentFeature(IInternalBDIAgentFeature.class).getRuleSystem().getRulebase().updateRule(rule);
}
// /**
// * Get the exception.
// * @return The exception.
// */
// public Exception getException();
/**
* Test if element is succeeded.
* @return True, if is succeeded.
*/
public boolean isSucceeded()
{
return isPassed();
}
// /**
// *
// */
// public BDIAgentInterpreter getInterpreter()
// {
// return (BDIAgentInterpreter)((BDIAgent)ia).getInterpreter();
// }
// /**
// *
// */
// class DefaultResumeCommand implements ICommand
// {
// protected Future waitfuture;
// protected ICommand cleancom;
//
// public DefaultResumeCommand(Future waitfuture, ICommand cleancom)
// {
// this.waitfuture = waitfuture;
// this.cleancom = cleancom;
// }
//
// public void execute(Void args)
// {
// if(getException()!=null)
// {
// waitfuture.setException(getException());
// }
// else
// {
// waitfuture.setResult((T)getDispatchedElement());
// }
//
// if(cleancom!=null)
// cleancom.execute(null);
// }
// }
/**
* Future that overrides addResultListener to keep track
* of current rplan in RPLANS variable.
*/
public class BDIFuture extends Future
{
/**
* Add a listener
* @param listener The listener.
*/
public void addResultListener(IResultListener listener)
{
super.addResultListener(new BDIComponentResultListener(listener, getAgent()));
}
}
/**
* Waitque holds events for later processing.
*/
public class Waitqueue
{
protected List queue = new ArrayList();
public String toString()
{
return "Waitqueue("+RPlan.this+", "+queue.toString()+")";
}
public RPlan getPlan()
{
return RPlan.this;
}
public void addElement(Object element)
{
queue.add(element);
}
/**
* Test if waitqueue is empty.
*/
public boolean isEmpty()
{
return queue.isEmpty();
}
/**
* Get the currently contained elements of the waitqueue.
* @return The collected elements.
*/
public Object[] getElements()
{
return queue.toArray();
}
/**
*
*/
protected Object getFromWaitqueue(WaitAbstraction wa)
{
Object ret = null;
for(int i=0; i