View Javadoc

1   package cz.cuni.amis.pogamut.sposh.engine;
2   
3   import cz.cuni.amis.pogamut.sposh.elements.ActionPattern;
4   import cz.cuni.amis.pogamut.sposh.elements.Adopt;
5   import cz.cuni.amis.pogamut.sposh.elements.Competence;
6   import cz.cuni.amis.pogamut.sposh.elements.LapPath;
7   import cz.cuni.amis.pogamut.sposh.elements.LapType;
8   import cz.cuni.amis.pogamut.sposh.elements.PoshPlan;
9   import cz.cuni.amis.pogamut.sposh.elements.PrimitiveCall;
10  import cz.cuni.amis.pogamut.sposh.elements.TriggeredAction;
11  import cz.cuni.amis.pogamut.sposh.exceptions.FubarException;
12  
13  /**
14   * Predecesor of all executors, basically provides only logging infrastructure.
15   * @author Honza
16   */
17  abstract class AbstractExecutor {
18      /**
19       * Path to the element this executor is representing.
20       */
21      protected final LapPath path;
22      /**
23       * Variable context in the element the executor is representing.
24       */
25      protected final VariableContext ctx;
26      /**
27       * Logger of execution of executor.
28       */
29      protected final EngineLog engineLog;
30      
31      /**
32       * Create new executor.
33       * @param path Path to the element this executor is processing.
34       * @param ctx Variable context in the body of an element represented by the executor.
35       * @param engineLog Log used to record info about execution of the plan by the engine.
36       */
37      protected AbstractExecutor(LapPath path, VariableContext ctx, EngineLog engineLog) {
38          this.path = path;
39          this.ctx = ctx;
40          this.engineLog = engineLog;
41      }
42  
43      public final LapPath getPath() {
44          return path;
45      }
46      
47      private StackElement<ADExecutor> getElementAD(PoshPlan plan, PrimitiveCall adaptCall, LapPath referencePath) {
48      	String adoptName = adaptCall.getName();
49          Adopt adopt = plan.getAD(adoptName);
50          if (adopt == null) {
51              return null;
52          }
53          int adoptId = plan.getAdoptId(adopt);
54          
55          assert plan.getAdopts().get(adoptId) == adopt;
56          
57          LapPath adoptPath = referencePath.concat(LapType.ADOPT, adoptId);
58          VariableContext adoptContext = new VariableContext(ctx, adaptCall.getParameters(), adopt.getParameters());
59          ADExecutor adoptExecutor = new ADExecutor(plan, adopt, adoptPath, adoptContext, engineLog);
60          
61          return new StackElement<ADExecutor>(Adopt.class, adoptName, adoptExecutor);
62      }
63      
64      private StackElement<APExecutor> getElementAP(PoshPlan plan, PrimitiveCall actionPatternCall, LapPath referencePath) {
65      	String actionPatternName = actionPatternCall.getName();
66          ActionPattern actionPattern = plan.getAP(actionPatternName);
67          if (actionPattern == null) {
68              return null;
69          }
70          int actionPatternId = plan.getActionPatternId(actionPattern);
71          
72          assert plan.getActionPatterns().get(actionPatternId) == actionPattern;
73          
74          LapPath actionPatternPath = referencePath.concat(LapType.ACTION_PATTERN, actionPatternId);
75          VariableContext actionPatternContext = new VariableContext(ctx, actionPatternCall.getParameters(), actionPattern.getParameters());
76          APExecutor actionPatternExecutor = new APExecutor(plan, actionPattern, FireResult.Type.SURFACE, actionPatternPath, actionPatternContext, engineLog);
77  
78          return new StackElement<APExecutor>(ActionPattern.class, actionPatternName, actionPatternExecutor);
79      }
80      
81      /**
82       * Get competence executor for @competenceCall if exists. If such competence
83       * doesn't exists, return null.
84       *
85       * @param plan Plan in which we are looking for competence with name
86       * retrieved from @competenceCall.
87       * @param competenceCall Reference to the competence in the plan.
88       * @param referencePath Path ending with reference (i.e. {@link LapType#ACTION).
89       * @return new wrapped executor if competence of @competenceCall exists,
90       * otherwise null.
91       */
92      private StackElement<CExecutor> getElementC(PoshPlan plan, PrimitiveCall competenceCall, LapPath referencePath) {
93          String competenceName = competenceCall.getName();
94          Competence competence = plan.getC(competenceName);
95          if (competence == null) {
96              return null;
97          }
98          int competenceId = plan.getCompetenceId(competence);
99  
100         assert plan.getCompetences().get(competenceId) == competence;
101 
102         LapPath competencePath = referencePath.concat(LapType.COMPETENCE, competenceId);
103         VariableContext competenceContext = new VariableContext(ctx, competenceCall.getParameters(), competence.getParameters());
104         CExecutor competenceExecutor = new CExecutor(plan, competence, competencePath, competenceContext, engineLog);
105 
106         return new StackElement<CExecutor>(Competence.class, competenceName, competenceExecutor);
107     }
108     
109     /**
110      * Create executor for a primitive action.
111      *
112      * @param referencePath Path referencing the action. Note that {@link LapPath}
113      * doesn't extend into primitives, thus the @referencePath will end with
114      * link of type {@link LapType#ACTION}.
115      * @return
116      */
117     private StackElement<ActionExecutor> getElementAction(
118     		PoshPlan plan, 
119             PrimitiveCall actionCall, 
120             LapPath referencePath,
121 		    Runnable finishedResultCallback, 
122             Runnable runningResultCallback, 
123             Runnable runningOnceResultCallback, 
124             Runnable failedResultCallback)
125     {
126 		String actionName = actionCall.getName();
127         ActionExecutor actionExecutor = new ActionExecutor(actionCall,
128                 finishedResultCallback, runningResultCallback, runningOnceResultCallback, failedResultCallback,
129                 referencePath, new VariableContext(ctx, actionCall.getParameters()), engineLog);
130 
131 		return new StackElement<ActionExecutor>(TriggeredAction.class, actionName, actionExecutor);
132 	}
133     
134     protected StackElement getElement(PoshPlan plan, PrimitiveCall actionCall, LapPath referencePath) {
135     	return getElement(plan, actionCall, referencePath,
136                 null, null, null, null);
137     }
138     
139     /**
140      * Create executor for element referenced by the @actionCall and encapsulate
141      * it in the {@link StackElement}. The @actionCall can reference to AP, AD,
142      * C or simple primitive action. This method will find correct element that
143      * is being referenced and creates an executor for it.
144      *
145      * <b>IMPORTANT:</b> The action*Result and *Callbacks are used only for
146      * action. They are ignored if @actionCall references something else (i.e.
147      * not an primitive action).
148      *
149      * @param plan Plan in which we use to look for element referenced by @actionCall.
150      * @param actionCall Reference to some unknown element in the @plan.
151      * @param referencePath Path up to the reference. The path will end with {@link LapType#ACTION}
152      * (i.e. reference), e.g. <tt>/P:0/DC:0/DE:4/A:0</tt>, the last link is A:0,
153      * the reference of fourth drive.
154      * @param finishedResultCallback
155      * @param runningResultCallback
156      * @param runningOnceCallback
157      * @param failedResultCallback
158      * @return 
159      */
160     protected StackElement getElement(PoshPlan plan, PrimitiveCall actionCall, LapPath referencePath,
161 			  						  Runnable finishedResultCallback, 
162                                       Runnable runningResultCallback, 
163                                       Runnable runningOnceCallback, 
164                                       Runnable failedResultCallback
165     ) {
166     	StackElement stackElement = getElementC(plan, actionCall, referencePath);
167     	
168 		if (stackElement == null) {
169 			stackElement = getElementAP(plan, actionCall, referencePath);
170 			if (stackElement == null) {
171 				stackElement = getElementAD(plan, actionCall, referencePath);
172 				if (stackElement == null) {
173 					stackElement = getElementAction(plan, actionCall, referencePath,
174 													finishedResultCallback,
175 													runningResultCallback,
176 													runningOnceCallback,
177 													failedResultCallback
178 				    );
179 				}
180 			}
181 		}
182 		
183 		return stackElement;    	
184     }
185 }