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

COVERAGE SUMMARY FOR SOURCE FILE [Rdseff2Lqn.java]

nameclass, %method, %block, %line, %
Rdseff2Lqn.java0%   (0/1)0%   (0/25)0%   (0/1555)0%   (0/295)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Rdseff2Lqn0%   (0/1)0%   (0/25)0%   (0/1555)0%   (0/295)
<static initializer> 0%   (0/1)0%   (0/5)0%   (0/2)
Rdseff2Lqn (LqnBuilder, ContextWrapper): void 0%   (0/1)0%   (0/9)0%   (0/4)
caseAcquireAction (AcquireAction): String 0%   (0/1)0%   (0/95)0%   (0/22)
caseBranchAction (BranchAction): String 0%   (0/1)0%   (0/87)0%   (0/17)
caseCollectionIteratorAction (CollectionIteratorAction): String 0%   (0/1)0%   (0/11)0%   (0/3)
caseExternalCallAction (ExternalCallAction): String 0%   (0/1)0%   (0/7)0%   (0/1)
caseForkAction (ForkAction): String 0%   (0/1)0%   (0/215)0%   (0/32)
caseForkActionOld (ForkAction): String 0%   (0/1)0%   (0/62)0%   (0/14)
caseInternalAction (InternalAction): String 0%   (0/1)0%   (0/199)0%   (0/32)
caseLoopAction (LoopAction): String 0%   (0/1)0%   (0/11)0%   (0/3)
caseReleaseAction (ReleaseAction): String 0%   (0/1)0%   (0/57)0%   (0/13)
caseResourceDemandingBehaviour (ResourceDemandingBehaviour): String 0%   (0/1)0%   (0/7)0%   (0/1)
caseResourceDemandingSEFF (ResourceDemandingSEFF): String 0%   (0/1)0%   (0/56)0%   (0/11)
caseSetVariableAction (SetVariableAction): String 0%   (0/1)0%   (0/11)0%   (0/2)
caseStartAction (StartAction): String 0%   (0/1)0%   (0/163)0%   (0/29)
caseStopAction (StopAction): String 0%   (0/1)0%   (0/12)0%   (0/3)
createCallActivity (String, ResourceDemandingSEFF, CallType): void 0%   (0/1)0%   (0/7)0%   (0/2)
createCallActivity (String, ResourceDemandingSEFF, CallType, double): void 0%   (0/1)0%   (0/45)0%   (0/10)
getLoopIterations (AbstractLoopAction): String 0%   (0/1)0%   (0/24)0%   (0/8)
getProcessorName (ParametricResourceDemand): String 0%   (0/1)0%   (0/60)0%   (0/9)
getStartAction (ResourceDemandingBehaviour): StartAction 0%   (0/1)0%   (0/8)0%   (0/3)
getStopAction (ResourceDemandingBehaviour): StopAction 0%   (0/1)0%   (0/8)0%   (0/3)
handleExternalCallAction (ExternalCallAction, CallType, AbstractAction): String 0%   (0/1)0%   (0/310)0%   (0/53)
handleLoop (AbstractLoopAction, String): void 0%   (0/1)0%   (0/35)0%   (0/8)
handleLoopBody (AbstractLoopAction, String): String 0%   (0/1)0%   (0/51)0%   (0/10)

1package de.uka.ipd.sdq.pcmsolver.transformations.pcm2lqn;
2 
3import java.util.ArrayList;
4import java.util.HashMap;
5import java.util.List;
6import java.util.Map;
7 
8import org.apache.log4j.Logger;
9import org.eclipse.emf.common.util.EList;
10 
11import LqnCore.ActivityDefType;
12import LqnCore.ActivityMakingCallType;
13import LqnCore.ActivityPhasesType;
14import LqnCore.CallOrderType;
15import LqnCore.EntryType;
16import LqnCore.PhaseActivities;
17import LqnCore.PrecedenceType;
18import LqnCore.ProcessorType;
19import LqnCore.TaskType;
20import LqnCore.TypeType;
21import de.uka.ipd.sdq.pcm.allocation.AllocationContext;
22import de.uka.ipd.sdq.pcm.resourceenvironment.CommunicationLinkResourceSpecification;
23import de.uka.ipd.sdq.pcm.resourceenvironment.ProcessingResourceSpecification;
24import de.uka.ipd.sdq.pcm.resourceenvironment.ResourceContainer;
25import de.uka.ipd.sdq.pcm.resourcetype.ProcessingResourceType;
26import de.uka.ipd.sdq.pcm.seff.AbstractAction;
27import de.uka.ipd.sdq.pcm.seff.AbstractBranchTransition;
28import de.uka.ipd.sdq.pcm.seff.AbstractLoopAction;
29import de.uka.ipd.sdq.pcm.seff.AcquireAction;
30import de.uka.ipd.sdq.pcm.seff.BranchAction;
31import de.uka.ipd.sdq.pcm.seff.CollectionIteratorAction;
32import de.uka.ipd.sdq.pcm.seff.ExternalCallAction;
33import de.uka.ipd.sdq.pcm.seff.ForkAction;
34import de.uka.ipd.sdq.pcm.seff.ForkedBehaviour;
35import de.uka.ipd.sdq.pcm.seff.InternalAction;
36import de.uka.ipd.sdq.pcm.seff.LoopAction;
37import de.uka.ipd.sdq.pcm.seff.ReleaseAction;
38import de.uka.ipd.sdq.pcm.seff.ResourceDemandingBehaviour;
39import de.uka.ipd.sdq.pcm.seff.ResourceDemandingSEFF;
40import de.uka.ipd.sdq.pcm.seff.SetVariableAction;
41import de.uka.ipd.sdq.pcm.seff.StartAction;
42import de.uka.ipd.sdq.pcm.seff.StopAction;
43import de.uka.ipd.sdq.pcm.seff.SynchronisationPoint;
44import de.uka.ipd.sdq.pcm.seff.seff_performance.ParametricResourceDemand;
45import de.uka.ipd.sdq.pcm.seff.util.SeffSwitch;
46import de.uka.ipd.sdq.pcmsolver.transformations.ContextWrapper;
47import de.uka.ipd.sdq.pcmsolver.transformations.EMFHelper;
48import de.uka.ipd.sdq.pcmsolver.visitors.EMFQueryHelper;
49import de.uka.ipd.sdq.pcmsolver.visitors.ExpressionHelper;
50import de.uka.ipd.sdq.probfunction.math.IContinousPDF;
51import de.uka.ipd.sdq.probfunction.math.IProbabilityDensityFunction;
52import de.uka.ipd.sdq.probfunction.math.ManagedPDF;
53import de.uka.ipd.sdq.probfunction.math.ManagedPMF;
54import de.uka.ipd.sdq.probfunction.math.exception.DomainNotNumbersException;
55import de.uka.ipd.sdq.probfunction.math.exception.FunctionNotInTimeDomainException;
56 
57/**
58 * Visits one SEFF. An {@link Rdseff2Lqn} instance creates a new 
59 * {@link Rdseff2Lqn} instance when visiting an external call, this new one
60 * is responsible for the other SEFF. 
61 * 
62 * Thus, only information local to this SEFF could be stored as member variables here.
63 * 
64 *  Each visitor method (case*) returns the id of the first generated LQN model element, 
65 *  so that it can be used by the handler of the previous model element
66 *  to connect itself to this successor.
67 *  
68 * @author koziolek, martens
69 *
70 */
71public class Rdseff2Lqn extends SeffSwitch<String> {
72 
73        private static Logger logger = Logger.getLogger(Rdseff2Lqn.class.getName());
74 
75        private ContextWrapper myContextWrapper;
76        private LqnBuilder lqnBuilder;
77        
78        public Rdseff2Lqn(LqnBuilder aLqnBuilder, ContextWrapper aContextWrapper) {
79                lqnBuilder = aLqnBuilder;
80                myContextWrapper = aContextWrapper;
81        }
82 
83        /**
84         * Does nothing yet, is ignored and the visitor continues with the successor.
85         * Can be implemented with a Semaphore task in LQN. 
86         * 
87         * Excerpt from LQN 4.3 documentation:
88         * 
89         * Semaphore Task: Semaphore tasks are used to model passive resources such as buffers. They always have two entries
90         * which are used to signal and wait the semaphore. The wait entry must be called using a synchronous request
91         * whereas the signal entry can be called using any type of request. Once a request is accepted by the wait entry,
92         * no further requests will be accepted until a request is processed by the signal entry. The signal and wait entries
93         * do not have to called from a common task. However, the two entries must share a common call graph, and the
94         * call graph must be deterministic. The entries themselves can be defined using phases or activies and can make
95         * requests to other tasks. Counting semaphores can be modeled using a multiserver.
96         * 
97         */
98        @Override
99        public String caseAcquireAction(AcquireAction object) {
100                
101                String successorId;
102                if (lqnBuilder.isLQSimAnalysis()) {
103                        String id = Pcm2LqnHelper.getId(object, myContextWrapper);
104                        String passiveResourceId = Pcm2LqnHelper.getIdForPassiveResource(object.getPassiveresource_AcquireAction(), myContextWrapper.getAllCtx());
105                        
106                        ProcessorType pt = lqnBuilder.addProcessor(passiveResourceId);
107                        
108                        lqnBuilder.addSemaphoreTask(passiveResourceId, pt, Integer.valueOf(object
109                                        .getPassiveresource_AcquireAction()
110                                        .getCapacity_PassiveResource().getSpecification()));
111 
112                        ActivityDefType adt = lqnBuilder.addActivityDef(id);
113                        adt.setCallOrder(CallOrderType.DETERMINISTIC);
114                        
115                        lqnBuilder.addActivityMakingCall(id, Pcm2LqnHelper.getWaitEntryId(passiveResourceId), CallType.SYNCH);
116                        successorId = (String) doSwitch(object
117                                        .getSuccessor_AbstractAction());
118                        lqnBuilder.addSequencePrecedence(id, successorId);
119                        return id;
120                } else {
121                        if (object.getPassiveresource_AcquireAction().getEntityName().toLowerCase().contains("pool")){
122                                logger.warn("Passive resource pool found. Support by PCM2LQN is limited. Please analyze the results carefully.");
123                                Integer poolCapacity = Integer.valueOf(object.getPassiveresource_AcquireAction().getCapacity_PassiveResource().getSpecification());        
124                                lqnBuilder.setPoolCapacity(poolCapacity);
125                        } else {
126                                logger.warn("Ignored release action because it is not supported by LQNS. Be aware that the passive resource is not analysed.");
127                        }
128                        successorId = (String) doSwitch(object
129                                        .getSuccessor_AbstractAction());
130                        return successorId;
131                }
132                
133                
134        }
135 
136        /**
137         * Does nothing yet, is ignored and the visitor continues with the successor.
138         */
139        @Override
140        public String caseReleaseAction(ReleaseAction object) {
141                
142                String successorId;
143                if (lqnBuilder.isLQSimAnalysis()) {
144                        String id = Pcm2LqnHelper.getId(object, myContextWrapper);
145                        
146                        ActivityDefType adt = lqnBuilder.addActivityDef(id);
147                        adt.setCallOrder(CallOrderType.DETERMINISTIC);
148                        
149                        String passiveResourceId = Pcm2LqnHelper.getIdForPassiveResource(object.getPassiveResource_ReleaseAction(), myContextWrapper.getAllCtx());
150                        
151                        lqnBuilder.addActivityMakingCall(id, Pcm2LqnHelper.getSignalEntryId(passiveResourceId), CallType.SYNCH);
152                        successorId = (String) doSwitch(object.getSuccessor_AbstractAction());
153                        lqnBuilder.addSequencePrecedence(id, successorId);
154                        return id;
155                
156                } else {
157                        logger.warn("Ignored release action because it is not supported by LQNS. Be aware that the passive resource is not analysed.");
158                        successorId = (String) doSwitch(object
159                                        .getSuccessor_AbstractAction());
160                        return successorId;
161                }
162                
163        }
164 
165        @Override
166        public String caseResourceDemandingSEFF(ResourceDemandingSEFF object) {
167                String id = Pcm2LqnHelper.getId(object, myContextWrapper);
168                                
169                ProcessorType pt = lqnBuilder.addProcessor(id);
170                
171                TaskType tt = lqnBuilder.addTask(id, pt);
172                //tt.setMultiplicity(new BigInteger("1"));
173                //tt.setScheduling(TaskSchedulingType.INF);
174 
175                EntryType et = lqnBuilder.addEntry(id, tt);
176                lqnBuilder.addTaskActivityGraph(tt);
177                
178                ResourceDemandingBehaviour rdb = (ResourceDemandingBehaviour)object;
179                String startId = (String)doSwitch(getStartAction(rdb));
180                String stopId = Pcm2LqnHelper.getId(getStopAction(rdb), myContextWrapper);
181                lqnBuilder.addReplyActivity(id, startId, stopId);
182                
183                lqnBuilder.restoreFormerTaskActivityGraph();
184                
185                return et.getName();
186        }
187 
188        @Override
189        public String caseLoopAction(LoopAction object) {
190                String id = Pcm2LqnHelper.getId(object, myContextWrapper);
191                handleLoop(object, id);
192                return id;
193                
194        }
195 
196        private void handleLoop(AbstractLoopAction object, String id) {
197                String startId = handleLoopBody(object,id);
198                lqnBuilder.addActivityDef(id); // for the loop action
199                // makes an external call to the task representing the loop body:
200                ActivityMakingCallType amct = lqnBuilder.addActivityMakingCall(id,
201                                startId, CallType.SYNCH);
202                amct.setCallsMean(getLoopIterations(object));
203 
204                String successorId = (String)doSwitch(object.getSuccessor_AbstractAction());
205                lqnBuilder.addSequencePrecedence(id, successorId);
206        }
207        
208        private String handleLoopBody(AbstractLoopAction loop,String id) {
209                ProcessorType pt = lqnBuilder.addProcessor(id);
210                TaskType tt = lqnBuilder.addTask(id,pt);
211                EntryType et = lqnBuilder.addEntry(id,tt);
212                lqnBuilder.addTaskActivityGraph(tt);
213 
214                ResourceDemandingBehaviour rdb = loop.getBodyBehaviour_Loop();
215                String startId = (String) doSwitch(getStartAction(rdb));
216                String stopId = Pcm2LqnHelper.getId(getStopAction(rdb), myContextWrapper);
217                lqnBuilder.addReplyActivity(id, startId, stopId);
218                
219                lqnBuilder.restoreFormerTaskActivityGraph();
220                
221                return startId;
222        }
223 
224        private String getLoopIterations(AbstractLoopAction loop) {
225                ManagedPMF pmf = myContextWrapper.getLoopIterations(loop);
226                if (pmf != null) {
227                        try {
228                                return pmf.getPmfTimeDomain().getArithmeticMeanValue() + "";
229                        } catch (DomainNotNumbersException e) {
230                                return "0.0";
231                        } catch (FunctionNotInTimeDomainException e) {
232                                return "0.0";
233                        }
234                } else {
235                        return "0.0";
236                }
237        }
238 
239        @Override
240        public String caseCollectionIteratorAction(CollectionIteratorAction object) {
241                String id = Pcm2LqnHelper.getId(object, myContextWrapper);
242                handleLoop(object, id);
243                return id;
244        }
245 
246        @Override
247        public String caseResourceDemandingBehaviour(ResourceDemandingBehaviour object) {
248                return doSwitch(getStartAction(object));
249        }
250        
251        @Override
252        public String caseStartAction(StartAction object) {
253                String id = Pcm2LqnHelper.getId(object, myContextWrapper);
254                String entryId = "";
255                
256                if (object.eContainer() instanceof ResourceDemandingSEFF){
257                        ResourceDemandingSEFF rdseff = (ResourceDemandingSEFF)object.eContainer();
258                        ActivityDefType adt = lqnBuilder.addActivityDef(id);
259                        entryId = Pcm2LqnHelper.getId(rdseff, myContextWrapper)+"_Entry";
260                        adt.setBoundToEntry(entryId);
261                } else if (object.eContainer().eContainer() instanceof LoopAction){
262                        LoopAction la = (LoopAction)object.eContainer().eContainer();
263                        ActivityDefType adt = lqnBuilder.addActivityDef(id);
264                        entryId = Pcm2LqnHelper.getId(la, myContextWrapper)+"_Entry";
265                        adt.setBoundToEntry(entryId);
266                } else if (object.eContainer().eContainer() instanceof CollectionIteratorAction){
267                        CollectionIteratorAction cia = (CollectionIteratorAction)object.eContainer().eContainer();
268                        ActivityDefType adt = lqnBuilder.addActivityDef(id);
269                        entryId = Pcm2LqnHelper.getId(cia, myContextWrapper)+"_Entry";
270                        adt.setBoundToEntry(entryId);
271                } else if (object.eContainer().eContainer() instanceof SynchronisationPoint){
272                        lqnBuilder.addActivityDef(id);
273                } else if (object.eContainer() instanceof ForkedBehaviour){
274                        ForkedBehaviour fb = (ForkedBehaviour)object.eContainer();
275                        ActivityDefType adt = lqnBuilder.addActivityDef(id);
276                        entryId = Pcm2LqnHelper.getIdForForkedBehaviour(fb, myContextWrapper)+"_Entry";
277                        adt.setBoundToEntry(entryId);
278                } else { //nested resource demanding behaviour
279                        lqnBuilder.addActivityDef(id);
280                }
281                
282                String successorId = (String) doSwitch(object.getSuccessor_AbstractAction());
283                lqnBuilder.addSequencePrecedence(id, successorId);
284                
285                if (entryId.equals("")) return id;
286                else return entryId;
287        }
288        
289 
290        @Override
291        public String caseBranchAction(BranchAction object) {
292                String id = Pcm2LqnHelper.getId(object, myContextWrapper);
293                
294                lqnBuilder.addActivityDef(id);
295                PrecedenceType ptBegin = lqnBuilder.addBeginBranchPrecedence(id);
296                PrecedenceType ptEnd = lqnBuilder.addEndBranchPrecedence();
297 
298                EList<AbstractBranchTransition> btList = object.getBranches_Branch();
299                for (AbstractBranchTransition bt : btList) {
300                        ResourceDemandingBehaviour rdb = bt.getBranchBehaviour_BranchTransition();
301 
302                        // the lqn solver complains if a branch has zero probability
303//                        if(contextWrapper.getBranchProbability(bt)!=0.0){
304                        Double branchProbNumeric = myContextWrapper.getBranchProbability(bt);
305                        if (branchProbNumeric > 0){
306                                String startId = (String) doSwitch(rdb);
307        
308                                String branchProb = branchProbNumeric.toString();
309                                
310                                lqnBuilder.addActivityOrType(startId,branchProb, ptBegin);
311 
312                                String stopId = Pcm2LqnHelper.getId(getStopAction(rdb), myContextWrapper);
313                                lqnBuilder.addActivityType(stopId, ptEnd);
314                        }
315                }
316 
317                String successorId = (String) doSwitch(object.getSuccessor_AbstractAction());
318                ptEnd.getPost().getActivity().setName(successorId);
319 
320                //If a precedence with exactly the same activities is already there, 
321                //this one needs to be deleted. 
322                //This can happen if this SEFF is called from multiple contexts. 
323                //TODO: should we not be able to distinguish multiple contexts?
324                // -> I have put the deletion of duplicate precedences in the LQNBuilder. 
325                
326 
327                return id;
328        }
329 
330        @Override
331        public String caseSetVariableAction(SetVariableAction object) {
332                Pcm2LqnHelper.getId(object, myContextWrapper);
333                return doSwitch(object.getSuccessor_AbstractAction());
334        }
335 
336        @Override
337        public String caseExternalCallAction(ExternalCallAction object) {
338                return handleExternalCallAction(object, CallType.SYNCH, object.getSuccessor_AbstractAction());
339        }
340        
341        /**
342         * Handle an {@link ExternalCallAction}
343         * @param object The {@link ExternalCallAction}
344         * @param callType
345         * @param successor The successor action is determined by the caller, so that it does not necessarily have to be 
346         *        object.getSuccessor_AbstractAction(). For example, when simplifying a fork with internal ExternalCalls
347         *        to asynchronous LQN calls, the proper successor is the successor of the ForkAction, not of the 
348         *        ExternalCall (which is a StopAction that is pruned in that case) 
349         * @return The id of the first generated LQN model element, to be connected with the successor.  
350         */
351        private String handleExternalCallAction(ExternalCallAction object, CallType callType, AbstractAction successor){
352                String callId = Pcm2LqnHelper.getId(object, myContextWrapper);
353                
354                AllocationContext callerAllocationContext = myContextWrapper.getAllCtx();
355                
356                ResourceDemandingSEFF seff = (ResourceDemandingSEFF)myContextWrapper.getNextSEFF(object);
357                if (seff == null){
358                        // this is a system external call
359                        // we continue with the internal action added after this action
360                        //logger.warn("Call "+object.getId()+" does not call a seff, ignoring it. Note that time required for system external calls are not supported by PCM2LQN yet.");
361                        return doSwitch(object.getSuccessor_AbstractAction());
362                } else {
363                        ContextWrapper oldContextWrapper = (ContextWrapper)myContextWrapper.clone();
364 
365 
366                        List<ContextWrapper> contextWrapperList = myContextWrapper.getContextWrapperFor(object);
367                        List<AllocationContext> calledAllocationContextList = new ArrayList<AllocationContext>(contextWrapperList.size());
368                                                
369                        // if one of the contextWrappers refers to the same allocation context than the current one, then 
370                        // then direct all calls to only this one
371                        // assume there is at most component instance per resource container (more should be prohibited by the metamodel)
372                        boolean localComponentInstanceAvailable = false;
373                        ContextWrapper localContextWrapper = null;
374                        for (ContextWrapper contextWrapper : contextWrapperList) {
375                                if (contextWrapper.getAllCtx().getId().equals(oldContextWrapper.getAllCtx().getId())){
376                                        localComponentInstanceAvailable = true;
377                                        localContextWrapper = contextWrapper;
378                                        break;
379                                }
380                        }
381 
382                        if (localComponentInstanceAvailable || contextWrapperList.size() == 1){
383                                // only one component instance is called (either there is only one, or there is a local one). 
384                                if (localContextWrapper != null){
385                                        myContextWrapper = localContextWrapper;
386                                } else {
387                                        myContextWrapper = contextWrapperList.get(0);
388                                }
389                                AllocationContext toAllocationContext = myContextWrapper.getAllCtx();
390                                calledAllocationContextList.add(toAllocationContext);
391 
392                                // create LQN call
393                                createCallActivity(callId, seff, callType);
394 
395                        } else {
396                                // need to create a branch because several remote component instances are called
397                                // thus, iterate over all context wrappers and call the following SEFF for them. 
398 
399                                double branchProb = 1.0/contextWrapperList.size();
400 
401                                for (ContextWrapper contextWrapper : contextWrapperList) {
402                                        myContextWrapper = contextWrapper;
403 
404                                        AllocationContext toAllocationContext = myContextWrapper.getAllCtx();
405                                        calledAllocationContextList.add(toAllocationContext);
406                                        
407                                        // create LQN call
408                                        createCallActivity(callId, seff, callType, branchProb);
409 
410                                        // the ends of the branches are connected below after it has been decided whether to include network calls.
411                                }
412                                
413                        }
414 
415                        myContextWrapper = oldContextWrapper;
416                        
417                        String successorId = (String) doSwitch(successor);
418                        
419                        // Handle network calls. 
420                        // Just create a network call before the call created above that calls any network, 
421                        // and another one for the response afterwards. 
422                        // this is inaccurate, because the network of replica 1 may be called before replica 2 is called now,  
423                        // the proper dependency is lost.  
424                        // For the LQNS MVA analysis, it does not matter, though, because the mean values will stay the same
425                        
426                        for (AllocationContext targetAllocationContext : calledAllocationContextList) {
427                                
428                                // Add linking resource demand if this is a remote call.
429                                // careful: The linking resource processor is only generated if the latency is != 0. 
430                                if (callerAllocationContext.getResourceContainer_AllocationContext() != targetAllocationContext.getResourceContainer_AllocationContext()){
431                                        // call latency entry of linking resource before and after call.
432 
433                                        // get resource that connects the two
434                                        CommunicationLinkResourceSpecification link = oldContextWrapper.getConcreteLinkingResource(object, targetAllocationContext);
435 
436                                        // only create a call if latency is larger than 0
437                                        if (link != null && ExpressionHelper.getMeanValue(link.getLatency_CommunicationLinkResourceSpecification()) > 0){
438 
439                                                String linkId = Pcm2LqnHelper.getIdForCommResource(link.getLinkingResource_CommunicationLinkResourceSpecification(), link.getCommunicationLinkResourceType_CommunicationLinkResourceSpecification());
440                                                String latencyId = Pcm2LqnHelper.getIdForLatency(linkId, callType);
441 
442                                                String networkCallId = "LAN_"+callId+"_"+callType;
443                                                String networkResponseId = "LAN_"+callId+"_return";
444 
445                                                lqnBuilder.addActivityDef(networkCallId);
446                                                lqnBuilder.addActivityMakingCall(networkCallId, latencyId+"_Entry", callType);
447 
448                                                // only response if it is a synch call
449                                                if (callType == CallType.SYNCH){
450                                                        lqnBuilder.addActivityDef(networkResponseId);
451                                                        lqnBuilder.addActivityMakingCall(networkResponseId, latencyId+"_Entry", callType);
452                                                }
453 
454                                                // TODO: call throughput entry if bytesize characterization is available
455                                                // there is same very initial implementation at 
456                                                // contextWrapper.getDelayOnLinkingResource(eca, clrs);
457                                                // pay attention to use the right context wraper (old or new?)
458 
459                                                // first LAN call(s), then external call(s), then LAN call(s), then successor
460                                                // no response for asynchronous call
461                                                lqnBuilder.addSequencePrecedence(networkCallId, callId);
462                                                if (callType == CallType.SYNCH){
463                                                        lqnBuilder.addSequencePrecedence(callId, networkResponseId);
464                                                        lqnBuilder.addSequencePrecedence(networkResponseId, successorId);
465                                                } else {
466                                                        lqnBuilder.addSequencePrecedence(callId, successorId);
467                                                }
468 
469                                                return networkCallId;
470        
471 
472                                        } else {
473                                                if (link == null){
474                                                        logger.warn("No link found between "+callerAllocationContext.getEntityName()+" <"+callerAllocationContext.getId()+"> and "+targetAllocationContext.getEntityName()+" <"+targetAllocationContext.getId()+"> , ignoring this.");
475                                                }
476                                        }
477                                        // else go to return statement below and return the id of the external call itself.
478                                }
479                        }
480                        
481            //only come here if no linking resource calls have been created, e.g. because there is no latency defined.  
482                        lqnBuilder.addSequencePrecedence(callId, successorId);
483                        
484                        
485                        
486                        // all possible communication paths are thus the following
487                        // replication and LAN:     branch, LAN, external, LAN, branch, successor
488                        // no replication and LAN:          LAN, external, LAN,         successor
489            // no replication and local:             external,              successor
490                        //
491                        // The last combination, namely
492                        // replication and no LAN:  branch,      external,      branch, successor
493                        // is usually not used because two replicas cannot be on the same node, so branch is always combined with remote.
494                        // However, if a remote call has no latency specified, then this will be generated, ignoring the link. 
495                        // 
496                        
497                        return callId; // for predecessor
498                }
499        }
500        
501        private void createCallActivity(String callerId, ResourceDemandingSEFF sefftoBeCalled, CallType callType) {
502                createCallActivity(callerId, sefftoBeCalled, callType, 1.0);
503        }
504 
505        private void createCallActivity(String callerId, ResourceDemandingSEFF sefftoBeCalled, CallType callType, double callMeans) {
506                String entryId = "";
507                try {
508                        Rdseff2Lqn seffVisitor = new Rdseff2Lqn(lqnBuilder, myContextWrapper);
509                        entryId = (String)seffVisitor.doSwitch(sefftoBeCalled);
510                } catch (RuntimeException e) {
511                        logger.error("Error while visiting RDSEFF "+sefftoBeCalled.getId());
512                        e.printStackTrace();
513                        throw e;
514                }
515 
516                lqnBuilder.addActivityDef(callerId);
517                lqnBuilder.addActivityMakingCall(callerId, entryId, callType, callMeans);
518        }
519 
520        @Override
521        public String caseInternalAction(InternalAction object) {
522                String id = Pcm2LqnHelper.getId(object, myContextWrapper);
523                
524                EList<ParametricResourceDemand> resDemList = object.getResourceDemand_Action();
525                int counter = 0; // for the number of resource demands (mapped to entry name)
526                for (ParametricResourceDemand resourceDemand : resDemList){
527                        String processorId = getProcessorName(resourceDemand);
528 
529//                        // create a new task for the resource demand
530//                        ProcessorType pt = lqnBuilder.getProcessor(processorId);
531//                        TaskType tt = lqnBuilder.addTaskForResourceDemand(id+counter, pt);
532//                        EntryType et = lqnBuilder.addEntry(id+counter, tt);
533//                        et.setType(TypeType.PH1PH2);
534                        
535                        // first a new entry for the resource demand
536                        TaskType tt = lqnBuilder.getTaskForProcessor(processorId);
537                        EntryType et = lqnBuilder.addEntry(id+counter, tt);
538                        et.setType(TypeType.PH1PH2);
539 
540                        // the entry makes a call to the processor
541                        ActivityPhasesType apt = lqnBuilder.addActivityPhases(id+counter);
542                        Double demand = myContextWrapper.getMeanTimeConsumption(resourceDemand);
543                        String hostDemand = demand.toString();
544                        apt.setHostDemandMean(hostDemand);
545                        
546                        //if continuous function, get coefficient of variance
547                        //TODO: also get this for stepwise defined functions!
548                        //Check whether this has been a distribution originally 
549                        if (myContextWrapper.getIsOriginalPDFFor(resourceDemand)){
550                                ManagedPDF pdf = myContextWrapper.getTimeConsumptionAsPDF(resourceDemand);
551                                IProbabilityDensityFunction innerPDF = pdf.getPdfTimeDomain();
552                                if (innerPDF instanceof IContinousPDF){
553                                        IContinousPDF innerContPDF = (IContinousPDF)innerPDF; 
554                                        double coeffv = innerContPDF.getCoefficientOfVariance();
555                                        Double squaredcv = coeffv * coeffv;
556                                        apt.setHostDemandCvsq(squaredcv.toString());
557                                }
558                        }
559                        
560                        PhaseActivities pa = lqnBuilder.addPhaseActivities(apt);
561                        et.setEntryPhaseActivities(pa);
562                        
563                        // now another activity in the current task graph making the 
564                        // call to the entry created for the resource demand
565                        lqnBuilder.addActivityDef(id+counter);
566                        lqnBuilder.addActivityMakingCall(id+counter, et.getName(), CallType.SYNCH);
567                        if (counter<resDemList.size()-1){
568                                lqnBuilder.addSequencePrecedence(id+counter, id+(counter+1));        
569                        }
570                        
571                        counter++;
572                }
573                
574                String successorId = (String) doSwitch(object.getSuccessor_AbstractAction());
575                if ( resDemList.size() > 0){
576                        //Only add a sequence predecence if there actually was a resource demand in the list, i.e. if an activity etc. has been created
577                        lqnBuilder.addSequencePrecedence(id+(counter-1), successorId);
578                        return id+0; // for predecessor
579                } else {
580                        //If no resource demands were there, just let the predecessor connect itself to this action's successor (action disappears)
581                        return successorId;
582                }
583 
584 
585        }
586 
587        private String getProcessorName(ParametricResourceDemand resourceDemand) {
588                ProcessingResourceSpecification prs = myContextWrapper.getConcreteProcessingResource(resourceDemand);
589                if (prs == null){
590                        throw new RuntimeException("Could not find "+ProcessingResourceSpecification.class.getName()
591                                        +"of type "+resourceDemand.getRequiredResource_ParametricResourceDemand().getEntityName()+"(id:"+resourceDemand.getRequiredResource_ParametricResourceDemand().getId()+")"
592                                        +" adressed by resource demand of action "+resourceDemand.getAction_ParametricResourceDemand().getEntityName()+" ("+resourceDemand.getAction_ParametricResourceDemand().getId()+"). Check your model that the required resources are available on the server.");
593                }
594                ResourceContainer rc = (ResourceContainer)prs.eContainer();
595                ProcessingResourceType prt = prs.getActiveResourceType_ActiveResourceSpecification();
596                String name = Pcm2LqnHelper.getIdForProcResource(rc, prt); 
597                return name;
598        }
599 
600        @Override
601        public String caseStopAction(StopAction object) {
602                String id = Pcm2LqnHelper.getId(object, myContextWrapper);
603                lqnBuilder.addActivityDef(id);
604                // Precedence has already been created by predecessor
605                return id;
606        }
607        
608        private StartAction getStartAction(ResourceDemandingBehaviour behaviour) {
609                StartAction startAction = (StartAction) EMFQueryHelper.getObjectByType(
610                                behaviour.getSteps_Behaviour(), StartAction.class);
611                return startAction;
612        }
613 
614        
615        private StopAction getStopAction(ResourceDemandingBehaviour behaviour) {
616                StopAction stopAction = (StopAction) EMFQueryHelper.getObjectByType(
617                                behaviour.getSteps_Behaviour(), StopAction.class);
618                return stopAction;
619        }
620 
621        
622        public String caseForkActionOld(ForkAction object) {
623                // if this fork action is asynchronous and only contains an external call, 
624                // it can be modelled in LQN by just changing the call to send-no-reply
625                // TODO: for now only support one forked behaviour. TODO add several ones, 
626                // should be possible to map them to the same constructs, too.
627                if (object.getAsynchronousForkedBehaviours_ForkAction().size() == 1
628                                && (object.getSynchronisingBehaviours_ForkAction() == null 
629                                        || object.getSynchronisingBehaviours_ForkAction().getSynchronousForkedBehaviours_SynchronisationPoint().size() == 0)){
630                        ForkedBehaviour innerFork = object.getAsynchronousForkedBehaviours_ForkAction().get(0);
631                        // if there is only an external call, that means there are three steps (start, call, stop) and one is an external call
632                        if (innerFork.getSteps_Behaviour().size() == 3){
633                                // find the external call action, the other two have to be start and stop in a valid model
634                                ExternalCallAction eca = null;
635                                for (AbstractAction action : innerFork.getSteps_Behaviour()) {
636                                        if (action instanceof ExternalCallAction){
637                                                eca = (ExternalCallAction)action;
638                                                break;
639                                        }
640                                }
641                                if (eca != null){
642                                        // we have the preconditions for using an LQN send-no-response call
643                                        return handleExternalCallAction(eca, CallType.ASYNCH, object.getSuccessor_AbstractAction());
644                                }
645                                // else return super.caseFork (i.e. go to end of method)
646                        }
647                                
648                } 
649                logger.warn("No arbitrary Fork action supported yet, only asnychronous Forks containing a single ExternalCall are supported.");
650                
651                return super.caseForkAction(object);
652                
653        }
654        
655        @Override
656        public String caseForkAction(ForkAction object){
657                String id = Pcm2LqnHelper.getId(object, myContextWrapper);
658                ActivityDefType adt = lqnBuilder.addActivityDef(id);
659 
660                String currentId = id;
661                String predecessorId = id;
662 
663                EList<ForkedBehaviour> asyncBehList = object.getAsynchronousForkedBehaviours_ForkAction();
664                for (ForkedBehaviour asyncBeh : asyncBehList){
665                        currentId = Pcm2LqnHelper.getIdForForkedBehaviour(asyncBeh, myContextWrapper);
666                        
667                        // create new task graph for the forked behaviour
668                        ProcessorType pt = lqnBuilder.addProcessor(currentId);
669                        TaskType tt = lqnBuilder.addTask(currentId,pt);
670                        EntryType et = lqnBuilder.addEntry(currentId,tt);
671                        lqnBuilder.addTaskActivityGraph(tt);
672 
673                        // create the actions of the new task graph by traversing the forked behavior's steps
674                        doSwitch(getStartAction(asyncBeh));
675                        
676                        lqnBuilder.restoreFormerTaskActivityGraph();
677                        
678                        // create an asynchronous external call to the task representing the forked behaviour
679                        lqnBuilder.addActivityDef(currentId+"_Action");
680                        lqnBuilder.addActivityMakingCall(currentId+"_Action", currentId+"_Entry", CallType.ASYNCH);
681                        
682                        lqnBuilder.addSequencePrecedence(predecessorId, currentId+"_Action");
683                        predecessorId = currentId+"_Action";
684                        
685                }
686                
687                if (object.getSynchronisingBehaviours_ForkAction() != null
688                        && object.getSynchronisingBehaviours_ForkAction().getSynchronousForkedBehaviours_SynchronisationPoint().size() > 0) {
689                        EList<ForkedBehaviour> syncBehList = object.getSynchronisingBehaviours_ForkAction().getSynchronousForkedBehaviours_SynchronisationPoint();
690                
691                        PrecedenceType ptBegin = lqnBuilder.addBeginForkPrecedence(currentId+"_Action");
692                        PrecedenceType ptEnd = lqnBuilder.addEndForkPrecedence();                
693 
694                        for (ForkedBehaviour syncBeh : syncBehList){
695                                
696                                String startId = doSwitch(getStartAction(syncBeh));
697                                lqnBuilder.addActivityToPostAnd(startId, ptBegin);
698                                
699                                String stopId = Pcm2LqnHelper.getId(getStopAction(syncBeh), myContextWrapper);
700                                lqnBuilder.addActivityToPreAnd(stopId, ptEnd);
701                                
702                        }
703                        String successorId = (String) doSwitch(object.getSuccessor_AbstractAction());
704                        ptEnd.getPost().getActivity().setName(successorId);
705                } else {
706                        String successorId = (String) doSwitch(object.getSuccessor_AbstractAction());
707                        lqnBuilder.addSequencePrecedence(currentId + "_Action", successorId);
708                }
709                
710                return id;
711        }
712        
713        
714}

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