// Copyright 2012 Georg-August-Universität Göttingen, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package de.ugoe.cs.autoquest.plugin.uml; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.eclipse.emf.common.util.EList; import org.eclipse.uml2.uml.Comment; import org.eclipse.uml2.uml.Region; import org.eclipse.uml2.uml.StateMachine; import org.eclipse.uml2.uml.Transition; import org.eclipse.uml2.uml.Vertex; import de.ugoe.cs.autoquest.eventcore.Event; import de.ugoe.cs.autoquest.plugin.http.eventcore.SOAPEventType; import de.ugoe.cs.autoquest.plugin.uml.eventcore.UMLTransitionType; /** *

* TODO comment *

* * @author Steffen Herbold */ public class UMLUtils { public static List createUMLTransitionSequence(List sequence, StateMachine stateMachine) { List> matchingSequences = determineMatchingTransitionSequences(sequence, stateMachine); if (matchingSequences.size() != 1) { throw new RuntimeException("no unique match found; " + matchingSequences.size() + " matches"); } List umlEventSequence = new LinkedList<>(); for (Transition transition : matchingSequences.get(0)) { umlEventSequence.add(new Event(new UMLTransitionType(transition))); } return umlEventSequence; } public static void convertStateMachineToUsageProfile(Collection> sequences, StateMachine stateMachine) { // create state->outgoings hashmap Map> stateMap = new HashMap<>(); for( Region region : stateMachine.getRegions() ) { for( Vertex state : region.getSubvertices() ) { stateMap.put(state, new HashMap()); } } // create counters for each transition for( List sequence : sequences) { for( Event event : sequence ) { if( event.getType() instanceof UMLTransitionType ) { Transition transition = ((UMLTransitionType) event.getType()).getTransition(); Map transitionMap = stateMap.get(transition.getSource()); Integer value = transitionMap.get(transition); if( value==null ) { value = 0; } transitionMap.put(transition, value+1); } else { throw new RuntimeException("Wrong event type. Only UMLTransitionType supported but was: " + event.getType().getClass().getName()); } } } // calculate probabilities for( Region region : stateMachine.getRegions() ) { for( Vertex state : region.getSubvertices() ) { Map transitionMap = stateMap.get(state); int totalCount = 0; for( Entry entry : transitionMap.entrySet() ) { totalCount += entry.getValue(); } if( totalCount!=0 ) { for( Transition transition : state.getOutgoings() ) { double prob = 0.0d; if( transitionMap.containsKey(transition)) { prob = ((double) transitionMap.get(transition))/totalCount; } Comment comment = transition.createOwnedComment(); comment.setBody("" + prob ); } } else { // system has never been in this state, all transitions equally likely int numOutgoings = state.getOutgoings().size(); for( Transition transition : state.getOutgoings() ) { Comment comment = transition.createOwnedComment(); comment.setBody("" + (1.0d/numOutgoings) ); } } } } } public static List> determineMatchingTransitionSequences(List sequence, StateMachine stateMachine) { EList regions = stateMachine.getRegions(); EList states = null; for (Region region : regions) { if (states == null) { states = region.getSubvertices(); } else { states.addAll(region.getSubvertices()); } } List allTransitions = new LinkedList<>(); for (Vertex state : states) { allTransitions.addAll(state.getOutgoings()); } List> matchingSequences = null; List currentTransitions = null; // first, we try to find a single unique transition that we can match using the method name for (Iterator eventIterator = sequence.iterator(); eventIterator.hasNext();) { Event event = eventIterator.next(); if (event.getType() instanceof SOAPEventType) { SOAPEventType eventType = (SOAPEventType) event.getType(); if (matchingSequences == null) { matchingSequences = new LinkedList<>(); List initialMatches = matchTransitions(allTransitions, eventType); for (Transition transition : initialMatches) { List candidate = new LinkedList<>(); candidate.add(transition); matchingSequences.add(candidate); } currentTransitions = initialMatches; } else { List> nextMatchingSequences = new LinkedList<>(); List nextCurrentTransitions = new LinkedList<>(); Iterator currentTransitionIterator = currentTransitions.iterator(); Iterator> currentMatchingSequencesIterator = matchingSequences.iterator(); while (currentTransitionIterator.hasNext()) { Transition currentTransition = currentTransitionIterator.next(); List currentMatch = currentMatchingSequencesIterator.next(); List matches = matchTransitions(currentTransition.getTarget().getOutgoings(), eventType); if (matches.isEmpty()) { throw new RuntimeException("no matches found"); } for (Transition matchingTransition : matches) { List candidate = new LinkedList<>(currentMatch); candidate.add(matchingTransition); nextMatchingSequences.add(candidate); nextCurrentTransitions.add(matchingTransition); } } matchingSequences = nextMatchingSequences; currentTransitions = nextCurrentTransitions; } } else { throw new RuntimeException("Wrong event type. Only UMLTransitionType supported but was: " + event.getType().getClass().getName()); } } return matchingSequences; } private static List matchTransitions(List transitions, SOAPEventType eventType) { List matching = new LinkedList<>(); for (Transition transition : transitions) { // String serviceName = transition.getName().split("\\.")[0]; // TODO service name check String methodName = transition.getName().split("\\.")[1]; if (methodName.equals(eventType.getCalledMethod())) { matching.add(transition); } } return matching; } }