package jadex.bdi.runtime.interpreter; import jadex.bdi.model.OAVBDIMetaModel; import jadex.bdi.runtime.IBeliefbase; import jadex.bdi.runtime.IParameterElement; 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.ExpressionbaseFlyweight; 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.PlanFlyweight; import jadex.bdi.runtime.impl.flyweights.PlanbaseFlyweight; import jadex.bdi.runtime.impl.flyweights.PropertybaseFlyweight; import jadex.bridge.IComponentAdapter; import jadex.bridge.MessageType; import jadex.javaparser.SimpleValueFetcher; import jadex.rules.state.IOAVState; import java.lang.reflect.Array; /** * Fetcher allows to inject parameters during expression/condition evaluation. */ public class OAVBDIFetcher extends SimpleValueFetcher { //-------- attributes -------- /** The state. */ protected IOAVState state; /** The agent adapter. */ protected IComponentAdapter adapter; /** The capability. */ protected Object rcapa; /** The rgoal (if any). */ protected Object rgoal; /** The rplan (if any). */ protected Object rplan; /** The rmessageevent (if any). */ protected Object rmessageevent; /** The rinternalevent (if any). */ protected Object rinternalevent; //-------- constructors -------- /** * Create a new fetcher. */ public OAVBDIFetcher(IOAVState state, Object rcapa) { this.state = state; this.adapter = BDIInterpreter.getInterpreter(state).getAgentAdapter(); this.rcapa = rcapa; } /** * Create a new fetcher. */ public OAVBDIFetcher(IOAVState state, Object rcapa, Object relem) { this(state, rcapa); if(state.getType(relem).equals(OAVBDIRuntimeModel.goal_type)) setRGoal(relem); else if(state.getType(relem).equals(OAVBDIRuntimeModel.plan_type)) setRPlan(relem); else if(state.getType(relem).equals(OAVBDIRuntimeModel.messageevent_type)) setRMessageEvent(relem); else if(state.getType(relem).equals(OAVBDIRuntimeModel.internalevent_type)) setRInternalEvent(relem); else throw new IllegalArgumentException("Unsoppurted object: "+relem); } //-------- IValueFetcher methods -------- /** * Fetch a value via its name. * @param name The name. * @return The value. */ public Object fetchValue(String name) { Object ret = null; if(name==null) throw new RuntimeException("Name must not be null."); if(name.equals("$scope")) ret = new CapabilityFlyweight(state, rcapa); else if(name.equals("$beliefbase")) ret = BeliefbaseFlyweight.getBeliefbaseFlyweight(state, rcapa); else if(name.equals("$goalbase")) ret = GoalbaseFlyweight.getGoalbaseFlyweight(state, rcapa); else if(name.equals("$planbase")) ret = PlanbaseFlyweight.getPlanbaseFlyweight(state, rcapa); else if(name.equals("$eventbase")) ret = EventbaseFlyweight.getEventbaseFlyweight(state, rcapa); else if(name.equals("$expressionbase")) ret = ExpressionbaseFlyweight.getExpressionbaseFlyweight(state, rcapa); else if(name.equals("$propertybase")) ret = PropertybaseFlyweight.getPropertybaseFlyweight(state, rcapa); else if(name.equals("$goal") && rgoal!=null) ret = GoalFlyweight.getGoalFlyweight(state, rcapa, rgoal); else if(name.equals("$event") && rmessageevent!=null) ret = MessageEventFlyweight.getMessageEventFlyweight(state, rcapa, rmessageevent); else if(name.equals("$event") && rinternalevent!=null) ret = InternalEventFlyweight.getInternalEventFlyweight(state, rcapa, rinternalevent); else if(name.equals("$plan") && rplan!=null) ret = PlanFlyweight.getPlanFlyweight(state, rcapa, rplan); // Hack! todo: remove and replace with async service call // else if(name.equals("$clock")) // ret = BDIInterpreter.getInterpreter(state).getClockService(); else ret = super.fetchValue(name); return ret; } /** * Fetch a value via its name from an object. * @param name The name. * @param object The object. * @return The value. */ public Object fetchValue(String name, Object object) { Object ret = null; if(object instanceof IBeliefbase) { IBeliefbase bb = (IBeliefbase)object; if(bb.containsBelief(name)) ret = bb.getBelief(name).getFact(); else if(bb.containsBeliefSet(name)) ret = bb.getBeliefSet(name).getFacts(); else throw new RuntimeException("Unknown belief/set: "+name); } else if(object instanceof IParameterElement) { IParameterElement pe = (IParameterElement)object; if(pe.hasParameter(name)) { ret = pe.getParameter(name).getValue(); } else if(pe.hasParameterSet(name)) { ret = pe.getParameterSet(name).getValues(); } else { // Check if parameter exists, but has not been instantiated (return null or empty array). boolean exists = false; IOAVState state = ((ElementFlyweight)pe).getState(); Object pehandle = ((ElementFlyweight)pe).getHandle(); Object mpe = state.getAttributeValue(pehandle, OAVBDIRuntimeModel.element_has_model); if(state.getType(mpe).isSubtype(OAVBDIMetaModel.messageevent_type)) { MessageType mtype = MessageEventRules.getMessageEventType(state, mpe); MessageType.ParameterSpecification spec = mtype.getParameter(name); if(spec!=null) { exists = true; if(spec.isSet()) { ret = Array.newInstance(spec.getClazz(), 0); } } } else if(state.containsKey(mpe, OAVBDIMetaModel.parameterelement_has_parameters, name)) { exists = true; } else if(state.containsKey(mpe, OAVBDIMetaModel.parameterelement_has_parametersets, name)) { exists = true; Object paramset = state.getAttributeValue(mpe, OAVBDIMetaModel.parameterelement_has_parametersets, name); Class clazz = (Class)state.getAttributeValue(paramset, OAVBDIMetaModel.typedelement_has_class); ret = Array.newInstance(clazz, 0); } if(!exists) throw new RuntimeException("Unknown parameter/set: "+name); } } else { super.fetchValue(name, object); } return ret; } //-------- additional methods -------- /** * Set the rgoal. * @param rgoal The rgoal to set. */ public void setRGoal(Object rgoal) { this.rgoal = rgoal; } /** * Set the rplan. * @param rgoal The rplan to set. */ public void setRPlan(Object rplan) { this.rplan = rplan; } /** * Set the message event. * @param rmessageevent The rmessageevent to set. */ public void setRMessageEvent(Object rmessageevent) { this.rmessageevent = rmessageevent; } /** * Set the internal event. * @param rinternalevent The rinternalevent to set. */ public void setRInternalEvent(Object rinternalevent) { this.rinternalevent = rinternalevent; } }