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

COVERAGE SUMMARY FOR SOURCE FILE [ContextWrapper.java]

nameclass, %method, %block, %line, %
ContextWrapper.java0%   (0/1)0%   (0/58)0%   (0/2007)0%   (0/582)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ContextWrapper0%   (0/1)0%   (0/58)0%   (0/2007)0%   (0/582)
<static initializer> 0%   (0/1)0%   (0/5)0%   (0/3)
ContextWrapper (): void 0%   (0/1)0%   (0/38)0%   (0/9)
ContextWrapper (PCMInstance): void 0%   (0/1)0%   (0/41)0%   (0/10)
addComponentParametersToNewContext (ComputedUsageContext): void 0%   (0/1)0%   (0/145)0%   (0/45)
addExternalCallInputToCurrentContext (ExternalCallAction): ExternalCallInput 0%   (0/1)0%   (0/32)0%   (0/9)
areEqual (EList, EList): boolean 0%   (0/1)0%   (0/106)0%   (0/32)
clone (): Object 0%   (0/1)0%   (0/53)0%   (0/12)
copyComponentParameters (AssemblyContext): Collection 0%   (0/1)0%   (0/12)0%   (0/7)
createContextWrappersBasedOnTemplate (ContextWrapper, List, ComputedUsageCont... 0%   (0/1)0%   (0/43)0%   (0/15)
createNewComputedUsageContext (ExternalCallAction): ComputedUsageContext 0%   (0/1)0%   (0/33)0%   (0/12)
exists (EList, ResourceContainer): boolean 0%   (0/1)0%   (0/21)0%   (0/4)
findReliabilityAnnotationForSystemExternalCall (ExternalCallAction, Operation... 0%   (0/1)0%   (0/50)0%   (0/15)
findSystemRequiredRoleForCurrentAssemblyContext (OperationRequiredRole): Oper... 0%   (0/1)0%   (0/79)0%   (0/27)
getAllCtx (): AllocationContext 0%   (0/1)0%   (0/3)0%   (0/1)
getAssCtx (): AssemblyContext 0%   (0/1)0%   (0/10)0%   (0/1)
getAssCtxList (): List 0%   (0/1)0%   (0/3)0%   (0/1)
getBranchProbability (AbstractBranchTransition): Double 0%   (0/1)0%   (0/6)0%   (0/1)
getCompAllCtx (): ComputedAllocationContext 0%   (0/1)0%   (0/3)0%   (0/1)
getCompUsgCtx (): ComputedUsageContext 0%   (0/1)0%   (0/3)0%   (0/1)
getConcreteLinkingResource (ExternalCallAction, AllocationContext): Communica... 0%   (0/1)0%   (0/6)0%   (0/1)
getConcretePassiveResource (AcquireAction): PassiveResource 0%   (0/1)0%   (0/3)0%   (0/1)
getConcretePassiveResource (ReleaseAction): PassiveResource 0%   (0/1)0%   (0/3)0%   (0/1)
getConcreteProcessingResource (ParametricResourceDemand): ProcessingResourceS... 0%   (0/1)0%   (0/6)0%   (0/1)
getContextWrapperFor (EntryLevelSystemCall): List 0%   (0/1)0%   (0/19)0%   (0/5)
getContextWrapperFor (EntryLevelSystemCall, PCMInstance): List 0%   (0/1)0%   (0/29)0%   (0/12)
getContextWrapperFor (ExternalCallAction): List 0%   (0/1)0%   (0/20)0%   (0/6)
getContextWrapperFor (ExternalCallAction, ComputedUsageContext, ComputedAlloc... 0%   (0/1)0%   (0/56)0%   (0/18)
getDelayOnLinkingResource (ExternalCallAction, CommunicationLinkResourceSpeci... 0%   (0/1)0%   (0/24)0%   (0/6)
getExistingComputedAllocationContext (ComputedUsageContext): ComputedAllocati... 0%   (0/1)0%   (0/35)0%   (0/10)
getExistingComputedUsageContext (ExternalCallAction): ComputedUsageContext 0%   (0/1)0%   (0/111)0%   (0/37)
getFailureOccurrenceDescriptionsForSystemExternalCall (ExternalCallAction): List 0%   (0/1)0%   (0/30)0%   (0/12)
getFirstComputedUsageContext (EntryLevelSystemCall): ComputedUsageContext 0%   (0/1)0%   (0/69)0%   (0/23)
getFullParameterName (AbstractNamedReference): String 0%   (0/1)0%   (0/36)0%   (0/6)
getIsOriginalPDFFor (ParametricResourceDemand): boolean 0%   (0/1)0%   (0/5)0%   (0/1)
getLoopIterations (AbstractLoopAction): ManagedPMF 0%   (0/1)0%   (0/6)0%   (0/1)
getMeanTimeConsumption (ParametricResourceDemand): Double 0%   (0/1)0%   (0/5)0%   (0/1)
getMeanTotalInputParameterBytesize (ExternalCallAction): Double 0%   (0/1)0%   (0/6)0%   (0/1)
getMeanTotalInputParameterBytesize (ExternalCallInput): Double 0%   (0/1)0%   (0/54)0%   (0/14)
getMeanTotalOutputParameterBytesize (ExternalCallAction): Double 0%   (0/1)0%   (0/6)0%   (0/1)
getMeanTotalOutputParameterBytesize (ExternalCallOutput): Double 0%   (0/1)0%   (0/54)0%   (0/14)
getNextAllocationContextList (Iterator): List 0%   (0/1)0%   (0/49)0%   (0/13)
getNextAllocationContextList (List): List 0%   (0/1)0%   (0/5)0%   (0/1)
getNextComputedAllocationContext (ComputedUsageContext): ComputedAllocationCo... 0%   (0/1)0%   (0/52)0%   (0/17)
getNextComputedUsageContext (ExternalCallAction): ComputedUsageContext 0%   (0/1)0%   (0/44)0%   (0/9)
getNextSEFF (EntryLevelSystemCall): ServiceEffectSpecification 0%   (0/1)0%   (0/46)0%   (0/13)
getNextSEFF (ExternalCallAction): ServiceEffectSpecification 0%   (0/1)0%   (0/62)0%   (0/17)
getPcmInstance (): PCMInstance 0%   (0/1)0%   (0/3)0%   (0/1)
getRequiredRoleForExternalCallAction (ExternalCallAction): OperationRequiredRole 0%   (0/1)0%   (0/41)0%   (0/12)
getTimeConsumptionAsPDF (ParametricResourceDemand): ManagedPDF 0%   (0/1)0%   (0/5)0%   (0/1)
getTimeConsumptionSpecification (ParametricResourceDemand): String 0%   (0/1)0%   (0/8)0%   (0/2)
handleComputedContexts (ComputedUsageContext, ComputedAllocationContext): void 0%   (0/1)0%   (0/19)0%   (0/6)
matchVariableUsages (EList): ComputedUsageContext 0%   (0/1)0%   (0/42)0%   (0/12)
readComputedContextsToHashMaps (): void 0%   (0/1)0%   (0/342)0%   (0/97)
setAllCtx (AllocationContext): void 0%   (0/1)0%   (0/4)0%   (0/2)
setAssCtxList (List): void 0%   (0/1)0%   (0/4)0%   (0/2)
setCompAllCtx (ComputedAllocationContext): void 0%   (0/1)0%   (0/4)0%   (0/2)
setCompUsgCtx (ComputedUsageContext): void 0%   (0/1)0%   (0/4)0%   (0/2)
setPcmInstance (PCMInstance): void 0%   (0/1)0%   (0/4)0%   (0/2)

1package de.uka.ipd.sdq.pcmsolver.transformations;
2 
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.HashMap;
6import java.util.Iterator;
7import java.util.List;
8 
9import org.antlr.runtime.RecognitionException;
10import org.apache.log4j.Logger;
11import org.eclipse.emf.common.util.BasicEList;
12import org.eclipse.emf.common.util.EList;
13import org.eclipse.emf.ecore.util.EcoreUtil;
14 
15import de.uka.ipd.sdq.context.computed_allocation.ComputedAllocationContext;
16import de.uka.ipd.sdq.context.computed_allocation.ComputedAllocationFactory;
17import de.uka.ipd.sdq.context.computed_allocation.ResourceDemand;
18import de.uka.ipd.sdq.context.computed_usage.BranchProbability;
19import de.uka.ipd.sdq.context.computed_usage.ComputedUsageContext;
20import de.uka.ipd.sdq.context.computed_usage.ComputedUsageFactory;
21import de.uka.ipd.sdq.context.computed_usage.ExternalCallInput;
22import de.uka.ipd.sdq.context.computed_usage.ExternalCallOutput;
23import de.uka.ipd.sdq.context.computed_usage.Input;
24import de.uka.ipd.sdq.context.computed_usage.LoopIteration;
25import de.uka.ipd.sdq.pcm.allocation.AllocationContext;
26import de.uka.ipd.sdq.pcm.core.composition.AssemblyContext;
27import de.uka.ipd.sdq.pcm.core.composition.ComposedStructure;
28import de.uka.ipd.sdq.pcm.core.composition.Connector;
29import de.uka.ipd.sdq.pcm.core.composition.RequiredDelegationConnector;
30import de.uka.ipd.sdq.pcm.parameter.VariableCharacterisation;
31import de.uka.ipd.sdq.pcm.parameter.VariableCharacterisationType;
32import de.uka.ipd.sdq.pcm.parameter.VariableUsage;
33import de.uka.ipd.sdq.pcm.qosannotations.QoSAnnotations;
34import de.uka.ipd.sdq.pcm.qosannotations.SpecifiedQoSAnnotation;
35import de.uka.ipd.sdq.pcm.qosannotations.qos_reliability.SpecifiedReliabilityAnnotation;
36import de.uka.ipd.sdq.pcm.reliability.ExternalFailureOccurrenceDescription;
37import de.uka.ipd.sdq.pcm.repository.BasicComponent;
38import de.uka.ipd.sdq.pcm.repository.ImplementationComponentType;
39import de.uka.ipd.sdq.pcm.repository.OperationInterface;
40import de.uka.ipd.sdq.pcm.repository.OperationRequiredRole;
41import de.uka.ipd.sdq.pcm.repository.PassiveResource;
42import de.uka.ipd.sdq.pcm.repository.RequiredRole;
43import de.uka.ipd.sdq.pcm.repository.Signature;
44import de.uka.ipd.sdq.pcm.resourceenvironment.CommunicationLinkResourceSpecification;
45import de.uka.ipd.sdq.pcm.resourceenvironment.LinkingResource;
46import de.uka.ipd.sdq.pcm.resourceenvironment.ProcessingResourceSpecification;
47import de.uka.ipd.sdq.pcm.resourceenvironment.ResourceContainer;
48import de.uka.ipd.sdq.pcm.resourcetype.ProcessingResourceType;
49import de.uka.ipd.sdq.pcm.seff.AbstractBranchTransition;
50import de.uka.ipd.sdq.pcm.seff.AbstractLoopAction;
51import de.uka.ipd.sdq.pcm.seff.AcquireAction;
52import de.uka.ipd.sdq.pcm.seff.ExternalCallAction;
53import de.uka.ipd.sdq.pcm.seff.ReleaseAction;
54import de.uka.ipd.sdq.pcm.seff.ServiceEffectSpecification;
55import de.uka.ipd.sdq.pcm.seff.seff_performance.ParametricResourceDemand;
56import de.uka.ipd.sdq.pcm.system.System;
57import de.uka.ipd.sdq.pcm.usagemodel.EntryLevelSystemCall;
58import de.uka.ipd.sdq.pcm.usagemodel.UsageModel;
59import de.uka.ipd.sdq.pcm.usagemodel.UserData;
60import de.uka.ipd.sdq.pcmsolver.models.PCMInstance;
61import de.uka.ipd.sdq.pcmsolver.visitors.ExpressionHelper;
62import de.uka.ipd.sdq.pcmsolver.visitors.VariableUsageHelper;
63import de.uka.ipd.sdq.probfunction.math.ManagedPDF;
64import de.uka.ipd.sdq.probfunction.math.ManagedPMF;
65import de.uka.ipd.sdq.probfunction.math.exception.StringNotPDFException;
66import de.uka.ipd.sdq.stoex.AbstractNamedReference;
67import de.uka.ipd.sdq.stoex.Expression;
68import de.uka.ipd.sdq.stoex.NamespaceReference;
69 
70/**
71 * For convenient implementation of model transformations in Java from PCM
72 * instances to performance models, the DS provides a so-called ContextWrapper.
73 * It hides all specified and computed context models from the transformation
74 * and assists the traversal of a PCM instance. A transformation can instantiate
75 * a new ContextWrapper upon visiting an EntryLevelSystemCall or
76 * ExternalCallAction as it is specific for each RDSEFF call.
77 * 
78 * Transformations must instantiate a ContextWrapper initially when visiting the
79 * first EntryLevelSystemCall by calling its constructor and passing a reference
80 * to the current PCM instance, which already includes the specified contexts as
81 * well as the computed contexts from a former run of the DS. Thus, from an
82 * EntryLevelSystemCall and the given PCM instance, the ContextWrapper can
83 * retrieve the called assembly context, allocation context, computed usage
84 * context, and computed allocation context internally. The ContextWrapper also
85 * includes functions to retrieve the RDSEFF called by an EntryLevelSystemCall
86 * or ExternalCallAction, which a transformation needs to continue traversing a
87 * PCM instance. These functions (getNextSEFF) hide the context-dependent
88 * traversal through the model via delegation and assembly connectors from the
89 * transformation.
90 * 
91 * When a model transformation visits RDSEFF actions, it may call the Context-
92 * Wrapper for performance annotations, such as branch probabilities, loop
93 * iteration numbers, or timing values. This information is not contained in the
94 * parameterized RDSEFF, but only in the computed contexts. The ContextWrapper
95 * retrieves the information from the computed contexts given for example an
96 * AbstractBranchTransition or ParametricResourceDemand.
97 * 
98 * TODO: This class is way too big and needs refactoring. For many methods, it
99 * would make sense to re-write them so that they only depend on their input
100 * parameters (and not on the state of the object). This should make it much
101 * easier to understand the code. Moreover, context-independent methods
102 * can be outsourced into helper classes.
103 * 
104 * @see Heiko's dissertation, section 6.2.4 at
105 *      http://docserver.bis.uni-oldenburg
106 *      .de/_publikationen/dissertation/2008/kozpar08/pdf/kozpar08.pdf
107 * @author Heiko Koziolek
108 * 
109 */
110public class ContextWrapper implements Cloneable {
111 
112        /**
113         * 
114         */
115        protected static Logger logger = Logger.getLogger(ContextWrapper.class
116                        .getName());
117 
118        /**
119         * Creates a List of {@link ContextWrapper}s to handle the given
120         * {@link EntryLevelSystemCall}. One {@link ContextWrapper} is created for
121         * each {@link AllocationContext} the receiving component is allocated to.
122         * Thus, callers must handle multiple component allocation instances of the
123         * called component. One ContextWrapper then handles the context of that
124         * particular component instance (i.e. one replica) These are new
125         * ContextWrappers without any previous context information.
126         * */
127        public static List<ContextWrapper> getContextWrapperFor(
128                        EntryLevelSystemCall elsa, PCMInstance pcm) {
129 
130                ContextWrapper templateContextWrapper = new ContextWrapper();
131                templateContextWrapper.pcmInstance = pcm;
132 
133                List<AssemblyContext> handlingAssemblyContexts = PCMInstanceHelper
134                                .getHandlingAssemblyContexts(elsa, pcm.getSystem());
135                templateContextWrapper.setAssCtxList(handlingAssemblyContexts);
136 
137                ComputedUsageContext computedUsageContext = templateContextWrapper
138                                .getFirstComputedUsageContext(elsa);
139                templateContextWrapper.setCompUsgCtx(computedUsageContext);
140 
141                List<ContextWrapper> contextWrapperList = createContextWrappersBasedOnTemplate(
142                                templateContextWrapper, handlingAssemblyContexts,
143                                computedUsageContext);
144 
145                return contextWrapperList;
146        }
147 
148        /**
149         * Attention: This constructor modifies the passed ContextWrapper!
150         * 
151         * @param eca
152         * @param cuc
153         * @param cac
154         * @param oldContextWrapper
155         *            IS MODIFIED!
156         */
157        public static List<ContextWrapper> getContextWrapperFor(
158                        ExternalCallAction eca, ComputedUsageContext cuc,
159                        ComputedAllocationContext cac, ContextWrapper oldContextWrapper) {
160 
161                ContextWrapper templateContextWrapper = new ContextWrapper();
162                templateContextWrapper.pcmInstance = oldContextWrapper.getPcmInstance();
163 
164                templateContextWrapper
165                                .setAssCtxList(PCMInstanceHelper.getHandlingAssemblyContexts(
166                                                eca, oldContextWrapper.assCtxList));
167                List<AllocationContext> allocationContextList = templateContextWrapper
168                                .getNextAllocationContextList(templateContextWrapper
169                                                .getAssCtxList());
170                List<ContextWrapper> contextWrapperList = new ArrayList<ContextWrapper>(
171                                allocationContextList.size());
172                for (AllocationContext allocationContext : allocationContextList) {
173                        // XXX: only a fully initialised context wrapper can be cloned...
174                        templateContextWrapper.setAllCtx(allocationContext);
175 
176                        ContextWrapper contextWrapper = (ContextWrapper) templateContextWrapper
177                                        .clone();
178                        contextWrapper.setAllCtx(allocationContext);
179                        contextWrapperList.add(contextWrapper);
180                        contextWrapper.handleComputedContexts(cuc, cac);
181                }
182                return contextWrapperList;
183        }
184 
185        /**
186         * Uses the passed ContextWrapper as a template to create new ones for each
187         * called AllocationContext The template is needed to keep existing usage
188         * information such as branch probabilities.
189         * 
190         * @param templateContextWrapper
191         * @param calledAssemblyContextList
192         * @param computedUsageContext
193         * @return
194         */
195        private static List<ContextWrapper> createContextWrappersBasedOnTemplate(
196                        ContextWrapper templateContextWrapper,
197                        List<AssemblyContext> calledAssemblyContextList,
198                        ComputedUsageContext computedUsageContext) {
199 
200                List<AllocationContext> allocationContextList = templateContextWrapper
201                                .getNextAllocationContextList(templateContextWrapper
202                                                .getAssCtxList());
203                List<ContextWrapper> contextWrapperList = new ArrayList<ContextWrapper>(
204                                allocationContextList.size());
205 
206                for (AllocationContext allocationContext : allocationContextList) {
207                        ContextWrapper contextWrapper = (ContextWrapper) templateContextWrapper
208                                        .clone();
209                        contextWrapper.setAllCtx(allocationContext);
210                        contextWrapper.setCompAllCtx(contextWrapper
211                                        .getNextComputedAllocationContext(contextWrapper
212                                                        .getCompUsgCtx()));
213                        contextWrapper.readComputedContextsToHashMaps();
214                        contextWrapperList.add(contextWrapper);
215                }
216                return contextWrapperList;
217        }
218 
219        /**
220         * 
221         */
222        private AllocationContext allCtx;
223 
224        /**
225         * See {@link #getAssCtxList()} for info.
226         */
227        private List<AssemblyContext> assCtxList;
228 
229        /**
230         * 
231         */
232        private HashMap<AbstractBranchTransition, Double> branchProbs = new HashMap<AbstractBranchTransition, Double>();
233 
234        /**
235         * 
236         */
237        private ComputedAllocationContext compAllCtx;
238 
239        /**
240         * 
241         */
242        private ComputedUsageContext compUsgCtx;
243 
244        /**
245         * 
246         */
247        private HashMap<ExternalCallAction, Double> inputParameterBytesizes = new HashMap<ExternalCallAction, Double>();
248 
249        /**
250         * 
251         */
252        private CallsToLinkResourcesMap linkResources = new CallsToLinkResourcesMap();
253 
254        /**
255         * 
256         */
257        private HashMap<AbstractLoopAction, ManagedPMF> loopIters = new HashMap<AbstractLoopAction, ManagedPMF>();
258 
259        /**
260         * 
261         */
262        private HashMap<ExternalCallAction, Double> outputParameterBytesizes = new HashMap<ExternalCallAction, Double>();
263 
264        /**
265         * 
266         */
267        private PCMInstance pcmInstance;
268 
269        /**
270         * 
271         */
272        private HashMap<ParametricResourceDemand, ProcessingResourceSpecification> procResources = new HashMap<ParametricResourceDemand, ProcessingResourceSpecification>();
273 
274        /**
275         * Contains the already solved resource demand in time on the specific
276         * processor
277         */
278        private ResourceDemandCache resDemands = new ResourceDemandCache();
279 
280        /**
281         * Creates an empty ContextWrapper instance based only on the given PCM
282         * model instance.
283         * 
284         * @param pcmInstance
285         *            the PCM model instance
286         */
287        public ContextWrapper(final PCMInstance pcmInstance) {
288                this.pcmInstance = pcmInstance;
289        }
290 
291        /**
292         * Standard constructor.
293         * 
294         * Protected, only for private use through clone().
295         */
296        private ContextWrapper() {
297        }
298 
299        /**
300         * Copies this ContextWrapper. Sets references to the PCM model elements and
301         * the computed context objects, so that the context can be shared (e.g.
302         * retrieving branch probabilities of earlier context wrapper traversals).
303         */
304        @Override
305        public Object clone() {
306                ContextWrapper clonedWrapper = new ContextWrapper();
307                EList<AssemblyContext> list = new BasicEList<AssemblyContext>();
308                for (AssemblyContext ac : assCtxList) {
309                        list.add(ac);
310                }
311 
312                clonedWrapper.setAssCtxList(list);
313                // clonedWrapper.setAssCtx(assCtx);
314                clonedWrapper.setAllCtx(allCtx);
315                clonedWrapper.setCompAllCtx(compAllCtx);
316                clonedWrapper.setCompUsgCtx(compUsgCtx);
317                clonedWrapper.setPcmInstance(pcmInstance);
318 
319                if (compAllCtx != null && compUsgCtx != null) {
320                        clonedWrapper.readComputedContextsToHashMaps();
321                }
322                return clonedWrapper;
323        }
324 
325        /**
326         * 
327         * @return
328         */
329        public AllocationContext getAllCtx() {
330                return allCtx;
331        }
332 
333        /**
334         * 
335         * @return
336         */
337        public AssemblyContext getAssCtx() {
338                return assCtxList.get(assCtxList.size() - 1);
339        }
340 
341        /**
342         * @return The {@link AssemblyContext} this {@link ContextWrapper} describes
343         *         plus all the containing {@link AssemblyContext}s: If the
344         *         components are composite components, one {@link AssemblyContext}
345         *         does not define the context within a {@link System}, you need all
346         *         {@link AssemblyContext}s up to the {@link System}.
347         * 
348         *         The current {@link AssemblyContext} is the last in the list, the
349         *         previous one is its "parent", and so on.
350         */
351        public List<AssemblyContext> getAssCtxList() {
352                return assCtxList;
353        }
354 
355        /**
356         * 
357         * @param abt
358         * @return
359         */
360        public Double getBranchProbability(AbstractBranchTransition abt) {
361                return branchProbs.get(abt);
362        }
363 
364        /**
365         * 
366         * @return
367         */
368        public ComputedAllocationContext getCompAllCtx() {
369                return compAllCtx;
370        }
371 
372        /**
373         * 
374         * @return
375         */
376        public ComputedUsageContext getCompUsgCtx() {
377                return compUsgCtx;
378        }
379 
380        /**
381         * 
382         * @param eca
383         * @param targetAllocationContext
384         * @return
385         */
386        public CommunicationLinkResourceSpecification getConcreteLinkingResource(
387                        ExternalCallAction eca, AllocationContext targetAllocationContext) {
388                return linkResources.get(eca, targetAllocationContext);
389        }
390 
391        /**
392         * 
393         * @param aa
394         * @return
395         */
396        public PassiveResource getConcretePassiveResource(AcquireAction aa) {
397                // TODO: Passive Resource should depend on AssemblyContext
398                return aa.getPassiveresource_AcquireAction();
399        }
400 
401        /**
402         * 
403         * @param ra
404         * @return
405         */
406        public PassiveResource getConcretePassiveResource(ReleaseAction ra) {
407                // TODO: Passive Resource should depend on AssemblyContext
408                return ra.getPassiveResource_ReleaseAction();
409        }
410 
411        /**
412         * 
413         * @param prd
414         * @return
415         */
416        public ProcessingResourceSpecification getConcreteProcessingResource(
417                        ParametricResourceDemand prd) {
418                return procResources.get(prd);
419        }
420 
421        /**
422         * FIXME: This method changes the current ContextWrapper this, but returns a
423         * {@link List} of new {@link ContextWrapper} instances created based on
424         * this one. It needs to use the current context in order to retain
425         * information such as branch probabilities
426         * 
427         * @param elsa
428         * @return
429         */
430        public List<ContextWrapper> getContextWrapperFor(EntryLevelSystemCall elsa) {
431 
432                assCtxList = PCMInstanceHelper.getHandlingAssemblyContexts(elsa,
433                                pcmInstance.getSystem());
434                compUsgCtx = getFirstComputedUsageContext(elsa);
435 
436                return createContextWrappersBasedOnTemplate(this, assCtxList,
437                                compUsgCtx);
438        }
439 
440        /**
441         * FIXME: This method changes the current ContextWrapper this, but returns a
442         * {@link List} of new {@link ContextWrapper} instances created based on
443         * this one. It needs to use the current context in order to retain
444         * information such as branch probabilities
445         * 
446         * @param eca
447         * @return A {@link List} of new {@link ContextWrapper} instances, but also
448         *         changes this one.
449         */
450        public List<ContextWrapper> getContextWrapperFor(ExternalCallAction eca) {
451 
452                assCtxList = PCMInstanceHelper.getHandlingAssemblyContexts(eca,
453                                assCtxList);
454                compUsgCtx = getNextComputedUsageContext(eca);
455 
456                List<ContextWrapper> contextWrapperList = createContextWrappersBasedOnTemplate(
457                                this, assCtxList, compUsgCtx);
458 
459                return contextWrapperList;
460        }
461 
462        /**
463         * 
464         * @param eca
465         * @param clrs
466         * @return
467         */
468        public ManagedPDF getDelayOnLinkingResource(ExternalCallAction eca,
469                        CommunicationLinkResourceSpecification clrs) {
470                EList<ExternalCallInput> eciList = compUsgCtx
471                                .getExternalCallInput_ComputedUsageContext();
472 
473                for (ExternalCallInput eci : eciList) {
474                        if (eci.getExternalCallAction_ExternalCallInput().getId().equals(
475                                        eca.getId())) {
476                                // getByteSize of all parameters
477                        }
478                }
479                return null;
480        }
481 
482        /**
483         * Retrieves the list of FailureOccurrenceDescriptions for the given system
484         * external call.
485         * 
486         * The FailureOccurrenceDescriptions may be given to the system as a
487         * SpecifiedReliabilityAnnotation. If no SpecifiedReliabilityAnnotation for
488         * the system external call is found, an empty list is returned.
489         * 
490         * @param externalCallAction
491         *            the system externall call
492         * @return the list of FailureOccurrenceDescriptions
493         */
494        public List<ExternalFailureOccurrenceDescription> getFailureOccurrenceDescriptionsForSystemExternalCall(
495                        final ExternalCallAction externalCallAction) {
496 
497                // Create the result list:
498                BasicEList<ExternalFailureOccurrenceDescription> resultList = new BasicEList<ExternalFailureOccurrenceDescription>();
499 
500                // Retrieve the system required role that is reached from this external
501                // call action:
502                OperationRequiredRole systemRequiredRole = findSystemRequiredRoleForCurrentAssemblyContext(getRequiredRoleForExternalCallAction(externalCallAction));
503                if (systemRequiredRole == null) {
504                        return resultList;
505                }
506 
507                // Retrieve a corresponding SpecifiedReliabilityAnnotation:
508                SpecifiedReliabilityAnnotation reliabilityAnnotation = findReliabilityAnnotationForSystemExternalCall(
509                                externalCallAction, systemRequiredRole);
510                if (reliabilityAnnotation == null) {
511                        return resultList;
512                }
513 
514                // Fill and return the result list:
515                resultList
516                                .addAll(reliabilityAnnotation
517                                                .getExternalFailureOccurrenceDescriptions__SpecifiedReliabilityAnnotation());
518                return resultList;
519        }
520 
521        /**
522         * 
523         * @param prd
524         * @return
525         */
526        public boolean getIsOriginalPDFFor(ParametricResourceDemand prd) {
527                return this.resDemands.isOriginalPDF(prd);
528        }
529 
530        /**
531         * 
532         * @param ala
533         * @return
534         */
535        public ManagedPMF getLoopIterations(AbstractLoopAction ala) {
536                return loopIters.get(ala);
537        }
538 
539        /**
540         * Gets the mean time demanded by prd on its processor in this context. Note
541         * that the processing rate has already been taken into account here.
542         * 
543         * @param prd
544         * @return A Double representing the mean time demanded by prd
545         */
546        public Double getMeanTimeConsumption(ParametricResourceDemand prd) {
547                return resDemands.getDouble(prd);
548        }
549 
550        /**
551         * 
552         * @param eca
553         * @return
554         */
555        public Double getMeanTotalInputParameterBytesize(ExternalCallAction eca) {
556                return inputParameterBytesizes.get(eca);
557        }
558 
559        /**
560         * 
561         * @param eca
562         * @return
563         */
564        public Double getMeanTotalOutputParameterBytesize(ExternalCallAction eca) {
565                return outputParameterBytesizes.get(eca);
566        }
567 
568        /**
569         * 
570         * @param elsc
571         * @return
572         */
573        public ServiceEffectSpecification getNextSEFF(EntryLevelSystemCall elsc) {
574                Signature sig = elsc.getOperationSignature__EntryLevelSystemCall();
575 
576                List<AssemblyContext> acList = PCMInstanceHelper
577                                .getHandlingAssemblyContexts(elsc, pcmInstance.getSystem());
578 
579                AssemblyContext ac = acList.get(acList.size() - 1);
580                BasicComponent bc = (BasicComponent) ac
581                                .getEncapsulatedComponent__AssemblyContext();
582                EList<ServiceEffectSpecification> seffList = bc
583                                .getServiceEffectSpecifications__BasicComponent();
584                for (ServiceEffectSpecification seff : seffList) {
585                        if (seff.getDescribedService__SEFF().getEntityName().equals(
586                                        sig.getEntityName())) {
587                                return seff;
588                        }
589                }
590                return null;
591        }
592 
593        /**
594         * Finds the next SEFF for a given external call action and its referenced
595         * signature. Uses the current assembly context ids from the context wrapper
596         * as reference.
597         * 
598         * @param eca
599         * @return
600         */
601        public ServiceEffectSpecification getNextSEFF(ExternalCallAction eca) {
602                Signature sig = eca.getCalledService_ExternalService();
603 
604                // Get the list of providing AssemblyContexts for this call:
605                List<AssemblyContext> acList = PCMInstanceHelper
606                                .getHandlingAssemblyContexts(eca, assCtxList);
607                if (acList.size() == 0) {
608                        // If no providing AssemblyContexts are found, the call is a system
609                        // external call, and there is no next SEFF for it:
610                        return null;
611                }
612 
613                // Retrieve the actual handling AssemblyContext of the call:
614                AssemblyContext ac = acList.get(acList.size() - 1);
615 
616                // Retrieve the actual SEFF that handles the call:
617                BasicComponent bc = (BasicComponent) ac
618                                .getEncapsulatedComponent__AssemblyContext();
619                EList<ServiceEffectSpecification> seffList = bc
620                                .getServiceEffectSpecifications__BasicComponent();
621                for (ServiceEffectSpecification seff : seffList) {
622                        if (seff.getDescribedService__SEFF().getEntityName().equals(
623                                        sig.getEntityName())) {
624                                return seff;
625                        }
626                }
627 
628                // should not happen:
629                logger.error("Could not find next SEFF " + "for ExternalCallAction "
630                                + eca.getCalledService_ExternalService() + "!");
631                return null;
632        }
633 
634        /**
635         * 
636         * 
637         * @return
638         */
639        public PCMInstance getPcmInstance() {
640                return pcmInstance;
641        }
642 
643        /**
644         * Gets the time demanded by prd on its processor in this context. Note that
645         * the processing rate has already been taken into account here.
646         * 
647         * @param prd
648         * @return A ManagedPDF representing the time demanded by prd
649         */
650        public ManagedPDF getTimeConsumptionAsPDF(ParametricResourceDemand prd) {
651                return resDemands.getPDF(prd);
652        }
653 
654        /**
655         * 
656         * @param prd
657         * @return
658         */
659        public String getTimeConsumptionSpecification(ParametricResourceDemand prd) {
660                String resultSpecification = resDemands.getPDF(prd).toString();
661                return resultSpecification;
662        }
663 
664        /**
665         * 
666         * @param allCtx
667         */
668        public void setAllCtx(AllocationContext allCtx) {
669                this.allCtx = allCtx;
670        }
671 
672        /**
673         * Set the internal list of {@link AssemblyContext}s. This list contains the
674         * {@link AssemblyContext} this {@link ContextWrapper} describes plus all
675         * the containing {@link AssemblyContext}s: If the components are composite
676         * components, one {@link AssemblyContext} does not define the context
677         * within a {@link System}, you need all {@link AssemblyContext}s up to the
678         * {@link System}.
679         * 
680         * @param assCtxList
681         */
682        public void setAssCtxList(List<AssemblyContext> assCtxList) {
683                this.assCtxList = assCtxList;
684        }
685 
686        /**
687         * 
688         * @param compAllCtx
689         */
690        public void setCompAllCtx(ComputedAllocationContext compAllCtx) {
691                this.compAllCtx = compAllCtx;
692        }
693 
694        /**
695         * 
696         * @param compUsgCtx
697         */
698        public void setCompUsgCtx(ComputedUsageContext compUsgCtx) {
699                this.compUsgCtx = compUsgCtx;
700        }
701 
702        /**
703         * 
704         * @param pcmInstance
705         */
706        public void setPcmInstance(PCMInstance pcmInstance) {
707                this.pcmInstance = pcmInstance;
708        }
709 
710        /**
711         * 
712         * @param newCompUsgCtx
713         */
714        private void addComponentParametersToNewContext(
715                        ComputedUsageContext newCompUsgCtx) {
716 
717                // We need to make a copy because the VariableUsages are changed if they
718                // are overwritten by configuration parameters from the assembly
719                // context.
720                Collection<VariableUsage> compParams = copyComponentParameters(getAssCtx());
721 
722                EList<VariableUsage> confParList = this.getAssCtx()
723                                .getConfigParameterUsages__AssemblyContext();
724 
725                // Remove variable characterization that are overwritten in the assembly
726                // context. Compare
727                // the variable usage pairwise by both name and then variable
728                // characterization.
729                // Finally, add the config parameters to the component parameter list
730                // (compParams).
731                for (VariableUsage confParVariableUsage : confParList) {
732                        boolean repoVariableUsageWithSameNameFound = false;
733                        for (VariableUsage repoVariableUsage : compParams) {
734                                if (confParVariableUsage.getNamedReference__VariableUsage()
735                                                .getReferenceName().equals(
736                                                                repoVariableUsage
737                                                                                .getNamedReference__VariableUsage()
738                                                                                .getReferenceName())) {
739                                        repoVariableUsageWithSameNameFound = true;
740                                        //
741                                        List<VariableCharacterisation> confParCharacterisations = confParVariableUsage
742                                                        .getVariableCharacterisation_VariableUsage();
743                                        List<VariableCharacterisation> repoCharacterisations = repoVariableUsage
744                                                        .getVariableCharacterisation_VariableUsage();
745                                        List<VariableCharacterisation> vcsToBeDeleted = new ArrayList<VariableCharacterisation>(
746                                                        repoCharacterisations.size());
747                                        for (VariableCharacterisation repoVariableCharacterisation : repoCharacterisations) {
748                                                for (VariableCharacterisation confParVariableCharacterisation : confParCharacterisations) {
749                                                        if (repoVariableCharacterisation.getType().equals(
750                                                                        confParVariableCharacterisation.getType())) {
751                                                                vcsToBeDeleted
752                                                                                .add(repoVariableCharacterisation);
753                                                        }
754                                                }
755                                        }
756                                        // remove all overwritten characterizations
757                                        repoCharacterisations.removeAll(vcsToBeDeleted);
758                                        // Add all variable characterizations of this
759                                        // confParVariableUsage instead
760                                        repoVariableUsage
761                                                        .getVariableCharacterisation_VariableUsage()
762                                                        .addAll(
763                                                                        VariableUsageHelper
764                                                                                        .copyVariableCharacterisations(confParCharacterisations));
765                                }
766                        }
767                        // If there is no variable with the name specified in the assembly
768                        // context, add the whole VariableUsage from the AssemblyContext.
769                        if (!repoVariableUsageWithSameNameFound) {
770                                compParams.add((VariableUsage) EcoreUtil
771                                                .copy(confParVariableUsage));
772                        }
773                }
774 
775                VariableUsageHelper.copySolvedVariableUsageToInput(newCompUsgCtx
776                                .getInput_ComputedUsageContext(), this, compParams);
777 
778                UsageModel um = this.getPcmInstance().getUsageModel();
779                EList<UserData> userDataList = um.getUserData_UsageModel();
780                for (UserData ud : userDataList) {
781                        if (ud.getAssemblyContext_userData().getId().equals(
782                                        this.getAssCtx().getId())) {
783                                EList<VariableUsage> userParList = ud
784                                                .getUserDataParameterUsages_UserData();
785                                VariableUsageHelper.copySolvedVariableUsageToInput(
786                                                newCompUsgCtx.getInput_ComputedUsageContext(), this,
787                                                userParList);
788                        }
789                }
790        }
791 
792        /**
793         * 
794         * @param eca
795         * @return
796         */
797        private ExternalCallInput addExternalCallInputToCurrentContext(
798                        ExternalCallAction eca) {
799                EList<VariableUsage> parList = eca.getInputVariableUsages__CallAction();
800                ExternalCallInput eci = ComputedUsageFactory.eINSTANCE
801                                .createExternalCallInput();
802                eci.setExternalCallAction_ExternalCallInput(eca);
803                compUsgCtx.getExternalCallInput_ComputedUsageContext().add(eci);
804                for (VariableUsage vu : parList) {
805                        VariableUsageHelper.copySolvedVariableUsageToExternalCallInput(
806                                        this, eci, vu);
807                }
808                return eci;
809        }
810 
811        /**
812         * 
813         * @param vuList1
814         * @param vuList2
815         * @return
816         */
817        private boolean areEqual(EList<VariableUsage> vuList1,
818                        EList<VariableUsage> vuList2) {
819 
820                int varUsgCounter = 0;
821                for (VariableUsage vu1 : vuList1) {
822                        for (VariableUsage vu2 : vuList2) {
823                                if (getFullParameterName(vu1.getNamedReference__VariableUsage())
824                                                .equals(
825                                                                getFullParameterName(vu2
826                                                                                .getNamedReference__VariableUsage()))) {
827                                        EList<VariableCharacterisation> vcList = vu1
828                                                        .getVariableCharacterisation_VariableUsage();
829                                        int varCharFoundCounter = 0;
830 
831                                        for (VariableCharacterisation vc1 : vcList) {
832                                                EList<VariableCharacterisation> vcList2 = vu2
833                                                                .getVariableCharacterisation_VariableUsage();
834                                                boolean singleVarCharFound = false;
835                                                for (VariableCharacterisation vc2 : vcList2) {
836                                                        // added replaceAll(" ", "") below so that different
837                                                        // formatting of specifications will not lead to
838                                                        // handling them as being different. There seems to
839                                                        // be some pretty printing going on somewhere.
840                                                        // XXX: This may not be enough to handle the pretty
841                                                        // printing, maybe the pretty printing introduces
842                                                        // other errors that are not handled by this.
843                                                        if (vc1.getType().getLiteral().equals(
844                                                                        vc2.getType().getLiteral())
845                                                                        && vc1
846                                                                                        .getSpecification_VariableCharacterisation()
847                                                                                        .getSpecification()
848                                                                                        .replaceAll(" ", "")
849                                                                                        .equals(
850                                                                                                        vc2
851                                                                                                                        .getSpecification_VariableCharacterisation()
852                                                                                                                        .getSpecification()
853                                                                                                                        .replaceAll(" ", ""))) {
854                                                                singleVarCharFound = true;
855                                                        }
856                                                }
857                                                // found a single matching characterisation
858                                                if (singleVarCharFound)
859                                                        varCharFoundCounter++;
860                                        }
861                                        // all characterisations for a parameter found:
862                                        if (varCharFoundCounter == vcList.size())
863                                                varUsgCounter++;
864                                }
865                        }
866                }
867                // return true if all matching variable usages found
868                return (varUsgCounter == vuList1.size());
869        }
870 
871        /**
872         * 
873         * @param context
874         * @return
875         */
876        private Collection<VariableUsage> copyComponentParameters(
877                        AssemblyContext context) {
878                ImplementationComponentType component = (ImplementationComponentType) context
879                                .getEncapsulatedComponent__AssemblyContext();
880                List<VariableUsage> originalVariableUsages = component
881                                .getComponentParameterUsage_ImplementationComponentType();
882 
883                Collection<VariableUsage> newVariableUsages = VariableUsageHelper
884                                .copyVariableUsageList(originalVariableUsages);
885 
886                return newVariableUsages;
887 
888        }
889 
890        /**
891         * 
892         * @param eca
893         * @return
894         */
895        private ComputedUsageContext createNewComputedUsageContext(
896                        ExternalCallAction eca) {
897                // create new computed usage context
898                ComputedUsageContext newCompUsgCtx = ComputedUsageFactory.eINSTANCE
899                                .createComputedUsageContext();
900                pcmInstance.getComputedUsage().getUsageContexts_ComputedUsage().add(
901                                newCompUsgCtx);
902 
903                newCompUsgCtx.setAssemblyContext_ComputedUsageContext(getAssCtx());
904 
905                Input newInput = ComputedUsageFactory.eINSTANCE.createInput();
906                newCompUsgCtx.setInput_ComputedUsageContext(newInput);
907 
908                EList<VariableUsage> parList = eca.getInputVariableUsages__CallAction();
909                VariableUsageHelper.copySolvedVariableUsageToInput(newCompUsgCtx
910                                .getInput_ComputedUsageContext(), this, parList);
911 
912                addComponentParametersToNewContext(newCompUsgCtx);
913 
914                return newCompUsgCtx;
915        }
916 
917        /**
918         * Checks if a resource container exists in a list of containers.
919         * 
920         * @param list
921         *            the list of resource containers
922         * @param container
923         *            the resource container to find
924         * @return TRUE if the container is in the list
925         */
926        private boolean exists(final EList<ResourceContainer> list,
927                        final ResourceContainer container) {
928                // Go through the list of resource containers:
929                for (ResourceContainer element : list) {
930                        if (element.getId().equals(container.getId())) {
931                                return true;
932                        }
933                }
934                return false;
935        }
936 
937        /**
938         * Retrieves the SpecifiedReliabilityAnnotation that belongs to the given
939         * system external call.
940         * 
941         * It is assumed that the external call action belongs to the component that
942         * is encapsulated by the current assembly context. The current assembly
943         * context is the last element of assCtxList. If no corresponding
944         * SpecifiedReliabilityAnnotation exists, the method returns NULL.
945         * 
946         * @param externalCallAction
947         *            the system external call
948         * @param systemRequiredRole
949         *            the system required role that provides the called service
950         * @return the corresponding SpecifiedReliabilityAnnotation (if one exists)
951         */
952        private SpecifiedReliabilityAnnotation findReliabilityAnnotationForSystemExternalCall(
953                        final ExternalCallAction externalCallAction,
954                        final OperationRequiredRole systemRequiredRole) {
955 
956                // Search through the system's QoS annotations:
957                for (QoSAnnotations annotation : pcmInstance.getSystem()
958                                .getQosAnnotations_System()) {
959                        for (SpecifiedQoSAnnotation specifiedAnnotation : annotation
960                                        .getSpecifiedQoSAnnotations_QoSAnnotations()) {
961                                if (!(specifiedAnnotation instanceof SpecifiedReliabilityAnnotation)) {
962                                        continue;
963                                }
964                                if (specifiedAnnotation.getRole_SpecifiedQoSAnnotation()
965                                                .getId().equals(systemRequiredRole.getId())) {
966                                        if (specifiedAnnotation.getSignature_SpecifiedQoSAnnation()
967                                                        .getId().equals(
968                                                                        externalCallAction
969                                                                                        .getCalledService_ExternalService()
970                                                                                        .getId())) {
971                                                return (SpecifiedReliabilityAnnotation) specifiedAnnotation;
972                                        }
973                                }
974                        }
975                }
976 
977                // No corresponding reliability annotation found:
978                return null;
979        }
980 
981        /**
982         * Searches for the required role of the system that is reached from the
983         * current AssemblyContext via its given required role.
984         * 
985         * The current AssemblyContext is the last element of the assCtxList. If the
986         * required role of the AssemblyContext does not lead to a system required
987         * role, the method returns NULL.
988         * 
989         * @param requiredRole
990         *            the required role of the current AssemblyContext
991         * @return the system required role
992         */
993        private OperationRequiredRole findSystemRequiredRoleForCurrentAssemblyContext(
994                        final OperationRequiredRole requiredRole) {
995 
996                // Initialize variables:
997                ComposedStructure reqStructure = null;
998                int index = assCtxList.size() - 1;
999                OperationRequiredRole reqRole = requiredRole;
1000 
1001                // Navigate upwards through the list of parent contexts:
1002                while ((reqStructure == null)
1003                                || (!reqStructure.getId().equals(
1004                                                pcmInstance.getSystem().getId()))) {
1005 
1006                        // Set reqStructure to the parent ComposedStructure of this
1007                        // AssemblyContext:
1008                        reqStructure = assCtxList.get(index)
1009                                        .getParentStructure__AssemblyContext();
1010 
1011                        // Check for the RequiredDelegationConnector that is connected to
1012                        // this AssemblyContext:
1013                        RequiredDelegationConnector delConn = null;
1014                        for (Connector conn : reqStructure
1015                                        .getConnectors__ComposedStructure()) {
1016                                if (conn instanceof RequiredDelegationConnector) {
1017                                        RequiredDelegationConnector connector = (RequiredDelegationConnector) conn;
1018                                        if (connector
1019                                                        .getAssemblyContext_RequiredDelegationConnector()
1020                                                        .getId().equals(assCtxList.get(index).getId())
1021                                                        && connector
1022                                                                        .getInnerRequiredRole_RequiredDelegationConnector()
1023                                                                        .getId().equals(reqRole.getId())) {
1024                                                delConn = connector;
1025                                                break;
1026                                        }
1027                                }
1028                        }
1029                        if (delConn == null) {
1030 
1031                                // No RequiredDelegationConnector found:
1032                                return null;
1033                        }
1034 
1035                        // Retrieve the outer required role of the connector:
1036                        reqRole = delConn
1037                                        .getOuterRequiredRole_RequiredDelegationConnector();
1038 
1039                        // Navigate upwards:
1040                        index--;
1041                }
1042 
1043                // No RequiredDelegationConnector found:
1044                return reqRole;
1045        }
1046 
1047        /**
1048         * 
1049         * @param compUsgCtx
1050         * @return
1051         */
1052        private ComputedAllocationContext getExistingComputedAllocationContext(
1053                        ComputedUsageContext compUsgCtx) {
1054                EList<ComputedAllocationContext> allCtxList = pcmInstance
1055                                .getComputedAllocation()
1056                                .getComputedAllocationContexts_ComputedAllocation();
1057                for (ComputedAllocationContext cac : allCtxList) {
1058                        if (cac.getAllocationContext_ComputedAllocationContext().getId()
1059                                        .equals(allCtx.getId())
1060                                        && cac.getUsageContext_ComputedAllocationContext().getId()
1061                                                        .equals(compUsgCtx.getId())) {
1062                                return cac;
1063                        }
1064                }
1065                return null;
1066        }
1067 
1068        /**
1069         * Try to find an existing {@link ComputedUsageContext} for the passed
1070         * ExternalCall. This method checks whether the references
1071         * {@link AssemblyContext} match as well as whether the required variables
1072         * match. If none is found, null is returned and a new
1073         * {@link ComputedUsageContext} needs to be created. As a side effect, the
1074         * {@link ExternalCallInput} of the current context is set by calling
1075         * addExternalCallInputToCurrentContext.
1076         * 
1077         * @param eca
1078         * @return A found matching {@link ComputedUsageContext} or null.
1079         */
1080        private ComputedUsageContext getExistingComputedUsageContext(
1081                        ExternalCallAction eca) {
1082                EList<ExternalCallInput> eciList = compUsgCtx
1083                                .getExternalCallInput_ComputedUsageContext();
1084                if (eciList.size() == 0) {
1085                        EList<ComputedUsageContext> cucList = pcmInstance
1086                                        .getComputedUsage().getUsageContexts_ComputedUsage();
1087 
1088                        // if input has no variables, we can take the first matching one
1089                        // without variables.
1090                        if (eca.getInputVariableUsages__CallAction().size() == 0) {
1091                                for (ComputedUsageContext cuc : cucList) {
1092                                        // assCtx already points to the next assCtx after the
1093                                        // external
1094                                        // call
1095                                        AssemblyContext referencedAssemblyContext = cuc
1096                                                        .getAssemblyContext_ComputedUsageContext();
1097                                        AssemblyContext assemblyContextThisCallIsComingFrom = getAssCtx();
1098                                        if (referencedAssemblyContext.getId().equals(
1099                                                        assemblyContextThisCallIsComingFrom.getId())
1100                                                        && cuc.getInput_ComputedUsageContext()
1101                                                                        .getParameterChacterisations_Input().size() == 0) {
1102                                                // do not forget to create the external call input to
1103                                                // current context:
1104                                                ExternalCallInput extCallIn = addExternalCallInputToCurrentContext(eca);
1105                                                return cuc;
1106                                        }
1107                                }
1108                        }
1109                        ExternalCallInput extCallIn = addExternalCallInputToCurrentContext(eca);
1110                        // check whether this pcm instances context contains matching input,
1111                        // compare by variable list.
1112                        EList<VariableUsage> inputVUList = extCallIn
1113                                        .getParameterCharacterisations_ExternalCallInput();
1114                        ComputedUsageContext cuc = matchVariableUsages(inputVUList);
1115                        if (cuc != null)
1116                                return cuc;
1117                } else {
1118                        // check if matching external call input already exists
1119                        for (ExternalCallInput eci : eciList) {
1120                                if (eci.getExternalCallAction_ExternalCallInput().getId()
1121                                                .equals(eca.getId())) {
1122                                        EList<VariableUsage> inputVUList = eci
1123                                                        .getParameterCharacterisations_ExternalCallInput();
1124 
1125                                        ComputedUsageContext cuc = matchVariableUsages(inputVUList);
1126                                        if (cuc != null)
1127                                                return cuc;
1128                                }
1129                        }
1130                        // matching external call input does not exist, create new one
1131                        ExternalCallInput extCallIn = addExternalCallInputToCurrentContext(eca);
1132                        // check whether following computed usage context contains matching
1133                        // input
1134                        EList<VariableUsage> inputVUList = extCallIn
1135                                        .getParameterCharacterisations_ExternalCallInput();
1136                        ComputedUsageContext cuc = matchVariableUsages(inputVUList);
1137                        if (cuc != null)
1138                                return cuc;
1139                }
1140                return null;
1141        }
1142 
1143        /**
1144         * 
1145         * @param elsa
1146         * @return
1147         */
1148        private ComputedUsageContext getFirstComputedUsageContext(
1149                        EntryLevelSystemCall elsa) {
1150                logger.debug("In getFirstComputedUsageContext");
1151 
1152                EList<VariableUsage> vuList = elsa
1153                                .getInputParameterUsages_EntryLevelSystemCall();
1154                ComputedUsageContext cuc = matchVariableUsages(vuList);
1155                if (cuc != null) {
1156                        logger.debug("Reusing existing computed usage context for "
1157                                        + getAssCtx().getEntityName());
1158                        return cuc;
1159                } else {
1160                        logger.debug("Creating new computed usage context for "
1161                                        + getAssCtx().getEntityName());
1162 
1163                        ComputedUsageContext newCompUsgCtx = ComputedUsageFactory.eINSTANCE
1164                                        .createComputedUsageContext();
1165                        pcmInstance.getComputedUsage().getUsageContexts_ComputedUsage()
1166                                        .add(newCompUsgCtx);
1167 
1168                        newCompUsgCtx.setAssemblyContext_ComputedUsageContext(getAssCtx());
1169 
1170                        Input newInput = ComputedUsageFactory.eINSTANCE.createInput();
1171                        newCompUsgCtx.setInput_ComputedUsageContext(newInput);
1172 
1173                        EList<VariableUsage> parList = elsa
1174                                        .getInputParameterUsages_EntryLevelSystemCall();
1175                        VariableUsageHelper.copySolvedVariableUsageToInput(newCompUsgCtx
1176                                        .getInput_ComputedUsageContext(), this, parList);
1177 
1178                        addComponentParametersToNewContext(newCompUsgCtx);
1179                        return newCompUsgCtx;
1180                }
1181        }
1182 
1183        /**
1184         * 
1185         * @param ref
1186         * @return
1187         */
1188        private String getFullParameterName(AbstractNamedReference ref) {
1189                String name = "";
1190                while (ref instanceof NamespaceReference) {
1191                        NamespaceReference nsRef = (NamespaceReference) ref;
1192                        name += nsRef.getReferenceName() + ".";
1193                        ref = nsRef.getInnerReference_NamespaceReference();
1194                }
1195                return name += ref.getReferenceName();
1196        }
1197 
1198        /**
1199         * Assumes that all parameter specifications are solved for the given
1200         * ExternalCallAction.
1201         * 
1202         * Sums up the mean values for all BYTESIZE characterizations for all input
1203         * parameters (on the lowest level only). If no BYTESIZE is specified,
1204         * assumes 0 bytes.
1205         * 
1206         * @param eca
1207         *            the ExternalCallAction with solved parameters
1208         * @return the mean total parameter bytesize
1209         */
1210        private Double getMeanTotalInputParameterBytesize(ExternalCallInput eci) {
1211                Double meanTotalInputParameterBytesize = 0.0;
1212 
1213                for (VariableUsage usage : eci
1214                                .getParameterCharacterisations_ExternalCallInput()) {
1215                        for (VariableCharacterisation vchar : usage
1216                                        .getVariableCharacterisation_VariableUsage()) {
1217                                if (vchar.getType() == VariableCharacterisationType.BYTESIZE) {
1218                                        ManagedPMF pmf;
1219                                        try {
1220                                                pmf = ManagedPMF.createFromString(vchar
1221                                                                .getSpecification_VariableCharacterisation()
1222                                                                .getSpecification());
1223                                        } catch (Exception e) {
1224                                                throw new RuntimeException(
1225                                                                "Error calculating MeanTotalInputParameterBytesize.");
1226                                        }
1227 
1228                                        meanTotalInputParameterBytesize += pmf.getExpectedValue();
1229                                }
1230                        }
1231                }
1232 
1233                return meanTotalInputParameterBytesize;
1234        }
1235 
1236        /**
1237         * Assumes that all parameter specifications are solved for the given
1238         * ExternalCallAction.
1239         * 
1240         * Sums up the mean values for all BYTESIZE characterizations for all output
1241         * parameters (on the lowest level only). If no BYTESIZE is specified,
1242         * assumes 0 bytes.
1243         * 
1244         * @param eca
1245         *            the ExternalCallAction with solved parameters
1246         * @return the mean total parameter bytesize
1247         */
1248        private Double getMeanTotalOutputParameterBytesize(ExternalCallOutput eco) {
1249                Double meanTotalOutputParameterBytesize = 0.0;
1250 
1251                for (VariableUsage usage : eco
1252                                .getParameterCharacterisations_ExternalCallOutput()) {
1253                        for (VariableCharacterisation vchar : usage
1254                                        .getVariableCharacterisation_VariableUsage()) {
1255                                if (vchar.getType() == VariableCharacterisationType.BYTESIZE) {
1256                                        ManagedPMF pmf;
1257                                        try {
1258                                                pmf = ManagedPMF.createFromString(vchar
1259                                                                .getSpecification_VariableCharacterisation()
1260                                                                .getSpecification());
1261                                        } catch (Exception e) {
1262                                                throw new RuntimeException(
1263                                                                "Error calculating MeanTotalInputParameterBytesize.");
1264                                        }
1265 
1266                                        meanTotalOutputParameterBytesize += pmf.getExpectedValue();
1267                                }
1268                        }
1269                }
1270 
1271                return meanTotalOutputParameterBytesize;
1272        }
1273 
1274        /**
1275         * It can be multiple ones if the component is replicated to several
1276         * servers. Otherwise the list contains only one element.
1277         * 
1278         * @param nextAssCtxIterator
1279         * @return
1280         * @see #getNextAllocationContextList(List)
1281         */
1282        private List<AllocationContext> getNextAllocationContextList(
1283                        Iterator<AssemblyContext> nextAssCtxIterator) {
1284                if (nextAssCtxIterator.hasNext()) {
1285                        AssemblyContext nextAssCtx = nextAssCtxIterator.next();
1286 
1287                        EList<AllocationContext> allCtxList = pcmInstance.getAllocation()
1288                                        .getAllocationContexts_Allocation();
1289 
1290                        // return all AllocationContexts this AssemblyContext is allocated
1291                        // to
1292                        List<AllocationContext> targetAllocationContextList = new ArrayList<AllocationContext>();
1293                        for (AllocationContext allCtx : allCtxList) {
1294                                if (allCtx.getAssemblyContext_AllocationContext().getId()
1295                                                .equals(nextAssCtx.getId())) {
1296                                        targetAllocationContextList.add(allCtx);
1297                                }
1298                        }
1299                        if (targetAllocationContextList.size() >= 0) {
1300                                return targetAllocationContextList;
1301                        } else {
1302                                return getNextAllocationContextList(nextAssCtxIterator);
1303                        }
1304                }
1305                // TODO: throw exception
1306                return null;
1307        }
1308 
1309        /**
1310         * Get the next {@link AllocationContext}s. It can be multiple ones if the
1311         * component is replicated to several servers. Otherwise the list contains
1312         * only one element. If this is a composite component, then the passed
1313         * nextAssCtxList contains several {@link AssemblyContext}. The outer
1314         * component is the one that is usally allocated (if composite and
1315         * non-completion). If no allocation for the outer can be found, check for
1316         * inner (e.g. for subsystems and completions).
1317         * 
1318         * @param nextAssCtxList
1319         *            : List of the hierarchy of the current assembly contexts.
1320         *            Contains several {@link AssemblyContext} if the components are
1321         *            composite The first is the outmost component.
1322         * @see ContextWrapper#getAssCtxList()
1323         * @return
1324         */
1325        private List<AllocationContext> getNextAllocationContextList(
1326                        List<AssemblyContext> nextAssCtxList) {
1327                return getNextAllocationContextList(nextAssCtxList.iterator());
1328        }
1329 
1330        /**
1331         * Calculated the next context based on the passed one and the current
1332         * allCtx of this ContextWrapper.
1333         * 
1334         * @param compUsgCtx
1335         * @return
1336         */
1337        private ComputedAllocationContext getNextComputedAllocationContext(
1338                        ComputedUsageContext compUsgCtx) {
1339                logger.debug("In getNextComputedAllocationContext ");
1340 
1341                ComputedAllocationContext cac = getExistingComputedAllocationContext(compUsgCtx);
1342                if (cac != null) {
1343                        logger.debug("Reusing existing computed allocation context for "
1344                                        + getAssCtx().getEntityName());
1345                        return cac;
1346                } else {
1347                        logger.debug("Creating new computed allocation context for "
1348                                        + getAssCtx().getEntityName());
1349                        ComputedAllocationContext newCompAllCtx = ComputedAllocationFactory.eINSTANCE
1350                                        .createComputedAllocationContext();
1351                        pcmInstance.getComputedAllocation()
1352                                        .getComputedAllocationContexts_ComputedAllocation().add(
1353                                                        newCompAllCtx);
1354                        newCompAllCtx.setUsageContext_ComputedAllocationContext(compUsgCtx);
1355                        newCompAllCtx
1356                                        .setAllocationContext_ComputedAllocationContext(allCtx);
1357                        return newCompAllCtx;
1358                }
1359        }
1360 
1361        /**
1362         * @param eca
1363         * @return
1364         */
1365        private ComputedUsageContext getNextComputedUsageContext(
1366                        ExternalCallAction eca) {
1367                logger.debug("In getNextComputedUsageContext " + eca.getEntityName());
1368 
1369                ComputedUsageContext cuc = getExistingComputedUsageContext(eca);
1370                if (cuc != null) {
1371                        logger.debug("Reusing existing computed usage context for "
1372                                        + getAssCtx().getEntityName());
1373                        return cuc;
1374                } else {
1375                        logger.debug("Creating new computed usage context for "
1376                                        + getAssCtx().getEntityName());
1377                        return createNewComputedUsageContext(eca);
1378                }
1379        }
1380 
1381        /**
1382         * Retrieves the OperationRequiredRole that belongs to the given external
1383         * call action.
1384         * 
1385         * It is assumed that the external call action belongs to the component that
1386         * is encapsulated by the current assembly context. The current assembly
1387         * context is the last element of assCtxList.
1388         * 
1389         * @param externalCallAction
1390         *            the external call action
1391         * @return the OperationRequiredRole
1392         */
1393        private OperationRequiredRole getRequiredRoleForExternalCallAction(
1394                        final ExternalCallAction externalCallAction) {
1395 
1396                // First retrieve the interface:
1397                OperationInterface reqInterface = externalCallAction
1398                                .getCalledService_ExternalService()
1399                                .getInterface__OperationSignature();
1400 
1401                // Search through the required roles of the current AssemblyContext:
1402                for (RequiredRole role : assCtxList.get(assCtxList.size() - 1)
1403                                .getEncapsulatedComponent__AssemblyContext()
1404                                .getRequiredRoles_InterfaceRequiringEntity()) {
1405                        if (role instanceof OperationRequiredRole) {
1406                                if (((OperationRequiredRole) role)
1407                                                .getRequiredInterface__OperationRequiredRole().getId()
1408                                                .equals(reqInterface.getId())) {
1409                                        return (OperationRequiredRole) role;
1410                                }
1411                        }
1412                }
1413 
1414                // Nothing found (should not happen):
1415                return null;
1416        }
1417 
1418        /**
1419         * 
1420         * @param cuc
1421         * @param cac
1422         */
1423        private void handleComputedContexts(ComputedUsageContext cuc,
1424                        ComputedAllocationContext cac) {
1425                compUsgCtx = cuc;
1426                compUsgCtx.setAssemblyContext_ComputedUsageContext(getAssCtx());
1427                compAllCtx = cac;
1428                compAllCtx.setAllocationContext_ComputedAllocationContext(allCtx);
1429                readComputedContextsToHashMaps();
1430        }
1431 
1432        /**
1433         * Tries to find the {@link ComputedUsageContext} in the pcm instance that
1434         * 1) references the same assembly context for that we want to have an
1435         * ComputedUsageContext and 2) references the same list of variables we are
1436         * looking for.
1437         * 
1438         * @param vuList
1439         * @return A matching {@link ComputedUsageContext} or null.
1440         */
1441        private ComputedUsageContext matchVariableUsages(EList<VariableUsage> vuList) {
1442                EList<ComputedUsageContext> cucList = pcmInstance.getComputedUsage()
1443                                .getUsageContexts_ComputedUsage();
1444                for (ComputedUsageContext cuc : cucList) {
1445                        if (cuc.getAssemblyContext_ComputedUsageContext().getId().equals(
1446                                        getAssCtx().getId())) {
1447                                Input input = cuc.getInput_ComputedUsageContext();
1448                                EList<VariableUsage> vuList2 = input
1449                                                .getParameterChacterisations_Input();
1450 
1451                                // logger.debug("List1: "+vuList);
1452                                // logger.debug("List2: "+vuList2);
1453 
1454                                if (areEqual(vuList, vuList2)) {
1455                                        // logger.debug("Are Equal Successful!");
1456                                        return cuc;
1457                                }
1458                        }
1459                }
1460                logger.debug("Matching Input Variables for External Call failed.");
1461                return null;
1462        }
1463 
1464        /**
1465         * 
1466         */
1467        private void readComputedContextsToHashMaps() {
1468                EList<BranchProbability> bpList = compUsgCtx
1469                                .getBranchProbabilities_ComputedUsageContext();
1470                for (BranchProbability bp : bpList) {
1471                        branchProbs.put(bp.getBranchtransition_BranchProbability(), bp
1472                                        .getProbability());
1473                }
1474 
1475                EList<LoopIteration> liList = compUsgCtx
1476                                .getLoopiterations_ComputedUsageContext();
1477                for (LoopIteration li : liList) {
1478                        String spec = li.getSpecification_LoopIteration()
1479                                        .getSpecification();
1480                        ManagedPMF pmf = null;
1481                        try {
1482                                pmf = ManagedPMF.createFromString(spec);
1483                        } catch (StringNotPDFException e) {
1484                                e.printStackTrace();
1485                        } catch (RecognitionException e) {
1486                                e.printStackTrace();
1487                        }
1488                        loopIters.put(li.getLoopaction_LoopIteration(), pmf);
1489                }
1490 
1491                EList<ResourceDemand> rdList = compAllCtx
1492                                .getResourceDemands_ComputedAllocationContext();
1493                for (ResourceDemand rd : rdList) {
1494                        // These are already solved expressions, they do not contain
1495                        // variables.
1496                        String spec = rd.getSpecification_ResourceDemand()
1497                                        .getSpecification();
1498 
1499                        Expression rdExpression = ExpressionHelper.parseToExpression(spec);
1500                        ExpressionToPDFWrapper rdWrapper = null;
1501 
1502                        try {
1503                                rdWrapper = ExpressionToPDFWrapper
1504                                                .createExpressionToPDFWrapper(rdExpression);
1505                        } catch (Exception e) {
1506                                throw new IllegalArgumentException(
1507                                                "Could not derive a PDF from expression \"" + spec
1508                                                                + "\"; Exception type: "
1509                                                                + e.getClass().getName()
1510                                                                + "; Error message: \"" + e.getMessage() + "\"");
1511                        }
1512                        resDemands.put(rd.getParametricResourceDemand_ResourceDemand(),
1513                                        rdWrapper);
1514 
1515                        /*
1516                         * FunctionLiteral function;
1517                         * function.getParameters_FunctionLiteral()
1518                         */
1519 
1520                        // ManagedPDF pdf = null;
1521                        // try {
1522                        // pdf = ManagedPDF.createFromString(spec);
1523                        // } catch (StringNotPDFException e) {
1524                        // e.printStackTrace();
1525                        // } catch (RecognitionException e) {
1526                        // e.printStackTrace();
1527                        // }
1528 
1529                }
1530 
1531                // Store the mapping which ParametricResourceDemand accesses which
1532                // Resource in this context.
1533                for (ResourceDemand rd : rdList) {
1534                        ParametricResourceDemand prd = rd
1535                                        .getParametricResourceDemand_ResourceDemand();
1536                        ProcessingResourceType prt = prd
1537                                        .getRequiredResource_ParametricResourceDemand();
1538                        EList<ProcessingResourceSpecification> prsList = allCtx
1539                                        .getResourceContainer_AllocationContext()
1540                                        .getActiveResourceSpecifications_ResourceContainer();
1541                        for (ProcessingResourceSpecification prs : prsList) {
1542                                ProcessingResourceType prsType = prs
1543                                                .getActiveResourceType_ActiveResourceSpecification();
1544                                if (prsType.getId().equals(prt.getId())) {
1545                                        procResources.put(prd, prs);
1546                                }
1547                        }
1548 
1549                        // special case for system external calls:
1550                        if (prt.getEntityName().equals("SystemExternalResource")) {
1551                                EList<ResourceContainer> containerList = getPcmInstance()
1552                                                .getResourceEnvironment()
1553                                                .getResourceContainer_ResourceEnvironment();
1554                                for (ResourceContainer container : containerList) {
1555                                        if (container.getEntityName().equals(
1556                                                        "SystemExternalResourceContainer")) {
1557                                                ProcessingResourceSpecification prs = container
1558                                                                .getActiveResourceSpecifications_ResourceContainer()
1559                                                                .get(0);
1560                                                procResources.put(prd, prs);
1561                                        }
1562                                }
1563                        }
1564 
1565                }
1566 
1567                EList<ExternalCallInput> eciList = compUsgCtx
1568                                .getExternalCallInput_ComputedUsageContext();
1569                EList<LinkingResource> lrList = pcmInstance.getResourceEnvironment()
1570                                .getLinkingResources__ResourceEnvironment();
1571                ResourceContainer rc1 = allCtx.getResourceContainer_AllocationContext();
1572                for (ExternalCallInput eci : eciList) {
1573                        ExternalCallAction eca = eci
1574                                        .getExternalCallAction_ExternalCallInput();
1575 
1576                        List<AssemblyContext> acList = PCMInstanceHelper
1577                                        .getHandlingAssemblyContexts(eca, assCtxList);
1578 
1579                        List<AllocationContext> allocationContextList = getNextAllocationContextList(acList);
1580                        for (AllocationContext nextAllCtx : allocationContextList) {
1581 
1582                                ResourceContainer rc2 = nextAllCtx
1583                                                .getResourceContainer_AllocationContext();
1584 
1585                                if (rc1 != rc2) {
1586                                        for (LinkingResource lr : lrList) {
1587 
1588                                                // ------------------------------
1589                                                // contains() does NOT work (fb)!
1590                                                // ------------------------------
1591                                                // if
1592                                                // (lr.getFromResourceContainer_LinkingResource().contains(rc1)
1593                                                // &&
1594                                                // lr.getToResourceContainer_LinkingResource().contains(rc2)){
1595 
1596                                                boolean rc1Contained = exists(
1597                                                                lr
1598                                                                                .getConnectedResourceContainers_LinkingResource(),
1599                                                                rc1);
1600                                                boolean rc2Contained = exists(
1601                                                                lr
1602                                                                                .getConnectedResourceContainers_LinkingResource(),
1603                                                                rc2);
1604                                                if (rc1Contained && rc2Contained) {
1605                                                        CommunicationLinkResourceSpecification clrs = lr
1606                                                                        .getCommunicationLinkResourceSpecifications_LinkingResource();
1607                                                        linkResources.put(eca, nextAllCtx, clrs);
1608                                                }
1609                                        }
1610                                }
1611                        }
1612                }
1613 
1614                // also compute and store parameter BYTESIZEs
1615                for (ExternalCallInput eci : compUsgCtx
1616                                .getExternalCallInput_ComputedUsageContext()) {
1617                        inputParameterBytesizes.put(eci
1618                                        .getExternalCallAction_ExternalCallInput(),
1619                                        getMeanTotalInputParameterBytesize(eci));
1620                }
1621                for (ExternalCallOutput eco : compUsgCtx
1622                                .getExternalCallOutput_ComputedUsageContext()) {
1623                        outputParameterBytesizes.put(eco
1624                                        .getExternalCallAction_ExternalCallOutput(),
1625                                        getMeanTotalOutputParameterBytesize(eco));
1626                }
1627        }
1628}

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