EMMA Coverage Report (generated Sun Feb 05 10:43:15 CET 2012)
[all classes][de.uka.ipd.sdq.pcmsolver.visitors]

COVERAGE SUMMARY FOR SOURCE FILE [AggregatedContextSEFFVisitor.java]

nameclass, %method, %block, %line, %
AggregatedContextSEFFVisitor.java0%   (0/1)0%   (0/11)0%   (0/578)0%   (0/130)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class AggregatedContextSEFFVisitor0%   (0/1)0%   (0/11)0%   (0/578)0%   (0/130)
AggregatedContextSEFFVisitor (ContextWrapper, double, ServiceEffectSpecificat... 0%   (0/1)0%   (0/32)0%   (0/9)
addToAggregatedUsage (ResourceType, double): void 0%   (0/1)0%   (0/53)0%   (0/14)
caseExternalCallAction (ExternalCallAction): Object 0%   (0/1)0%   (0/63)0%   (0/15)
caseInternalAction (InternalAction): Object 0%   (0/1)0%   (0/37)0%   (0/8)
caseResourceDemandingBehaviour (ResourceDemandingBehaviour): Object 0%   (0/1)0%   (0/140)0%   (0/26)
caseResourceDemandingSEFF (ResourceDemandingSEFF): Object 0%   (0/1)0%   (0/10)0%   (0/3)
createOrReuseAggregatedCommunication (ServiceExecutionContext, ServiceExecuti... 0%   (0/1)0%   (0/37)0%   (0/11)
createOrReuseExecutionContext (ResourceDemandingSEFF, AllocationContext, Usag... 0%   (0/1)0%   (0/71)0%   (0/18)
findCommunicationLink (ServiceExecutionContext, ServiceExecutionContext): Com... 0%   (0/1)0%   (0/95)0%   (0/15)
getCurrentFrequency (): double 0%   (0/1)0%   (0/3)0%   (0/1)
isOrContainsAssemblyContext (AssemblyContext, AssemblyContext): boolean 0%   (0/1)0%   (0/37)0%   (0/10)

1package de.uka.ipd.sdq.pcmsolver.visitors;
2 
3import java.util.List;
4 
5import org.eclipse.emf.ecore.EObject;
6 
7import de.uka.ipd.sdq.context.aggregatedUsageContext.AggregatedCommunication;
8import de.uka.ipd.sdq.context.aggregatedUsageContext.AggregatedResourceDemand;
9import de.uka.ipd.sdq.context.aggregatedUsageContext.AggregatedUsageContextFactory;
10import de.uka.ipd.sdq.context.aggregatedUsageContext.ComputedAggregatedUsage;
11import de.uka.ipd.sdq.context.aggregatedUsageContext.ServiceExecutionContext;
12import de.uka.ipd.sdq.context.computed_usage.BranchProbability;
13import de.uka.ipd.sdq.context.computed_usage.LoopIteration;
14import de.uka.ipd.sdq.pcm.allocation.Allocation;
15import de.uka.ipd.sdq.pcm.allocation.AllocationContext;
16import de.uka.ipd.sdq.pcm.core.composition.AssemblyContext;
17import de.uka.ipd.sdq.pcm.repository.CompositeComponent;
18import de.uka.ipd.sdq.pcm.repository.RepositoryComponent;
19import de.uka.ipd.sdq.pcm.resourceenvironment.CommunicationLinkResourceSpecification;
20import de.uka.ipd.sdq.pcm.resourceenvironment.LinkingResource;
21import de.uka.ipd.sdq.pcm.resourceenvironment.ResourceContainer;
22import de.uka.ipd.sdq.pcm.resourcetype.ResourceType;
23import de.uka.ipd.sdq.pcm.seff.AbstractAction;
24import de.uka.ipd.sdq.pcm.seff.AbstractBranchTransition;
25import de.uka.ipd.sdq.pcm.seff.AbstractLoopAction;
26import de.uka.ipd.sdq.pcm.seff.ExternalCallAction;
27import de.uka.ipd.sdq.pcm.seff.InternalAction;
28import de.uka.ipd.sdq.pcm.seff.ResourceDemandingBehaviour;
29import de.uka.ipd.sdq.pcm.seff.ResourceDemandingSEFF;
30import de.uka.ipd.sdq.pcm.seff.ServiceEffectSpecification;
31import de.uka.ipd.sdq.pcm.seff.seff_performance.ParametricResourceDemand;
32import de.uka.ipd.sdq.pcm.usagemodel.BranchTransition;
33import de.uka.ipd.sdq.pcm.usagemodel.UsageScenario;
34import de.uka.ipd.sdq.pcmsolver.handler.AggregatedContextExternalCallActionHandler;
35import de.uka.ipd.sdq.pcmsolver.handler.ExternalCallActionHandler;
36import de.uka.ipd.sdq.pcmsolver.transformations.ContextWrapper;
37import de.uka.ipd.sdq.stoex.Expression;
38 
39/**
40 * Visitor that builds up the context model including the aggregated usage context. 
41 * Extends the {@link SeffVisitor} and adds the calculation of execution frequencies. 
42 * Uses the {@link AggregatedContextExternalCallActionHandler} instead of the {@link ExternalCallActionHandler}.
43 * @author martens
44 *
45 */
46public class AggregatedContextSEFFVisitor extends SeffVisitor {
47 
48        private double currentFrequency;
49        private ServiceExecutionContext computedAggregatedUsage;
50        private UsageScenario usageScenario;
51        
52        public AggregatedContextSEFFVisitor(ContextWrapper ctxWrp, double frequency, ServiceEffectSpecification seff, UsageScenario currentScenario) {
53                super(ctxWrp);
54                this.currentFrequency = frequency;
55                this.usageScenario = currentScenario;
56                
57                if (seff instanceof ResourceDemandingSEFF){
58                                ResourceDemandingSEFF rdSEFF = (ResourceDemandingSEFF)seff;
59                        //AssemblyContext assemblyContext = ctxWrp.getAssCtx();
60                        AllocationContext allocationContext = ctxWrp.getAllCtx();
61                        ctxWrp.getAllCtx();
62                        //check if context is already there for this system. If yes, use it
63                        this.computedAggregatedUsage = createOrReuseExecutionContext(rdSEFF, allocationContext, this.usageScenario, this.currentFrequency);
64                }
65                
66 
67                
68        }
69 
70        /**
71         * Extends {@link SeffVisitor#caseResourceDemandingSEFF(ResourceDemandingSEFF)}: stores the described SEFF
72         * in the {@link ComputedAggregatedUsage}. 
73         * Then calls {@link SeffVisitor#caseResourceDemandingSEFF(ResourceDemandingSEFF)}. 
74         * 
75         * {@inheritDoc}.
76         */
77        @Override
78        public Object caseResourceDemandingSEFF(ResourceDemandingSEFF seff) {
79                this.computedAggregatedUsage.setDescribedSEFF_ServiceExecutionContext(seff);
80                Object object = super.caseResourceDemandingSEFF(seff);
81                
82                return object;
83        }
84 
85        /**
86         * Overwrites the {@link SeffVisitor#caseExternalCallAction(ExternalCallAction)}. 
87         * Does the same, but uses an {@link AggregatedContextExternalCallActionHandler} to handle the call, 
88         * which in turn will instantiate an {@link AggregatedContextSEFFVisitor} for the next SEFF. 
89         */
90        @Override
91        public Object caseExternalCallAction(ExternalCallAction call) {
92                
93                
94                AggregatedContextExternalCallActionHandler extCallAH = new AggregatedContextExternalCallActionHandler(this, this.usageScenario);
95                extCallAH.handle(call);
96        
97                ServiceEffectSpecification seff = extCallAH.getCalledSEFF();
98                if (seff instanceof ResourceDemandingSEFF){
99                        ResourceDemandingSEFF rdSEFF = (ResourceDemandingSEFF)seff;
100                        
101                        //AssemblyContext assemblyContext = extCallAH.getCalledAssemblyCtxt();
102                        AllocationContext allocationContext = extCallAH.getCalledAllocationContext();
103                        
104                        //frequency will be set by the next seff visitor that visits that seff.
105                        ServiceExecutionContext calleeComputedAggregatedUsage = createOrReuseExecutionContext(rdSEFF, allocationContext, this.usageScenario, 0.0);
106                                        
107                        //the new usage is a communication partner, add communication info. 
108                        AggregatedCommunication communication = createOrReuseAggregatedCommunication(this.computedAggregatedUsage, calleeComputedAggregatedUsage);
109                        
110                        double oldFrequency = communication.getAverageMessageFrequency();
111                        communication.setAverageMessageFrequency(oldFrequency + this.currentFrequency);
112                        
113                        // get link on which the message is sent
114                        CommunicationLinkResourceSpecification link = findCommunicationLink(this.computedAggregatedUsage, calleeComputedAggregatedUsage);
115                        
116                        //link is null if this is a local
117                        if (link != null){
118                                communication.setUsedCommunicationLinkResourceSpecification_AggregatedCommunication(link);
119                        }
120                        
121                        //TODO add message size
122                        //XXX consider return call? there always is a return call so far.
123                }
124                
125                doSwitch(call.getSuccessor_AbstractAction());
126                return call;
127        }
128 
129        /**
130         * Returns null if communication is local. 
131         * @param callerComputedAggregatedUsage
132         * @param calleeComputedAggregatedUsage
133         * @return
134         */
135        private CommunicationLinkResourceSpecification findCommunicationLink(
136                        ServiceExecutionContext callerComputedAggregatedUsage,
137                        ServiceExecutionContext calleeComputedAggregatedUsage) {
138                
139                //AssemblyContext assemblyFrom = callerComputedAggregatedUsage.getAssemblyContext_ServiceExecutionContext();
140                //AssemblyContext assemblyTo = calleeComputedAggregatedUsage.getAssemblyContext_ServiceExecutionContext();
141                AllocationContext to = calleeComputedAggregatedUsage.getAllocationContext_ServiceExecutionContext();
142                
143                AllocationContext from = this.contextWrapper.getAllCtx();
144                
145                Allocation allocation = this.contextWrapper.getPcmInstance().getAllocation();
146                
147                /*AllocationContext to = null;
148                for (AllocationContext allocationContext : allocation.getAllocationContexts_Allocation()) {
149                        
150                        AssemblyContext currentAssemblyContext = allocationContext.getAssemblyContext_AllocationContext();
151                        // look inside assembled component to see whether the search assembly context assemblyTo in contained
152                        if (isOrContainsAssemblyContext(currentAssemblyContext, assemblyTo)){
153                                to = allocationContext;
154                        } 
155                        if (to != null)
156                                break;
157                }*/
158                
159                if (to != null){
160                        
161                        ResourceContainer fromResourceContainer = from.getResourceContainer_AllocationContext();
162                        ResourceContainer toResourceContainer = to.getResourceContainer_AllocationContext();
163                        
164                        //local communication? then return null.
165                        if (fromResourceContainer == toResourceContainer)
166                                return null;
167                        
168                        List<LinkingResource> linkingResourceList = this.contextWrapper.getPcmInstance().getResourceEnvironment().getLinkingResources__ResourceEnvironment();
169                        for (LinkingResource linkingResource : linkingResourceList) {
170                                if (linkingResource.getConnectedResourceContainers_LinkingResource().contains(fromResourceContainer)
171                                                && linkingResource.getConnectedResourceContainers_LinkingResource().contains(toResourceContainer)){
172                                        return linkingResource.getCommunicationLinkResourceSpecifications_LinkingResource();
173                                }
174                        }
175                        throw new RuntimeException("The communication between allocation contexts "+to.getEntityName()+" and "+from.getEntityName()+" is remote, but there is no linking resource between them. Add a linking resource.");
176                        
177                }
178                throw new RuntimeException(this.getClass().getName()+": Could not determine allocation of "+calleeComputedAggregatedUsage.getDescribedSEFF_ServiceExecutionContext().getDescribedService__SEFF().getEntityName()+" to determine communication partners.");
179                
180        }
181 
182        private boolean isOrContainsAssemblyContext(AssemblyContext currenAssemblyContext, AssemblyContext targetAssembly) {
183                
184                if (currenAssemblyContext == targetAssembly)
185                        return true;
186                
187                RepositoryComponent component = currenAssemblyContext.getEncapsulatedComponent__AssemblyContext();
188                if (component instanceof CompositeComponent){
189                        CompositeComponent composite = (CompositeComponent)component;
190                        for (AssemblyContext containedAssemblyContext : composite.getAssemblyContexts__ComposedStructure()) {
191                                boolean contained = isOrContainsAssemblyContext(containedAssemblyContext, targetAssembly);
192                                if (contained)
193                                        return true;
194                        }
195                }
196                return false;
197        }
198 
199        /**
200         * Extends {@link SeffVisitor#caseInternalAction(InternalAction)}. Adds the calculation 
201         * of a mean resource demand weighted by frequency of execution. Adds this information to the  
202         * {@link AggregatedResourceDemand}. Then calls {@link SeffVisitor#caseInternalAction(InternalAction)}.
203         * 
204         * {@inheritDoc}
205         */
206        @Override
207        public Object caseInternalAction(InternalAction action) {
208                // add all types of resource demands. 
209                for (ParametricResourceDemand demand : action.getResourceDemand_Action()) {
210                        String specification = demand.getSpecification_ParametericResourceDemand().getSpecification();
211                        
212                        Expression solvedExpr = ExpressionHelper.getSolvedExpression(specification, this.contextWrapper);
213                                                
214                        ResourceType resourceType = demand.getRequiredResource_ParametricResourceDemand();
215                        
216                        double meanDemand = ExpressionHelper.meanValue(solvedExpr);
217                        
218                        addToAggregatedUsage(resourceType, meanDemand);
219                        
220                }
221                
222                //to get the successor right and also fill the computed allocation. 
223                Object object = super.caseInternalAction(action);
224                //Object object = action.getSuccessor_AbstractAction();
225                return object;
226        }
227 
228 
229 
230        /**
231         * Weight the demand by frequency and add it to the {@link AggregatedResourceDemand}.
232         * @param resourceType
233         * @param demand
234         */
235        private void addToAggregatedUsage(ResourceType resourceType, double demand) {
236                
237                //weight by probability
238                double weightedDemand = demand * this.currentFrequency;
239                
240                AggregatedResourceDemand resourceDemandForType = null;
241                
242                List<AggregatedResourceDemand> existingResourceDemands = this.computedAggregatedUsage.getAggregatedResourceDemands_ServiceExecutionContext();
243                for (AggregatedResourceDemand aggregatedResourceDemand : existingResourceDemands) {
244                        if (aggregatedResourceDemand.getResourceType_AggregatedResourceDemand().equals(resourceType)){
245                                resourceDemandForType = aggregatedResourceDemand;
246                                break;
247                        }
248                }
249                
250                if (resourceDemandForType == null){
251                        resourceDemandForType = AggregatedUsageContextFactory.eINSTANCE.createAggregatedResourceDemand();
252                        resourceDemandForType.setResourceType_AggregatedResourceDemand(resourceType);
253                        this.computedAggregatedUsage.getAggregatedResourceDemands_ServiceExecutionContext().add(resourceDemandForType);
254                }
255                
256                double newAggregatedValue = resourceDemandForType.getAggregatedResourceDemand()+weightedDemand;
257                resourceDemandForType.setAggregatedResourceDemand(newAggregatedValue);
258                
259        }
260 
261        /**
262         * Gets the frequency to execute this {@link ResourceDemandingBehaviour} by checking the container.
263         * If it is a {@link BranchTransition} or {@link AbstractLoopAction}, update the frequency before calling 
264         * {@link SeffVisitor#caseExternalCallAction(ExternalCallAction)}. Then resets the frequency for the next action or trasition.
265         * Then calls {@link SeffVisitor#caseResourceDemandingBehaviour(ResourceDemandingBehaviour)}.
266         * 
267         * {@inheritDoc}.
268         */
269        @Override
270        public Object caseResourceDemandingBehaviour(
271                        ResourceDemandingBehaviour behaviour) {
272                
273                
274                // to avoid rounding errors, reset probability after the call. 
275                double oldProbability = this.currentFrequency;
276                
277                
278                //determine container type
279                EObject container = behaviour.eContainer();
280                
281                if (container instanceof AbstractBranchTransition){
282                        AbstractBranchTransition branchTransition = (AbstractBranchTransition)container;
283                        
284                        double branchProb = -1;
285                        List<BranchProbability> branchProbabilities = this.contextWrapper.getCompUsgCtx().getBranchProbabilities_ComputedUsageContext();
286                        for (BranchProbability branchProbability : branchProbabilities) {
287                                if (branchTransition.equals(branchProbability.getBranchtransition_BranchProbability())){
288                                        branchProb = branchProbability.getProbability();
289                                        break;
290                                }
291                        }
292                        if (branchProb == -1){
293                                throw new RuntimeException("Internal error: Found no branch transition probability for branch "+branchTransition.getEntityName()+" "+branchTransition.getId());
294                        }
295                        this.currentFrequency = this.currentFrequency * branchProb;
296                        
297                } else if (container instanceof AbstractLoopAction){
298                        AbstractLoopAction loop = (AbstractLoopAction)container;
299                        double avgLoopIterationNumber = -1; 
300                        List<LoopIteration> loopIterations = this.contextWrapper.getCompUsgCtx().getLoopiterations_ComputedUsageContext();
301                        for (LoopIteration loopIteration : loopIterations) {
302                                if (loop.equals(loopIteration.getLoopaction_LoopIteration())){
303                                        avgLoopIterationNumber = ExpressionHelper.meanValue(ExpressionHelper.getSolvedExpression(loopIteration.getSpecification_LoopIteration().getSpecification(), this.contextWrapper));
304                                }
305                        }
306                        if (avgLoopIterationNumber == -1){
307                                throw new RuntimeException("Internal error: Found no branch transition probability for loop "+loop.getEntityName()+" "+loop.getId());
308                        }
309                        this.currentFrequency = this.currentFrequency * avgLoopIterationNumber;
310                }
311                
312                Object result = super.caseResourceDemandingBehaviour(behaviour);
313                
314                this.currentFrequency = oldProbability;
315                
316                return result;
317                 
318        }
319 
320        /**
321         * Get the current frequency of this object. This is <i>not</i> equal to the frequency 
322         * of this {@link ServiceEffectSpecification}, because the current frequency 
323         * reflects the frequency of the currently handled {@link AbstractAction}.
324         */
325        public double getCurrentFrequency() {
326                return this.currentFrequency;
327        }
328        
329        private ServiceExecutionContext createOrReuseExecutionContext(ResourceDemandingSEFF rdSEFF, AllocationContext allocationContext, UsageScenario usageScenario, double frequency){
330                
331                ServiceExecutionContext computedAggregatedUsage = null;
332                
333                List<ServiceExecutionContext> aggrUsageContext = this.contextWrapper.getPcmInstance().getComputedAggregatedUsage().getServiceExecutionContexts_ComputedAggregatedUsage();
334                for (ServiceExecutionContext serviceExecutionContext : aggrUsageContext) {
335                        if (serviceExecutionContext.getDescribedSEFF_ServiceExecutionContext() == rdSEFF
336                                        && serviceExecutionContext.getAllocationContext_ServiceExecutionContext() == allocationContext
337                                        && serviceExecutionContext.getUsageScenario_ServiceExecutionContext() == usageScenario){
338                                computedAggregatedUsage = serviceExecutionContext;
339                                double oldFrequency = computedAggregatedUsage.getGlobalExecutionFrequency();
340                                computedAggregatedUsage.setGlobalExecutionFrequency(frequency+oldFrequency);
341                                break;
342                        }
343                }
344                
345                //If no context is yet there for this seff in this assembly context, create a new one. 
346                if (computedAggregatedUsage == null){
347                
348                        computedAggregatedUsage = AggregatedUsageContextFactory.eINSTANCE.createServiceExecutionContext();
349                        computedAggregatedUsage.setGlobalExecutionFrequency(currentFrequency);
350 
351                        computedAggregatedUsage.setAllocationContext_ServiceExecutionContext(allocationContext);
352                        computedAggregatedUsage.setUsageScenario_ServiceExecutionContext(this.usageScenario);
353                        computedAggregatedUsage.setDescribedSEFF_ServiceExecutionContext(rdSEFF);
354                
355                        this.contextWrapper.getPcmInstance().getComputedAggregatedUsage().getServiceExecutionContexts_ComputedAggregatedUsage().add(computedAggregatedUsage);
356                }
357                
358                return computedAggregatedUsage;
359        }
360        
361        private AggregatedCommunication createOrReuseAggregatedCommunication(ServiceExecutionContext fromService, ServiceExecutionContext toService){
362                
363                AggregatedCommunication communication = null;
364                
365                List<AggregatedCommunication> communications = fromService.getSentAggregatedCommunications_ServiceExecutionContext();
366                for (AggregatedCommunication aggregatedCommunication : communications) {
367                        if (aggregatedCommunication.getReceiver_AggregatedCommunication() == toService){
368                                communication = aggregatedCommunication;
369                                break;
370                        }
371                }
372                
373                if (communication == null){
374                        communication = AggregatedUsageContextFactory.eINSTANCE.createAggregatedCommunication();
375                        communication.setReceiver_AggregatedCommunication(toService);
376                        communications.add(communication);
377                }
378                
379                return communication;
380                
381        }
382        
383        
384 
385        
386}

[all classes][de.uka.ipd.sdq.pcmsolver.visitors]
EMMA 2.0.9414 (unsupported private build) (C) Vladimir Roubtsov