source: trunk/autoquest-plugin-uml/src/main/java/de/ugoe/cs/autoquest/plugin/uml/UMLUtils.java @ 1835

Last change on this file since 1835 was 1835, checked in by sherbold, 10 years ago
  • updated UMLUtils and UMLUtilsTest to work with a first version of the MIDAS logistics pilot. This also required changes in the service name maps. They now must point to the component for a service, not the interface.
  • Property svn:mime-type set to text/plain
File size: 28.4 KB
RevLine 
[1604]1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.plugin.uml;
16
17import java.util.Collection;
[1763]18import java.util.Collections;
19import java.util.Comparator;
[1604]20import java.util.HashMap;
21import java.util.Iterator;
[1763]22import java.util.LinkedHashMap;
[1604]23import java.util.LinkedList;
24import java.util.List;
25import java.util.Map;
26import java.util.Map.Entry;
27
28import org.eclipse.emf.common.util.EList;
[1763]29import org.eclipse.uml2.uml.Activity;
30import org.eclipse.uml2.uml.ActivityEdge;
31import org.eclipse.uml2.uml.ActivityNode;
32import org.eclipse.uml2.uml.CallOperationAction;
[1604]33import org.eclipse.uml2.uml.Comment;
[1752]34import org.eclipse.uml2.uml.Component;
35import org.eclipse.uml2.uml.Connector;
36import org.eclipse.uml2.uml.ConnectorEnd;
[1835]37import org.eclipse.uml2.uml.Element;
[1624]38import org.eclipse.uml2.uml.Interaction;
[1643]39import org.eclipse.uml2.uml.InteractionFragment;
[1752]40import org.eclipse.uml2.uml.Interface;
[1624]41import org.eclipse.uml2.uml.Lifeline;
42import org.eclipse.uml2.uml.Message;
43import org.eclipse.uml2.uml.MessageOccurrenceSpecification;
[1752]44import org.eclipse.uml2.uml.MessageSort;
[1624]45import org.eclipse.uml2.uml.Model;
46import org.eclipse.uml2.uml.Operation;
[1752]47import org.eclipse.uml2.uml.Port;
[1759]48import org.eclipse.uml2.uml.Profile;
[1761]49import org.eclipse.uml2.uml.Property;
[1604]50import org.eclipse.uml2.uml.Region;
51import org.eclipse.uml2.uml.StateMachine;
[1759]52import org.eclipse.uml2.uml.Stereotype;
[1604]53import org.eclipse.uml2.uml.Transition;
[1624]54import org.eclipse.uml2.uml.UMLPackage;
[1604]55import org.eclipse.uml2.uml.Vertex;
56
57import de.ugoe.cs.autoquest.eventcore.Event;
58import de.ugoe.cs.autoquest.plugin.http.eventcore.SOAPEventType;
[1643]59import de.ugoe.cs.autoquest.plugin.http.eventcore.SimpleSOAPEventType;
[1604]60import de.ugoe.cs.autoquest.plugin.uml.eventcore.UMLTransitionType;
[1763]61import de.ugoe.cs.autoquest.usageprofiles.IStochasticProcess;
[1604]62
63/**
64 * <p>
[1624]65 * Utilities for working with UML.
[1604]66 * </p>
67 *
68 * @author Steffen Herbold
69 */
70public class UMLUtils {
71
[1624]72    /**
73     * <p>
74     * Creates a sequence of events with {@link UMLTransitionType} as event type from a given
75     * sequence of events with the {@link SOAPEventType}, by matching the sequences to a state
76     * machine.
77     * </p>
78     *
79     * @param sequence
80     *            SOAP sequences
81     * @param stateMachine
82     *            the state machine
83     * @return create UML sequences
84     */
85    public static List<Event> createUMLTransitionSequence(List<Event> sequence,
86                                                          StateMachine stateMachine)
87    {
88        List<List<Transition>> matchingSequences =
89            determineMatchingTransitionSequences(sequence, stateMachine);
[1604]90
91        if (matchingSequences.size() != 1) {
92            throw new RuntimeException("no unique match found; " + matchingSequences.size() +
93                " matches");
94        }
95        List<Event> umlEventSequence = new LinkedList<>();
96        for (Transition transition : matchingSequences.get(0)) {
97            umlEventSequence.add(new Event(new UMLTransitionType(transition)));
98        }
99        return umlEventSequence;
100    }
[1624]101
102    /**
103     * <p>
104     * Uses a sequences of events with the {@link UMLTransitionType} to determine the transition
105     * probabilities for the state machine.
106     * </p>
107     *
108     * @param sequences
109     *            UML sequences
110     * @param stateMachine
111     *            state machine to be converted to a usage profile
112     */
113    public static void convertStateMachineToUsageProfile(Collection<List<Event>> sequences,
114                                                         StateMachine stateMachine)
115    {
[1604]116        // create state->outgoings hashmap
[1624]117        Map<Vertex, Map<Transition, Integer>> stateMap = new HashMap<>();
118        for (Region region : stateMachine.getRegions()) {
119            for (Vertex state : region.getSubvertices()) {
120                stateMap.put(state, new HashMap<Transition, Integer>());
[1604]121            }
122        }
[1624]123
[1604]124        // create counters for each transition
[1624]125        for (List<Event> sequence : sequences) {
126            for (Event event : sequence) {
127                if (event.getType() instanceof UMLTransitionType) {
[1604]128                    Transition transition = ((UMLTransitionType) event.getType()).getTransition();
[1624]129                    Map<Transition, Integer> transitionMap = stateMap.get(transition.getSource());
[1604]130                    Integer value = transitionMap.get(transition);
[1624]131                    if (value == null) {
[1604]132                        value = 0;
133                    }
[1624]134                    transitionMap.put(transition, value + 1);
[1604]135                }
[1624]136                else {
137                    throw new RuntimeException(
138                                               "Wrong event type. Only UMLTransitionType supported but was: " +
139                                                   event.getType().getClass().getName());
140                }
[1604]141            }
142        }
143
144        // calculate probabilities
[1624]145        for (Region region : stateMachine.getRegions()) {
146            for (Vertex state : region.getSubvertices()) {
147                Map<Transition, Integer> transitionMap = stateMap.get(state);
[1604]148                int totalCount = 0;
[1624]149                for (Entry<Transition, Integer> entry : transitionMap.entrySet()) {
[1604]150                    totalCount += entry.getValue();
151                }
[1624]152                if (totalCount != 0) {
153                    for (Transition transition : state.getOutgoings()) {
[1604]154                        double prob = 0.0d;
[1624]155                        if (transitionMap.containsKey(transition)) {
156                            prob = ((double) transitionMap.get(transition)) / totalCount;
[1604]157                        }
158                        Comment comment = transition.createOwnedComment();
[1624]159                        comment.setBody("" + prob);
[1604]160                    }
[1624]161                }
162                else {
[1604]163                    // system has never been in this state, all transitions equally likely
164                    int numOutgoings = state.getOutgoings().size();
[1624]165                    for (Transition transition : state.getOutgoings()) {
[1604]166                        Comment comment = transition.createOwnedComment();
[1624]167                        comment.setBody("" + (1.0d / numOutgoings));
[1604]168                    }
169                }
170            }
171        }
172    }
[1624]173
174    /**
175     * <p>
176     * Determines all matching {@link Transition} sequences in a state machine for a given sequence
177     * of SOAP events.
178     * </p>
179     *
180     * @param sequence
181     *            SOAP sequence
182     * @param stateMachine
183     *            the state machine
184     * @return all matching {@link Transition} sequences
185     */
186    public static List<List<Transition>> determineMatchingTransitionSequences(List<Event> sequence,
187                                                                              StateMachine stateMachine)
188    {
[1604]189        EList<Region> regions = stateMachine.getRegions();
190        EList<Vertex> states = null;
191        for (Region region : regions) {
192            if (states == null) {
193                states = region.getSubvertices();
194            }
195            else {
196                states.addAll(region.getSubvertices());
197            }
198        }
199        List<Transition> allTransitions = new LinkedList<>();
200        for (Vertex state : states) {
201            allTransitions.addAll(state.getOutgoings());
202        }
203
204        List<List<Transition>> matchingSequences = null;
205        List<Transition> currentTransitions = null;
206
207        // first, we try to find a single unique transition that we can match using the method name
208        for (Iterator<Event> eventIterator = sequence.iterator(); eventIterator.hasNext();) {
209            Event event = eventIterator.next();
210            if (event.getType() instanceof SOAPEventType) {
211                SOAPEventType eventType = (SOAPEventType) event.getType();
212                if (matchingSequences == null) {
213                    matchingSequences = new LinkedList<>();
214                    List<Transition> initialMatches = matchTransitions(allTransitions, eventType);
215                    for (Transition transition : initialMatches) {
216                        List<Transition> candidate = new LinkedList<>();
217                        candidate.add(transition);
218                        matchingSequences.add(candidate);
219                    }
220                    currentTransitions = initialMatches;
221                }
222                else {
223                    List<List<Transition>> nextMatchingSequences = new LinkedList<>();
224                    List<Transition> nextCurrentTransitions = new LinkedList<>();
225                    Iterator<Transition> currentTransitionIterator = currentTransitions.iterator();
226                    Iterator<List<Transition>> currentMatchingSequencesIterator =
227                        matchingSequences.iterator();
228                    while (currentTransitionIterator.hasNext()) {
229                        Transition currentTransition = currentTransitionIterator.next();
230                        List<Transition> currentMatch = currentMatchingSequencesIterator.next();
231
232                        List<Transition> matches =
233                            matchTransitions(currentTransition.getTarget().getOutgoings(),
234                                             eventType);
235                        if (matches.isEmpty()) {
236                            throw new RuntimeException("no matches found");
237                        }
238                        for (Transition matchingTransition : matches) {
239                            List<Transition> candidate = new LinkedList<>(currentMatch);
240                            candidate.add(matchingTransition);
241                            nextMatchingSequences.add(candidate);
242                            nextCurrentTransitions.add(matchingTransition);
243                        }
244                    }
245                    matchingSequences = nextMatchingSequences;
246                    currentTransitions = nextCurrentTransitions;
247                }
248            }
249            else {
[1624]250                throw new RuntimeException(
251                                           "Wrong event type. Only UMLTransitionType supported but was: " +
252                                               event.getType().getClass().getName());
[1604]253            }
254        }
255        return matchingSequences;
256    }
[1624]257
258    /**
259     * <p>
[1633]260     * Extends a given model with an interaction that represents an observed sequence.
[1624]261     * </p>
[1633]262     *
263     * @param sequence
264     *            sequence that is added as sequence diagram
265     * @param model
266     *            UML model to which the interaction is added
267     * @param interactionName
268     *            name of the interaction
[1624]269     */
[1633]270    public static void createInteractionFromEventSequence(List<Event> sequence,
271                                                          Model model,
272                                                          String interactionName)
[1604]273    {
[1624]274
[1835]275        Component testContext = fetchTestContext(model);
[1759]276
277        final Profile utpProfile = model.getAppliedProfile("utp");
278        final Stereotype utpTestCase = (Stereotype) utpProfile.getOwnedMember("TestCase");
[1763]279        final Stereotype utpTestComponent = (Stereotype) utpProfile.getOwnedMember("TestComponent");
280        final Stereotype utpSUT = (Stereotype) utpProfile.getOwnedMember("SUT");
281       
[1759]282        Operation operation = testContext.createOwnedOperation(interactionName, null, null);
283        operation.applyStereotype(utpTestCase);
284
[1624]285        Interaction interaction =
[1759]286            (Interaction) testContext.createPackagedElement(interactionName + "_Impl",
287                                                            UMLPackage.Literals.INTERACTION);
[1761]288        operation.getMethods().add(interaction);
[1835]289
[1763]290        // create lifelines
291        Lifeline userLifeline = null;
[1835]292        // List<Port> userPorts = new LinkedList<>();
[1763]293        for (Property property : testContext.getAllAttributes()) {
294            if (property.getAppliedStereotypes().contains(utpSUT)) {
[1835]295                String serviceName = property.getName();
[1763]296                Lifeline targetLifeline = interaction.createLifeline(serviceName);
297                targetLifeline.setRepresents(property);
[1761]298            }
[1763]299            else if (property.getType().getAppliedStereotypes().contains(utpTestComponent)) {
300                userLifeline = interaction.createLifeline(property.getName());
301                userLifeline.setRepresents(property);
[1835]302            }   
[1761]303        }
[1835]304       
305        // TODO sanity checks for userLifeline!=null, etc.
[1753]306
[1624]307        int i = 0;
308        for (Event event : sequence) {
[1633]309            if (!(event.equals(Event.STARTEVENT) || event.equals(Event.ENDEVENT))) {
[1643]310                String serviceName = getServiceNameFromEvent(event);
311                String methodName = getCalledMethodFromEvent(event);
[1835]312               
313                // determine lifelines
314                Lifeline msgTargetLifeline;
315                Lifeline msgSourceLifeline;
316               
317                if( serviceName.equals(userLifeline.getName()) ) {
318                    // message being send to user
319                    // currently we just select the first lifeline that is not the user
320                    // this, obviously, has to be replaced with the real service.
321                    // however, identification of the source of a message is still an open issue
322                    msgSourceLifeline = null;
323                    for( Lifeline lifeline : interaction.getLifelines() ) {
324                        if(!lifeline.equals(userLifeline)){
325                            msgSourceLifeline = lifeline;
326                            break;
327                        }
328                    }
329                    msgTargetLifeline = userLifeline;
330                } else {
331                    msgSourceLifeline = userLifeline;
332                    msgTargetLifeline = interaction.getLifeline(serviceName);
333                }
[1624]334
[1835]335                // determine target interface
336                Interface targetInterface = getRealizedInterfaceFromProperty((Property) msgTargetLifeline.getRepresents());
337               
338                // create message
[1643]339                MessageOccurrenceSpecification sendFragment =
340                    (MessageOccurrenceSpecification) interaction
341                        .createFragment(i + ":" + methodName + "_sendFragment",
342                                        UMLPackage.Literals.MESSAGE_OCCURRENCE_SPECIFICATION);
343                MessageOccurrenceSpecification recvFragment =
344                    (MessageOccurrenceSpecification) interaction
345                        .createFragment(i + ":" + methodName + "_recvFragment",
346                                        UMLPackage.Literals.MESSAGE_OCCURRENCE_SPECIFICATION);
[1624]347
[1835]348                sendFragment.setCovered(msgSourceLifeline);
349                recvFragment.setCovered(msgTargetLifeline);
[1624]350
[1643]351                Message message = interaction.createMessage(methodName);
[1753]352                if (getOperationFromName(targetInterface.getOperations(), methodName) == null) {
[1835]353                    System.out.println("operation not found in the " + targetInterface.getName() + " interface: " + methodName);
[1752]354                }
[1753]355                message.setSignature(getOperationFromName(targetInterface.getOperations(),
356                                                          methodName));
[1752]357                message.setMessageSort(MessageSort.ASYNCH_CALL_LITERAL);
[1643]358                message.setSendEvent(sendFragment);
359                message.setReceiveEvent(recvFragment);
[1763]360
[1835]361                // now the connector needs to be determined
362                EList<Property> userAttributes = ((Component) msgSourceLifeline.getRepresents().getType()).getAttributes();
363                EList<Property> targetAttributes = ((Component) msgTargetLifeline.getRepresents().getType()).getAttributes();
364               
365                for( Property userAttribute : userAttributes ) {
366                    if( userAttribute instanceof Port ) {
367                        EList<ConnectorEnd> userEnds = ((Port) userAttribute).getEnds();
368                        for( ConnectorEnd userEnd : userEnds ) {
369                            Connector userConnector = (Connector) userEnd.eContainer();
370                            for( Property targetAttribute : targetAttributes ) {
371                                if( targetAttribute instanceof Port ) {
372                                    EList<ConnectorEnd> targetEnds = ((Port) targetAttribute).getEnds();
373                                    for( ConnectorEnd targetEnd : targetEnds ) {
374                                        Connector targetConnector = (Connector) targetEnd.eContainer();
375                                        if( targetConnector==userConnector ) {
376                                            message.setConnector(targetConnector);
377                                        }
378                                    }
379                                }
[1761]380                            }
[1752]381                        }
382                    }
[1753]383                }
[1835]384               
[1643]385                sendFragment.setMessage(message);
386                recvFragment.setMessage(message);
387
[1633]388                i++;
[1624]389            }
390        }
391    }
392
393    /**
394     * <p>
[1643]395     * Calculates the usage score of an interaction as the logsum of the event probabilities
396     * multiplied with the length of the interaction.
397     * </p>
398     *
399     * @param interaction
400     *            interaction for which the score is calculated
401     * @param usageProfile
402     *            usage profile used for the calculation
403     * @return calculated usage score
404     */
[1763]405    public static double calculateUsageScore(Interaction interaction,
406                                             IStochasticProcess usageProfile)
407    {
[1643]408        double usageScore = 0.0d;
409
410        EList<InteractionFragment> interactionFragments = interaction.getFragments();
411        List<Event> eventSequence = new LinkedList<>();
412        eventSequence.add(Event.STARTEVENT);
413        for (InteractionFragment interactionFragment : interactionFragments) {
414            if (interactionFragment.getName() != null &&
415                interactionFragment.getName().endsWith("_recvFragment"))
416            {
417                String serviceName =
[1763]418                    interactionFragment.getCovereds().get(0).getRepresents().getName().split("_")[0];
[1643]419                String methodName = "UNKNOWN";
420                if (interactionFragment instanceof MessageOccurrenceSpecification) {
421                    methodName =
422                        ((MessageOccurrenceSpecification) interactionFragment).getMessage()
423                            .getName();
424                }
425                eventSequence.add(new Event(new SimpleSOAPEventType(methodName, serviceName)));
426            }
427        }
[1763]428        eventSequence.add(Event.ENDEVENT);
[1643]429        double prob = usageProfile.getLogSum(eventSequence);
[1763]430        usageScore = eventSequence.size() * prob;
[1643]431
432        return usageScore;
433    }
434
435    /**
436     * <p>
[1763]437     * Extends the given model with an activity for usage-based scheduling of the test cases.
438     * </p>
439     *
440     * @param model
441     *            model to be extended
442     * @param usageProfile
443     *            usage profile used as foundation
444     */
445    public static void createScheduling(Model model, IStochasticProcess usageProfile) {
446
447        final Profile utpProfile = model.getAppliedProfile("utp");
448        final Stereotype utpTestCase = (Stereotype) utpProfile.getOwnedMember("TestCase");
449
[1835]450        Component testContext = fetchTestContext(model);
[1763]451
452        Map<Operation, Double> usageScoreMapUnsorted = new HashMap<>();
453
454        // first, we determine all test cases and calculate their usage scores
455        for (Operation operation : testContext.getAllOperations()) {
456            if (operation.getAppliedStereotypes().contains(utpTestCase)) {
457                Interaction interaction = (Interaction) operation.getMethods().get(0);
458                usageScoreMapUnsorted
459                    .put(operation, calculateUsageScore(interaction, usageProfile));
460            }
461        }
462        Map<Operation, Double> usageScoreMapSorted = sortByValue(usageScoreMapUnsorted);
463
464        // now we create the scheduling
465        Activity schedulingActivity =
466            (Activity) testContext.createOwnedBehavior("UsageBasedScheduling",
467                                                       UMLPackage.Literals.ACTIVITY);
468        testContext.setClassifierBehavior(schedulingActivity);
469
470        ActivityNode startNode =
471            schedulingActivity.createOwnedNode("final", UMLPackage.Literals.INITIAL_NODE);
472        ActivityNode finalNode =
473            schedulingActivity.createOwnedNode("final", UMLPackage.Literals.ACTIVITY_FINAL_NODE);
474
475        ActivityNode currentOperationNode = startNode;
476
477        for (Entry<Operation, Double> entry : usageScoreMapSorted.entrySet()) {
478            Operation operation = entry.getKey();
479            CallOperationAction nextOperationNode =
480                (CallOperationAction) schedulingActivity
481                    .createOwnedNode(operation.getName(), UMLPackage.Literals.CALL_OPERATION_ACTION);
482            nextOperationNode.setOperation(operation);
483
484            ActivityEdge edge =
485                schedulingActivity.createEdge(currentOperationNode.getName() + "_to_" +
486                    nextOperationNode.getName(), UMLPackage.Literals.CONTROL_FLOW);
487            edge.setSource(currentOperationNode);
488            edge.setTarget(nextOperationNode);
489
490            currentOperationNode = nextOperationNode;
491        }
492
493        ActivityEdge edge =
494            schedulingActivity
495                .createEdge(currentOperationNode.getName() + "_to_" + finalNode.getName(),
496                            UMLPackage.Literals.CONTROL_FLOW);
497        edge.setSource(currentOperationNode);
498        edge.setTarget(finalNode);
499    }
500
501    /**
502     * From
503     * http://stackoverflow.com/questions/109383/how-to-sort-a-mapkey-value-on-the-values-in-java
504     * and adapted to do an inverse sorting
505     */
506    public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
507        List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet());
508        Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
509            @Override
510            public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
511                return -1 * (o1.getValue()).compareTo(o2.getValue());
512            }
513        });
514
515        Map<K, V> result = new LinkedHashMap<>();
516        for (Map.Entry<K, V> entry : list) {
517            result.put(entry.getKey(), entry.getValue());
518        }
519        return result;
520    }
521
522    /**
523     * <p>
[1643]524     * Helper function to get the name of a service from a SOAP event.
525     * </p>
526     *
527     * @param event
528     *            event for which the service name is retrieved
529     * @return service name
530     */
[1835]531    protected static String getServiceNameFromEvent(Event event) {
[1643]532        if (event.getType() instanceof SOAPEventType) {
533            return ((SOAPEventType) event.getType()).getServiceName();
534        }
535        else if (event.getType() instanceof SimpleSOAPEventType) {
536            return ((SimpleSOAPEventType) event.getType()).getServiceName();
537        }
538        else {
539            throw new RuntimeException(
540                                       "Wrong event type. Only SOAPEventType and SimpleSOAPEventType supported but was: " +
541                                           event.getType().getClass().getName());
542        }
543    }
544
545    /**
546     *
547     * <p>
548     * Helper function to get the called method from a SOAP event
549     * </p>
550     *
551     * @param event
552     *            event for which the called method is retrieved
553     * @return called method
554     */
555    private static String getCalledMethodFromEvent(Event event) {
556        if (event.getType() instanceof SOAPEventType) {
557            return ((SOAPEventType) event.getType()).getCalledMethod();
558        }
559        else if (event.getType() instanceof SimpleSOAPEventType) {
560            return ((SimpleSOAPEventType) event.getType()).getCalledMethod();
561        }
562        else {
563            throw new RuntimeException(
564                                       "Wrong event type. Only SOAPEventType and SimpleSOAPEventType supported but was: " +
565                                           event.getType().getClass().getName());
566        }
567    }
568
569    /**
570     * <p>
[1624]571     * Fetches an operation using only its name from a list of operations. Returns the first match
572     * found or null if no match is found.
573     * </p>
574     *
575     * @param operations
576     *            list of operations
577     * @param name
578     *            name of the operation
579     * @return first matching operation; null if no match is found
580     */
581    private static Operation getOperationFromName(EList<Operation> operations, String name) {
582        if (name == null) {
583            throw new IllegalArgumentException("name of the operation must not be null");
584        }
585        if (operations != null) {
586            for (Operation operation : operations) {
587                if (operation.getName() != null && operation.getName().equals(name)) {
588                    return operation;
589                }
590            }
591        }
592        return null;
593    }
594
595    /**
596     * <p>
597     * Determines which transitions match a given {@link SOAPEventType}.
598     * </p>
599     *
600     * @param transitions
601     *            the transitions
602     * @param eventType
603     *            the SOAP event
604     * @return matching transitions
605     */
606    private static List<Transition> matchTransitions(List<Transition> transitions,
607                                                     SOAPEventType eventType)
608    {
[1604]609        List<Transition> matching = new LinkedList<>();
610        for (Transition transition : transitions) {
611            // String serviceName = transition.getName().split("\\.")[0]; // TODO service name check
612            String methodName = transition.getName().split("\\.")[1];
613            if (methodName.equals(eventType.getCalledMethod())) {
614                matching.add(transition);
615            }
616        }
617        return matching;
618    }
[1763]619   
620    private static Interface getRealizedInterfaceFromProperty(Property property) {
621        return getRealizedInterfaceFromComponent((Component) property.getType());
622    }
623   
624    private static Interface getRealizedInterfaceFromComponent(Component comp) {
[1835]625        Interface myInterface = null;
626        for( Property property : comp.getAttributes() ) {
627            if( property instanceof Port ) {
628                Port port = (Port) property;
629                if( !port.isConjugated() ) {
630                    if( myInterface==null ) {
631                        myInterface = port.getProvideds().get(0);
632                    }
633                    else if( myInterface!=port.getProvideds().get(0)) {
634                        System.err.println("multiple different interfaces found");
635                    }
636                }
637            }
638        }
639        return myInterface;
640        //return ((Port) comp.getAttributes().get(0)).getInterface();
641        //Realization realization = (Realization) comp.getNestedClassifiers().get(0).getRelationships(UMLPackage.Literals.REALIZATION).get(0);
642        //return (Interface) realization.getSuppliers().get(0);
[1763]643    }
[1835]644   
645    private static Component fetchTestContext(Model model) {
646        final Profile utpProfile = model.getAppliedProfile("utp");
647        final Stereotype utpTestContext = (Stereotype) utpProfile.getOwnedMember("TestContext");
648       
649        for( Element element : model.getOwnedElements() ) {
650            if( element instanceof Component && element.getApplicableStereotypes().contains(utpTestContext) ) {
651                return (Component) element;
652            }
653        }
654        return null;
655    }
[1604]656}
Note: See TracBrowser for help on using the repository browser.