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