1 | package de.uka.ipd.sdq.pcmsolver.transformations.pcm2regex; |
2 | |
3 | import java.util.ArrayList; |
4 | import java.util.LinkedList; |
5 | import java.util.List; |
6 | |
7 | import org.apache.log4j.Logger; |
8 | |
9 | import de.uka.ipd.sdq.pcm.core.composition.ProvidedDelegationConnector; |
10 | import de.uka.ipd.sdq.pcm.repository.BasicComponent; |
11 | import de.uka.ipd.sdq.pcm.repository.OperationProvidedRole; |
12 | import de.uka.ipd.sdq.pcm.repository.RepositoryComponent; |
13 | import de.uka.ipd.sdq.pcm.repository.Signature; |
14 | import de.uka.ipd.sdq.pcm.seff.AbstractBranchTransition; |
15 | import de.uka.ipd.sdq.pcm.seff.ResourceDemandingSEFF; |
16 | import de.uka.ipd.sdq.pcm.seff.ServiceEffectSpecification; |
17 | import de.uka.ipd.sdq.pcm.usagemodel.Branch; |
18 | import de.uka.ipd.sdq.pcm.usagemodel.BranchTransition; |
19 | import de.uka.ipd.sdq.pcm.usagemodel.EntryLevelSystemCall; |
20 | import de.uka.ipd.sdq.pcm.usagemodel.Loop; |
21 | import de.uka.ipd.sdq.pcm.usagemodel.ScenarioBehaviour; |
22 | import de.uka.ipd.sdq.pcm.usagemodel.Start; |
23 | import de.uka.ipd.sdq.pcm.usagemodel.Stop; |
24 | import de.uka.ipd.sdq.pcm.usagemodel.util.UsagemodelSwitch; |
25 | import de.uka.ipd.sdq.pcmsolver.models.PCMInstance; |
26 | import de.uka.ipd.sdq.pcmsolver.transformations.ContextWrapper; |
27 | import de.uka.ipd.sdq.pcmsolver.visitors.EMFQueryHelper; |
28 | import de.uka.ipd.sdq.probfunction.math.IProbabilityFunctionFactory; |
29 | import de.uka.ipd.sdq.spa.expression.Alternative; |
30 | import de.uka.ipd.sdq.spa.expression.Expression; |
31 | import de.uka.ipd.sdq.spa.expression.ExpressionFactory; |
32 | import de.uka.ipd.sdq.spa.expression.Option; |
33 | import de.uka.ipd.sdq.spa.expression.Sequence; |
34 | import de.uka.ipd.sdq.spa.expression.Symbol; |
35 | import de.uka.ipd.sdq.stoex.RandomVariable; |
36 | |
37 | public class TransformUsageModelVisitor extends UsagemodelSwitch { |
38 | |
39 | private static Logger logger = Logger.getLogger(TransformUsageModelVisitor.class.getName()); |
40 | |
41 | private ExpressionFactory expFactory = ExpressionFactory.eINSTANCE; |
42 | private IProbabilityFunctionFactory pfFactory = IProbabilityFunctionFactory.eINSTANCE; |
43 | |
44 | private PCMInstance pcmInstance; |
45 | private ContextWrapper myContextWrapper = null; |
46 | |
47 | public TransformUsageModelVisitor(PCMInstance pcm){ |
48 | pcmInstance = pcm; |
49 | } |
50 | |
51 | @Override |
52 | public Object caseStart(Start object) { |
53 | Symbol sym = expFactory.createSymbol(); |
54 | sym.setName("Start"); |
55 | |
56 | Sequence seq = expFactory.createSequence(); |
57 | seq.setLeftRegExp(sym); |
58 | seq.setRightRegExp((Expression)doSwitch(object.getSuccessor())); |
59 | |
60 | return seq; |
61 | } |
62 | |
63 | @Override |
64 | public Object caseStop(Stop object) { |
65 | Symbol sym = expFactory.createSymbol(); |
66 | sym.setName("Stop"); |
67 | return sym; |
68 | } |
69 | |
70 | @Override |
71 | public Object caseEntryLevelSystemCall(EntryLevelSystemCall object) { |
72 | // Get List of ContextWrappers, one for each called component instance |
73 | List<ContextWrapper> contextWrapperList; |
74 | if (myContextWrapper == null) |
75 | contextWrapperList = ContextWrapper.getContextWrapperFor(object, pcmInstance); |
76 | else |
77 | contextWrapperList = myContextWrapper.getContextWrapperFor(object); |
78 | |
79 | List<Option> optionsPerContextWrapperList = new LinkedList<Option>(); |
80 | for (ContextWrapper contextWrapper : contextWrapperList) { |
81 | |
82 | // calculate the expression for the contextWrapper in the list iteration |
83 | myContextWrapper = contextWrapper; |
84 | |
85 | Option option = expFactory.createOption(); |
86 | option.setRegexp(getEntryExpression(object)); |
87 | option.setProbability(1/contextWrapperList.size()); |
88 | optionsPerContextWrapperList.add(option); |
89 | } |
90 | Expression exp = null; |
91 | if (optionsPerContextWrapperList.size() == 1){ |
92 | exp = optionsPerContextWrapperList.get(0).getRegexp(); |
93 | } else { |
94 | exp = Pcm2RegexHelper.createAlternativesForExpressions(optionsPerContextWrapperList); |
95 | } |
96 | Sequence seq = expFactory.createSequence(); |
97 | seq.setLeftRegExp(exp); |
98 | seq.setRightRegExp((Expression)doSwitch(object.getSuccessor())); |
99 | |
100 | return seq; |
101 | |
102 | } |
103 | |
104 | |
105 | |
106 | private Expression getEntryExpression(EntryLevelSystemCall object) { |
107 | OperationProvidedRole role = object.getProvidedRole_EntryLevelSystemCall(); |
108 | ProvidedDelegationConnector delegationConnector = getDelegationConnector(role); |
109 | RepositoryComponent offeringComponent = delegationConnector |
110 | .getAssemblyContext_ProvidedDelegationConnector() |
111 | .getEncapsulatedComponent__AssemblyContext(); |
112 | |
113 | Expression expr = null; |
114 | ServiceEffectSpecification seff = myContextWrapper.getNextSEFF(object); |
115 | TransformSeffVisitor seffVisitor = new TransformSeffVisitor(myContextWrapper); |
116 | try { |
117 | expr = (Expression)seffVisitor.doSwitch((ResourceDemandingSEFF) seff); |
118 | } catch (Exception e) { |
119 | logger.error("Error while visiting RDSEFF"); |
120 | e.printStackTrace(); |
121 | } |
122 | |
123 | return expr; |
124 | } |
125 | |
126 | @Override |
127 | public Object caseBranch(Branch object) { |
128 | |
129 | List<Option> optionsForBranches = new LinkedList<Option>(); |
130 | |
131 | for (BranchTransition branch : object.getBranchTransitions_Branch()) { |
132 | Option option = expFactory.createOption(); |
133 | option.setProbability(branch.getBranchProbability()); |
134 | Expression branchExpression = (Expression)doSwitch(branch.getBranchedBehaviour_BranchTransition()); |
135 | option.setRegexp(branchExpression); |
136 | |
137 | optionsForBranches.add(option); |
138 | } |
139 | Expression alt = Pcm2RegexHelper.createAlternativesForExpressions(optionsForBranches); |
140 | |
141 | Sequence seq = expFactory.createSequence(); |
142 | seq.setLeftRegExp(alt); |
143 | seq.setRightRegExp((Expression)doSwitch(object.getSuccessor())); |
144 | |
145 | return seq; |
146 | } |
147 | |
148 | @Override |
149 | public Object caseLoop(Loop object) { |
150 | de.uka.ipd.sdq.spa.expression.Loop loop = expFactory.createLoop(); |
151 | RandomVariable iterations = (RandomVariable)object.getLoopIteration_Loop(); |
152 | loop.setIterationsString(iterations.getSpecification()); |
153 | loop.setRegExp((Expression)doSwitch(object.getBodyBehaviour_Loop())); |
154 | |
155 | Sequence seq = expFactory.createSequence(); |
156 | seq.setLeftRegExp(loop); |
157 | seq.setRightRegExp((Expression)doSwitch(object.getSuccessor())); |
158 | |
159 | return seq; |
160 | } |
161 | |
162 | @Override |
163 | public Object caseScenarioBehaviour(ScenarioBehaviour object) { |
164 | return doSwitch(getStartAction(object)); |
165 | } |
166 | |
167 | private Start getStartAction(ScenarioBehaviour object) { |
168 | Start startAction = (Start) EMFQueryHelper.getObjectByType(object |
169 | .getActions_ScenarioBehaviour(), Start.class); |
170 | return startAction; |
171 | } |
172 | |
173 | private ProvidedDelegationConnector getDelegationConnector( |
174 | OperationProvidedRole role) { |
175 | ProvidedDelegationConnector delegationConnector = |
176 | (ProvidedDelegationConnector) EMFQueryHelper |
177 | .executeOCLQuery( |
178 | pcmInstance.getSystem(), |
179 | "self.connectors__ComposedStructure->select(dc|dc.oclIsTypeOf(composition::ProvidedDelegationConnector) and dc.oclAsType(composition::ProvidedDelegationConnector).outerProvidedRole_ProvidedDelegationConnector.providedInterface__OperationProvidedRole.id = '" |
180 | + role.getProvidedInterface__OperationProvidedRole() |
181 | .getId() |
182 | + "')->asOrderedSet()->first()"); |
183 | return delegationConnector; |
184 | |
185 | } |
186 | |
187 | /** |
188 | * @param method |
189 | * @param basicComponent |
190 | * @return |
191 | */ |
192 | private ServiceEffectSpecification getSeff(Signature method, |
193 | BasicComponent basicComponent) { |
194 | ServiceEffectSpecification seff = (ServiceEffectSpecification) EMFQueryHelper |
195 | .executeOCLQuery( |
196 | basicComponent, |
197 | "self.serviceEffectSpecifications__BasicComponent->select(seff|seff.describedService__SEFF.serviceName = '" |
198 | + method.getEntityName() |
199 | + "')->asOrderedSet()->first()"); |
200 | return seff; |
201 | } |
202 | } |