| 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 | } |