1 | package de.uka.ipd.sdq.pcmsolver.visitors; |
2 | |
3 | import org.apache.log4j.Logger; |
4 | import org.eclipse.emf.common.util.EList; |
5 | |
6 | import de.uka.ipd.sdq.pcm.seff.AbstractBranchTransition; |
7 | import de.uka.ipd.sdq.pcm.seff.AbstractInternalControlFlowAction; |
8 | import de.uka.ipd.sdq.pcm.seff.AcquireAction; |
9 | import de.uka.ipd.sdq.pcm.seff.BranchAction; |
10 | import de.uka.ipd.sdq.pcm.seff.CollectionIteratorAction; |
11 | import de.uka.ipd.sdq.pcm.seff.ExternalCallAction; |
12 | import de.uka.ipd.sdq.pcm.seff.ForkAction; |
13 | import de.uka.ipd.sdq.pcm.seff.GuardedBranchTransition; |
14 | import de.uka.ipd.sdq.pcm.seff.InternalAction; |
15 | import de.uka.ipd.sdq.pcm.seff.LoopAction; |
16 | import de.uka.ipd.sdq.pcm.seff.ProbabilisticBranchTransition; |
17 | import de.uka.ipd.sdq.pcm.seff.ReleaseAction; |
18 | import de.uka.ipd.sdq.pcm.seff.ResourceDemandingBehaviour; |
19 | import de.uka.ipd.sdq.pcm.seff.ResourceDemandingSEFF; |
20 | import de.uka.ipd.sdq.pcm.seff.SetVariableAction; |
21 | import de.uka.ipd.sdq.pcm.seff.StartAction; |
22 | import de.uka.ipd.sdq.pcm.seff.StopAction; |
23 | import de.uka.ipd.sdq.pcm.seff.seff_reliability.RecoveryAction; |
24 | import de.uka.ipd.sdq.pcm.seff.util.SeffSwitch; |
25 | import de.uka.ipd.sdq.pcmsolver.handler.CollectionIteratorActionHandler; |
26 | import de.uka.ipd.sdq.pcmsolver.handler.ExternalCallActionHandler; |
27 | import de.uka.ipd.sdq.pcmsolver.handler.ForkActionHandler; |
28 | import de.uka.ipd.sdq.pcmsolver.handler.GuardedBranchTransitionHandler; |
29 | import de.uka.ipd.sdq.pcmsolver.handler.InternalActionHandler; |
30 | import de.uka.ipd.sdq.pcmsolver.handler.LoopActionHandler; |
31 | import de.uka.ipd.sdq.pcmsolver.handler.ProbabilisticBranchTransitionHandler; |
32 | import de.uka.ipd.sdq.pcmsolver.handler.RecoveryBlockActionHandler; |
33 | import de.uka.ipd.sdq.pcmsolver.handler.SetVariableActionHandler; |
34 | import de.uka.ipd.sdq.pcmsolver.transformations.ContextWrapper; |
35 | |
36 | /** |
37 | * Visitor that builds the computed usage and computed allocation contexts. |
38 | * |
39 | * @author Koziolek, Martens, Lankin, Brosch |
40 | * |
41 | */ |
42 | public class SeffVisitor extends SeffSwitch { |
43 | |
44 | /** |
45 | * Logging functionality. |
46 | */ |
47 | private static Logger logger = Logger |
48 | .getLogger(SeffVisitor.class.getName()); |
49 | |
50 | /** |
51 | * Handler for collection iterator actions. |
52 | */ |
53 | private CollectionIteratorActionHandler collectionIteratorHandler; |
54 | |
55 | /** |
56 | * Handler for external call actions. |
57 | */ |
58 | private ExternalCallActionHandler externalCallHandler; |
59 | |
60 | /** |
61 | * Handler for fork actions. |
62 | */ |
63 | private ForkActionHandler forkHandler; |
64 | |
65 | /** |
66 | * Handler for guarded branch transitions. |
67 | */ |
68 | private GuardedBranchTransitionHandler guardedBranchHandler; |
69 | |
70 | /** |
71 | * Handler for internal actions. |
72 | */ |
73 | private InternalActionHandler internalActionHandler; |
74 | |
75 | /** |
76 | * Handler for loop actions. |
77 | */ |
78 | private LoopActionHandler loopHandler; |
79 | |
80 | /** |
81 | * Handler for probabilistic branch transitions. |
82 | */ |
83 | private ProbabilisticBranchTransitionHandler probabilisticBranchHandler; |
84 | |
85 | /** |
86 | * Handler for recovery block actions. |
87 | */ |
88 | private RecoveryBlockActionHandler recoveryBlockHandler; |
89 | |
90 | /** |
91 | * Handler for set variable actions. |
92 | */ |
93 | private SetVariableActionHandler setVariableHandler; |
94 | |
95 | /** |
96 | * Context wrapper for access to context information. |
97 | */ |
98 | protected ContextWrapper contextWrapper; |
99 | |
100 | /** |
101 | * The constructor. |
102 | * |
103 | * @param wrapper |
104 | * reference to the context wrapper |
105 | */ |
106 | public SeffVisitor(final ContextWrapper wrapper) { |
107 | contextWrapper = wrapper; |
108 | externalCallHandler = new ExternalCallActionHandler(this); |
109 | internalActionHandler = new InternalActionHandler(this); |
110 | guardedBranchHandler = new GuardedBranchTransitionHandler(this); |
111 | probabilisticBranchHandler = new ProbabilisticBranchTransitionHandler( |
112 | this); |
113 | collectionIteratorHandler = new CollectionIteratorActionHandler(this); |
114 | loopHandler = new LoopActionHandler(this); |
115 | setVariableHandler = new SetVariableActionHandler(this); |
116 | recoveryBlockHandler = new RecoveryBlockActionHandler(this); |
117 | forkHandler = new ForkActionHandler(this); |
118 | } |
119 | |
120 | /** |
121 | * Handles recovery block actions. |
122 | * |
123 | * This is a workaround implementing the case for the base class of the |
124 | * RecoveryBlockAction type, as the type itself is not directly in the SEFF |
125 | * package and thus not handled by the SeffSwitch. |
126 | * |
127 | * @param action |
128 | * the recovery block action |
129 | * @return the recovery block action |
130 | */ |
131 | @Override |
132 | public Object caseAbstractInternalControlFlowAction( |
133 | final AbstractInternalControlFlowAction action) { |
134 | if (action instanceof RecoveryAction) { |
135 | logger.debug("Visit " + action.getClass().getSimpleName() + " \"" |
136 | + action.getEntityName() + "\""); |
137 | recoveryBlockHandler.handle((RecoveryAction) action); |
138 | doSwitch(action.getSuccessor_AbstractAction()); |
139 | return action; |
140 | } else { |
141 | return null; |
142 | } |
143 | } |
144 | |
145 | /** |
146 | * Handles acquire actions. |
147 | * |
148 | * Nothing to do for the dependency solver. Just goes to the next action. |
149 | * |
150 | * @param action |
151 | * the acquire action |
152 | * @return the acquire action |
153 | */ |
154 | @Override |
155 | public Object caseAcquireAction(final AcquireAction action) { |
156 | logger.debug("Visit " + action.getClass().getSimpleName() + " \"" |
157 | + action.getEntityName() + "\""); |
158 | doSwitch(action.getSuccessor_AbstractAction()); |
159 | return action; |
160 | } |
161 | |
162 | /** |
163 | * Handles branch actions. |
164 | * |
165 | * Proceeds with the inner branch transitions, then goes to the next action. |
166 | * |
167 | * @param action |
168 | * the branch action |
169 | * @return the branch action |
170 | */ |
171 | @Override |
172 | public Object caseBranchAction(final BranchAction action) { |
173 | logger.debug("Visit " + action.getClass().getSimpleName() + " \"" |
174 | + action.getEntityName() + "\""); |
175 | EList<AbstractBranchTransition> abtList = action.getBranches_Branch(); |
176 | for (AbstractBranchTransition abt : abtList) { |
177 | doSwitch(abt); |
178 | } |
179 | doSwitch(action.getSuccessor_AbstractAction()); |
180 | return action; |
181 | } |
182 | |
183 | /** |
184 | * Handles collection iterator actions. |
185 | * |
186 | * Invokes the collectionIteratorHandler, then goes to the next action. |
187 | * |
188 | * @param action |
189 | * the collection iterator action |
190 | * @return the collection iterator action |
191 | */ |
192 | @Override |
193 | public Object caseCollectionIteratorAction( |
194 | final CollectionIteratorAction action) { |
195 | logger.debug("Visit " + action.getClass().getSimpleName() + " \"" |
196 | + action.getEntityName() + "\""); |
197 | collectionIteratorHandler.handle(action); |
198 | doSwitch(action.getSuccessor_AbstractAction()); |
199 | return action; |
200 | } |
201 | |
202 | /** |
203 | * Handles external call actions. |
204 | * |
205 | * Invokes the externalCallHandler, then goes to the next action. |
206 | * |
207 | * @param action |
208 | * the external call action |
209 | * @return the external call action |
210 | */ |
211 | @Override |
212 | public Object caseExternalCallAction(final ExternalCallAction action) { |
213 | logger.debug("Visit " + action.getClass().getSimpleName() + " \"" |
214 | + action.getEntityName() + "\""); |
215 | externalCallHandler.handle(action); |
216 | doSwitch(action.getSuccessor_AbstractAction()); |
217 | return action; |
218 | } |
219 | |
220 | /** |
221 | * Handles fork actions. |
222 | * |
223 | * Invokes the forkActionHandler, then goes to the next action. |
224 | * |
225 | * @param action |
226 | * the fork action |
227 | * @return the fork action |
228 | */ |
229 | @Override |
230 | public Object caseForkAction(final ForkAction action) { |
231 | logger.debug("Visit " + action.getClass().getSimpleName() + " \"" |
232 | + action.getEntityName() + "\""); |
233 | forkHandler.handle(action); |
234 | doSwitch(action.getSuccessor_AbstractAction()); |
235 | return action; |
236 | } |
237 | |
238 | /** |
239 | * Handles guarded branch transitions. |
240 | * |
241 | * Invokes the guardedBranchHandler. |
242 | * |
243 | * @param transition |
244 | * the branch transition |
245 | * @return the branch transition |
246 | */ |
247 | @Override |
248 | public Object caseGuardedBranchTransition( |
249 | final GuardedBranchTransition transition) { |
250 | guardedBranchHandler.handle(transition); |
251 | return transition; |
252 | } |
253 | |
254 | /** |
255 | * Handles internal actions. |
256 | * |
257 | * Invokes the internalActionHandler, then goes to the next action. |
258 | * |
259 | * @param action |
260 | * the internal action |
261 | * @return the internal action |
262 | */ |
263 | @Override |
264 | public Object caseInternalAction(final InternalAction action) { |
265 | logger.debug("Visit " + action.getClass().getSimpleName() + " \"" |
266 | + action.getEntityName() + "\""); |
267 | internalActionHandler.handle(action); |
268 | doSwitch(action.getSuccessor_AbstractAction()); |
269 | return action; |
270 | } |
271 | |
272 | /** |
273 | * Handles loop actions. |
274 | * |
275 | * Invokes the loopActionHandler, then goes to the next action. |
276 | * |
277 | * @param action |
278 | * the loop action |
279 | * @return the loop action |
280 | */ |
281 | @Override |
282 | public Object caseLoopAction(final LoopAction action) { |
283 | logger.debug("Visit " + action.getClass().getSimpleName() + " \"" |
284 | + action.getEntityName() + "\""); |
285 | loopHandler.handle(action); |
286 | doSwitch(action.getSuccessor_AbstractAction()); |
287 | return action; |
288 | } |
289 | |
290 | /** |
291 | * Handles probabilistic branch transitions. |
292 | * |
293 | * Invokes the probabilisticBranchHandler, then goes to the next action. |
294 | * |
295 | * @param transition |
296 | * the branch transition |
297 | * @return the branch transition |
298 | */ |
299 | @Override |
300 | public Object caseProbabilisticBranchTransition( |
301 | final ProbabilisticBranchTransition transition) { |
302 | probabilisticBranchHandler.handle(transition); |
303 | return transition; |
304 | } |
305 | |
306 | /** |
307 | * Handles release actions. |
308 | * |
309 | * Nothing to do for the dependency solver. Just goes to the next action. |
310 | * |
311 | * @param action |
312 | * the release action |
313 | * @return the release action |
314 | */ |
315 | @Override |
316 | public Object caseReleaseAction(final ReleaseAction action) { |
317 | logger.debug("Visit " + action.getClass().getSimpleName() + " \"" |
318 | + action.getEntityName() + "\""); |
319 | doSwitch(action.getSuccessor_AbstractAction()); |
320 | return action; |
321 | } |
322 | |
323 | /** |
324 | * Handles resource demanding behaviours. |
325 | * |
326 | * Goes to the first action within the behaviour. |
327 | * |
328 | * @param behaviour |
329 | * the resource demanding behaviour |
330 | * @return the resource demanding behaviour |
331 | */ |
332 | @Override |
333 | public Object caseResourceDemandingBehaviour( |
334 | final ResourceDemandingBehaviour behaviour) { |
335 | doSwitch(getStartAction(behaviour)); |
336 | return behaviour; |
337 | } |
338 | |
339 | /** |
340 | * Handles resource demanding seffs. |
341 | * |
342 | * Goes to the first action within the seff. |
343 | * |
344 | * @param behaviour |
345 | * the resource demanding seff |
346 | * @return the resource demanding seff |
347 | */ |
348 | @Override |
349 | public Object caseResourceDemandingSEFF( |
350 | final ResourceDemandingSEFF behaviour) { |
351 | ResourceDemandingBehaviour rdb = (ResourceDemandingBehaviour) behaviour; |
352 | doSwitch(getStartAction(rdb)); |
353 | return behaviour; |
354 | } |
355 | |
356 | /** |
357 | * Handles set variable actions. |
358 | * |
359 | * Invokes the setVariableHandler, then goes to the next action. |
360 | * |
361 | * @param action |
362 | * the set variable action |
363 | * @return the set variable action |
364 | */ |
365 | @Override |
366 | public Object caseSetVariableAction(final SetVariableAction action) { |
367 | logger.debug("Visit " + action.getClass().getSimpleName() + " \"" |
368 | + action.getEntityName() + "\""); |
369 | setVariableHandler.handle(action); |
370 | doSwitch(action.getSuccessor_AbstractAction()); |
371 | return action; |
372 | } |
373 | |
374 | /** |
375 | * Handles start actions. |
376 | * |
377 | * Nothing to do for the dependency solver. Just goes to the next action. |
378 | * |
379 | * @param action |
380 | * the start action |
381 | * @return the start action |
382 | */ |
383 | @Override |
384 | public Object caseStartAction(final StartAction action) { |
385 | logger.debug("Visit " + action.getClass().getSimpleName() + " \"" |
386 | + action.getEntityName() + "\""); |
387 | doSwitch(action.getSuccessor_AbstractAction()); |
388 | return action; |
389 | } |
390 | |
391 | /** |
392 | * Handles stop actions. |
393 | * |
394 | * Saves the contexts that have been created for the surrounding resource |
395 | * demanding seff. |
396 | * |
397 | * @param action |
398 | * the stop action |
399 | * @return the stop action |
400 | */ |
401 | @Override |
402 | public Object caseStopAction(final StopAction action) { |
403 | logger.debug("Visit " + action.getClass().getSimpleName() + " \"" |
404 | + action.getEntityName() + "\""); |
405 | if (action.eContainer() instanceof ResourceDemandingSEFF) { |
406 | saveContexts(); |
407 | } |
408 | // no more doSwitch, visitor ends here! |
409 | return action; |
410 | } |
411 | |
412 | /** |
413 | * Retrieves the context wrapper. |
414 | * |
415 | * @return the context wrapper |
416 | */ |
417 | public ContextWrapper getContextWrapper() { |
418 | return contextWrapper; |
419 | } |
420 | |
421 | /** |
422 | * Sets the context wrapper. |
423 | * |
424 | * @param wrapper |
425 | * the context wrapper |
426 | */ |
427 | public void setContextWrapper(final ContextWrapper wrapper) { |
428 | contextWrapper = wrapper; |
429 | } |
430 | |
431 | /** |
432 | * Searches for a StartAction within the chain of AbstractActions of the |
433 | * behaviour and returns it. |
434 | * |
435 | * @param behaviour |
436 | * the behaviour |
437 | * @return the start action |
438 | */ |
439 | private StartAction getStartAction( |
440 | final ResourceDemandingBehaviour behaviour) { |
441 | StartAction startAction = (StartAction) EMFQueryHelper.getObjectByType( |
442 | behaviour.getSteps_Behaviour(), StartAction.class); |
443 | return startAction; |
444 | } |
445 | |
446 | /** |
447 | * Stores the just built usage and actual allocation context to the PCM |
448 | * instance. |
449 | */ |
450 | private void saveContexts() { |
451 | // ComputedUsageContext usageContext = contextWrapper.getCompUsgCtx(); |
452 | // contextWrapper.getPcmInstance().getComputedUsage().getUsageContexts_ComputedUsage().add(usageContext); |
453 | // ComputedAllocationContext actAll = contextWrapper.getCompAllCtx(); |
454 | // contextWrapper.getPcmInstance().getComputedAllocation().getComputedAllocationContexts_ComputedAllocation().add(actAll); |
455 | } |
456 | } |