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

Last change on this file since 1604 was 1604, checked in by sherbold, 10 years ago
  • sharing autoquest-plugin-uml code
  • Property svn:mime-type set to text/plain
File size: 8.8 KB
Line 
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;
18import java.util.HashMap;
19import java.util.Iterator;
20import java.util.LinkedList;
21import java.util.List;
22import java.util.Map;
23import java.util.Map.Entry;
24
25import org.eclipse.emf.common.util.EList;
26import org.eclipse.uml2.uml.Comment;
27import org.eclipse.uml2.uml.Region;
28import org.eclipse.uml2.uml.StateMachine;
29import org.eclipse.uml2.uml.Transition;
30import org.eclipse.uml2.uml.Vertex;
31
32import de.ugoe.cs.autoquest.eventcore.Event;
33import de.ugoe.cs.autoquest.plugin.http.eventcore.SOAPEventType;
34import de.ugoe.cs.autoquest.plugin.uml.eventcore.UMLTransitionType;
35
36/**
37 * <p>
38 * TODO comment
39 * </p>
40 *
41 * @author Steffen Herbold
42 */
43public class UMLUtils {
44
45    public static List<Event> createUMLTransitionSequence(List<Event> sequence, StateMachine stateMachine) {
46        List<List<Transition>> matchingSequences = determineMatchingTransitionSequences(sequence, stateMachine);
47
48        if (matchingSequences.size() != 1) {
49            throw new RuntimeException("no unique match found; " + matchingSequences.size() +
50                " matches");
51        }
52        List<Event> umlEventSequence = new LinkedList<>();
53        for (Transition transition : matchingSequences.get(0)) {
54            umlEventSequence.add(new Event(new UMLTransitionType(transition)));
55        }
56        return umlEventSequence;
57    }
58   
59    public static void convertStateMachineToUsageProfile(Collection<List<Event>> sequences, StateMachine stateMachine) {
60        // create state->outgoings hashmap
61        Map<Vertex, Map<Transition,Integer>> stateMap = new HashMap<>();
62        for( Region region : stateMachine.getRegions() ) {
63            for( Vertex state : region.getSubvertices() ) {
64                stateMap.put(state, new HashMap<Transition,Integer>());
65            }
66        }
67       
68        // create counters for each transition
69        for( List<Event> sequence : sequences) {
70            for( Event event : sequence ) {
71                if( event.getType() instanceof UMLTransitionType ) {
72                    Transition transition = ((UMLTransitionType) event.getType()).getTransition();
73                    Map<Transition,Integer> transitionMap = stateMap.get(transition.getSource());
74                    Integer value = transitionMap.get(transition);
75                    if( value==null ) {
76                        value = 0;
77                    }
78                    transitionMap.put(transition, value+1);
79                } else {
80                    throw new RuntimeException("Wrong event type. Only UMLTransitionType supported but was: " +
81                            event.getType().getClass().getName());
82                }
83            }
84        }
85
86        // calculate probabilities
87        for( Region region : stateMachine.getRegions() ) {
88            for( Vertex state : region.getSubvertices() ) {
89                Map<Transition,Integer> transitionMap = stateMap.get(state);
90                int totalCount = 0;
91                for( Entry<Transition,Integer> entry : transitionMap.entrySet() ) {
92                    totalCount += entry.getValue();
93                }
94                if( totalCount!=0 ) {
95                    for( Transition transition : state.getOutgoings() ) {
96                        double prob = 0.0d;
97                        if( transitionMap.containsKey(transition)) {
98                            prob = ((double) transitionMap.get(transition))/totalCount;
99                        }
100                        Comment comment = transition.createOwnedComment();
101                        comment.setBody("" + prob );
102                    }
103                } else {
104                    // system has never been in this state, all transitions equally likely
105                    int numOutgoings = state.getOutgoings().size();
106                    for( Transition transition : state.getOutgoings() ) {
107                        Comment comment = transition.createOwnedComment();
108                        comment.setBody("" + (1.0d/numOutgoings) );
109                    }
110                }
111            }
112        }
113    }
114   
115    public static List<List<Transition>> determineMatchingTransitionSequences(List<Event> sequence, StateMachine stateMachine) {
116        EList<Region> regions = stateMachine.getRegions();
117        EList<Vertex> states = null;
118        for (Region region : regions) {
119            if (states == null) {
120                states = region.getSubvertices();
121            }
122            else {
123                states.addAll(region.getSubvertices());
124            }
125        }
126        List<Transition> allTransitions = new LinkedList<>();
127        for (Vertex state : states) {
128            allTransitions.addAll(state.getOutgoings());
129        }
130
131        List<List<Transition>> matchingSequences = null;
132        List<Transition> currentTransitions = null;
133
134        // first, we try to find a single unique transition that we can match using the method name
135        for (Iterator<Event> eventIterator = sequence.iterator(); eventIterator.hasNext();) {
136            Event event = eventIterator.next();
137            if (event.getType() instanceof SOAPEventType) {
138                SOAPEventType eventType = (SOAPEventType) event.getType();
139                if (matchingSequences == null) {
140                    matchingSequences = new LinkedList<>();
141                    List<Transition> initialMatches = matchTransitions(allTransitions, eventType);
142                    for (Transition transition : initialMatches) {
143                        List<Transition> candidate = new LinkedList<>();
144                        candidate.add(transition);
145                        matchingSequences.add(candidate);
146                    }
147                    currentTransitions = initialMatches;
148                }
149                else {
150                    List<List<Transition>> nextMatchingSequences = new LinkedList<>();
151                    List<Transition> nextCurrentTransitions = new LinkedList<>();
152                    Iterator<Transition> currentTransitionIterator = currentTransitions.iterator();
153                    Iterator<List<Transition>> currentMatchingSequencesIterator =
154                        matchingSequences.iterator();
155                    while (currentTransitionIterator.hasNext()) {
156                        Transition currentTransition = currentTransitionIterator.next();
157                        List<Transition> currentMatch = currentMatchingSequencesIterator.next();
158
159                        List<Transition> matches =
160                            matchTransitions(currentTransition.getTarget().getOutgoings(),
161                                             eventType);
162                        if (matches.isEmpty()) {
163                            throw new RuntimeException("no matches found");
164                        }
165                        for (Transition matchingTransition : matches) {
166                            List<Transition> candidate = new LinkedList<>(currentMatch);
167                            candidate.add(matchingTransition);
168                            nextMatchingSequences.add(candidate);
169                            nextCurrentTransitions.add(matchingTransition);
170                        }
171                    }
172                    matchingSequences = nextMatchingSequences;
173                    currentTransitions = nextCurrentTransitions;
174                }
175            }
176            else {
177                throw new RuntimeException("Wrong event type. Only UMLTransitionType supported but was: " +
178                    event.getType().getClass().getName());
179            }
180        }
181        return matchingSequences;
182    }
183   
184    private static List<Transition> matchTransitions(List<Transition> transitions, SOAPEventType eventType)
185    {
186        List<Transition> matching = new LinkedList<>();
187        for (Transition transition : transitions) {
188            // String serviceName = transition.getName().split("\\.")[0]; // TODO service name check
189            String methodName = transition.getName().split("\\.")[1];
190            if (methodName.equals(eventType.getCalledMethod())) {
191                matching.add(transition);
192            }
193        }
194        return matching;
195    }
196   
197}
Note: See TracBrowser for help on using the repository browser.