package jadex.bdi.runtime.impl; import jadex.bdi.model.OAVBDIMetaModel; import jadex.bdi.runtime.GoalFailureException; import jadex.bdi.runtime.TimeoutException; import jadex.bdi.runtime.impl.flyweights.ChangeEventFlyweight; import jadex.bdi.runtime.impl.flyweights.ExternalAccessFlyweight; import jadex.bdi.runtime.impl.flyweights.GoalFlyweight; import jadex.bdi.runtime.impl.flyweights.InternalEventFlyweight; import jadex.bdi.runtime.impl.flyweights.MessageEventFlyweight; import jadex.bdi.runtime.interpreter.BDIInterpreter; import jadex.bdi.runtime.interpreter.OAVBDIRuntimeModel; import jadex.bridge.CheckedAction; import jadex.commons.Future; import jadex.rules.state.IOAVState; import jadex.rules.state.OAVObjectType; import java.util.List; /** * The action class for continuing the external thread. */ public class WakeupAction extends CheckedAction { //-------- attributes -------- /** The state. */ protected IOAVState state; /** The scope. */ protected Object scope; /** The wait abstraction. */ protected Object wa; /** The external access. */ protected Object ea; /** The external access flyweight. */ protected Object eafly; /** The observeds elements (factadded, changed, removed). */ protected List observeds; /** The future. */ protected Future future; /** The timeout flag. */ protected boolean timeout; //-------- constructors -------- /** * Create a new wakeup action. */ public WakeupAction(IOAVState state, Object scope, Object wa, Object ea, ExternalAccessFlyweight eafly, List observeds, Future future) { this.state = state; this.scope = scope; this.wa = wa; this.ea = ea; this.eafly = eafly; this.observeds = observeds; this.future = future; this.timeout = true; } //-------- methods -------- /** * After external wait notify future with result. */ public void run() { Object ret = null; Exception e = null; if(isTimeout()) { if(wa!=null) { // state.removeAttributeValue(scope, OAVBDIRuntimeModel.capability_has_externalaccesses, ea); e = new TimeoutException(); } } else { Object de = state.getAttributeValue(ea, OAVBDIRuntimeModel.externalaccess_has_dispatchedelement); if(de!=null) { OAVObjectType type = state.getType(de); if(OAVBDIRuntimeModel.goal_type.equals(type)) { // When goal is not succeeded (or idle for maintaingoals) throw exception. if(!OAVBDIRuntimeModel.GOALPROCESSINGSTATE_SUCCEEDED.equals( state.getAttributeValue(de, OAVBDIRuntimeModel.goal_has_processingstate))) { Object mgoal = state.getAttributeValue(de, OAVBDIRuntimeModel.element_has_model); if(!state.getType(mgoal).isSubtype(OAVBDIMetaModel.maintaingoal_type) || !OAVBDIRuntimeModel.GOALPROCESSINGSTATE_IDLE.equals( state.getAttributeValue(de, OAVBDIRuntimeModel.goal_has_processingstate))) { // state.removeAttributeValue(scope, OAVBDIRuntimeModel.capability_has_externalaccesses, ea); e = new GoalFailureException("Goal failed: "+de+" "+state.getAttributeValue(mgoal, OAVBDIMetaModel.modelelement_has_name)); } } ret = GoalFlyweight.getGoalFlyweight(state, scope, de); } else if(OAVBDIRuntimeModel.internalevent_type.equals(type)) { // Todo: Hack!!! wrong scope ret = InternalEventFlyweight.getInternalEventFlyweight(state, scope, de); } else if(OAVBDIRuntimeModel.messageevent_type.equals(type)) { // Todo: Hack!!! wrong scope ret = MessageEventFlyweight.getMessageEventFlyweight(state, scope, de); } else if(OAVBDIRuntimeModel.changeevent_type.equals(type)) { // Todo: Hack!!! wrong scope ret = new ChangeEventFlyweight(state, scope, de); } else if(OAVBDIMetaModel.condition_type.equals(type)) { // Todo: change event for triggered condition. ret = state.getAttributeValue(de, OAVBDIMetaModel.modelelement_has_name); } } } state.removeAttributeValue(scope, OAVBDIRuntimeModel.capability_has_externalaccesses, ea); if(wa!=null) state.removeExternalObjectUsage(wa, eafly); if(observeds!=null) { BDIInterpreter ip = BDIInterpreter.getInterpreter(state); for(int i=0; i<observeds.size(); i++) ip.getEventReificator().removeObservedElement(observeds.get(i)); } if(e!=null) future.setException(e); else future.setResult(ret); } /** * Get the timeout flag. * @return True when a timeout occurred. */ public boolean isTimeout() { return timeout; } /** * Set the timeout flag to false when an event was dispatched. */ public void setTimeout(boolean timeout) { this.timeout = timeout; } }