1 | package de.uka.ipd.sdq.pcmsolver.visitors; |
2 | |
3 | import java.util.List; |
4 | |
5 | import org.apache.log4j.Logger; |
6 | import org.eclipse.emf.ecore.EObject; |
7 | |
8 | import de.uka.ipd.sdq.pcm.seff.ResourceDemandingSEFF; |
9 | import de.uka.ipd.sdq.pcm.seff.ServiceEffectSpecification; |
10 | import de.uka.ipd.sdq.pcm.usagemodel.BranchTransition; |
11 | import de.uka.ipd.sdq.pcm.usagemodel.EntryLevelSystemCall; |
12 | import de.uka.ipd.sdq.pcm.usagemodel.Loop; |
13 | import de.uka.ipd.sdq.pcm.usagemodel.ScenarioBehaviour; |
14 | import de.uka.ipd.sdq.pcm.usagemodel.UsageModel; |
15 | import de.uka.ipd.sdq.pcm.usagemodel.UsageScenario; |
16 | import de.uka.ipd.sdq.pcmsolver.models.PCMInstance; |
17 | import de.uka.ipd.sdq.pcmsolver.transformations.ContextWrapper; |
18 | |
19 | /** |
20 | * Visitor that builds up the context model including the aggregated usage context. |
21 | * Extends the UsageModelVisitor and adds the calculation of execution frequencies. |
22 | * Uses the {@link AggregatedContextSEFFVisitor} instead of the {@link SeffVisitor}. |
23 | * @author martens |
24 | * |
25 | */ |
26 | public class AggregatedContextUsageModelVisitor extends UsageModelVisitor { |
27 | |
28 | private double currentFrequency = 1; |
29 | private UsageScenario currentScenario = null; |
30 | |
31 | public AggregatedContextUsageModelVisitor(PCMInstance inst) { |
32 | super(inst); |
33 | logger = Logger.getLogger(AggregatedContextUsageModelVisitor.class.getName()); |
34 | } |
35 | |
36 | |
37 | |
38 | @Override |
39 | public Object caseUsageModel(UsageModel object) { |
40 | List<UsageScenario> scenarios = object.getUsageScenario_UsageModel(); |
41 | for (UsageScenario usageScenario : scenarios) { |
42 | currentScenario = usageScenario; |
43 | doSwitch(usageScenario.getScenarioBehaviour_UsageScenario()); |
44 | } |
45 | return null; |
46 | |
47 | } |
48 | |
49 | |
50 | |
51 | /** |
52 | * Extends {@link UsageModelVisitor#caseScenarioBehaviour(ScenarioBehaviour)}. Gets the frequency |
53 | * of the container of the object, then stores that frequency while calling |
54 | * {@link UsageModelVisitor#caseScenarioBehaviour(ScenarioBehaviour)}. |
55 | * Finally resets the frequency for handling the next action. |
56 | */ |
57 | @Override |
58 | public Object caseScenarioBehaviour(ScenarioBehaviour object) { |
59 | |
60 | // to avoid rounding errors, reset probability after the call. |
61 | double oldProbability = this.currentFrequency; |
62 | |
63 | |
64 | //determine container type |
65 | EObject container = object.eContainer(); |
66 | |
67 | if (container instanceof BranchTransition){ |
68 | BranchTransition branchTransition = (BranchTransition)container; |
69 | this.currentFrequency = this.currentFrequency * branchTransition.getBranchProbability(); |
70 | } else if (container instanceof Loop){ |
71 | Loop loop = (Loop)container; |
72 | this.currentFrequency = this.currentFrequency * ExpressionHelper.meanValue(ExpressionHelper.getSolvedExpression(loop.getLoopIteration_Loop().getSpecification(), myContextWrapper)); |
73 | } |
74 | |
75 | Object result = super.caseScenarioBehaviour(object); |
76 | |
77 | this.currentFrequency = oldProbability; |
78 | |
79 | return result; |
80 | } |
81 | |
82 | /** |
83 | * Overwrites {@link UsageModelVisitor#caseEntryLevelSystemCall(EntryLevelSystemCall)}: Created an |
84 | * {@link AggregatedContextSEFFVisitor} for visiting the next SEFF. |
85 | */ |
86 | @Override |
87 | //Copied from superclass and adjusted. |
88 | public Object caseEntryLevelSystemCall(EntryLevelSystemCall elsc) { |
89 | logger.debug("VisitEntryLevelSystemCall"); |
90 | logger.debug("Called System Method " |
91 | + elsc.getOperationSignature__EntryLevelSystemCall().getEntityName()); |
92 | |
93 | // Get List of ContextWrappers, one for each called component instance |
94 | List<ContextWrapper> contextWrapperList; |
95 | if (myContextWrapper == null) |
96 | contextWrapperList = ContextWrapper.getContextWrapperFor(elsc, pcmInstance); |
97 | else |
98 | contextWrapperList = myContextWrapper.getContextWrapperFor(elsc); |
99 | |
100 | for (ContextWrapper contextWrapper : contextWrapperList) { |
101 | ServiceEffectSpecification seff = contextWrapper.getNextSEFF(elsc); |
102 | AggregatedContextSEFFVisitor visitor = new AggregatedContextSEFFVisitor(contextWrapper, this.currentFrequency, seff, this.currentScenario); |
103 | visitor.doSwitch((ResourceDemandingSEFF) seff); |
104 | } |
105 | |
106 | //XXX: The internal myContextWrapper is not affected by the handling of the |
107 | // EntryLevelSystem call because the copies of it handle it. This was different |
108 | // before allowing replication, when only one ContextWrapper instance was used. |
109 | doSwitch(elsc.getSuccessor()); |
110 | return elsc; |
111 | } |
112 | |
113 | |
114 | } |