Ignore:
Timestamp:
07/29/14 14:30:16 (10 years ago)
Author:
sherbold
Message:
  • added missing comments
  • added method to extend an UML model with an interaction based on a sequence of SOAP events.
Location:
trunk/autoquest-plugin-uml/src/main/java/de/ugoe/cs/autoquest/plugin/uml
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/autoquest-plugin-uml/src/main/java/de/ugoe/cs/autoquest/plugin/uml/UMLUtils.java

    r1604 r1624  
    2424 
    2525import org.eclipse.emf.common.util.EList; 
     26import org.eclipse.uml2.uml.Association; 
     27import org.eclipse.uml2.uml.Class; 
    2628import org.eclipse.uml2.uml.Comment; 
     29import org.eclipse.uml2.uml.Element; 
     30import org.eclipse.uml2.uml.Interaction; 
     31import org.eclipse.uml2.uml.Lifeline; 
     32import org.eclipse.uml2.uml.Message; 
     33import org.eclipse.uml2.uml.MessageOccurrenceSpecification; 
     34import org.eclipse.uml2.uml.Model; 
     35import org.eclipse.uml2.uml.Operation; 
    2736import org.eclipse.uml2.uml.Region; 
    2837import org.eclipse.uml2.uml.StateMachine; 
    2938import org.eclipse.uml2.uml.Transition; 
     39import org.eclipse.uml2.uml.UMLPackage; 
    3040import org.eclipse.uml2.uml.Vertex; 
    3141 
     
    3646/** 
    3747 * <p> 
    38  * TODO comment 
     48 * Utilities for working with UML. 
    3949 * </p> 
    4050 *  
     
    4353public class UMLUtils { 
    4454 
    45     public static List<Event> createUMLTransitionSequence(List<Event> sequence, StateMachine stateMachine) { 
    46         List<List<Transition>> matchingSequences = determineMatchingTransitionSequences(sequence, stateMachine); 
     55    /** 
     56     * <p> 
     57     * Creates a sequence of events with {@link UMLTransitionType} as event type from a given 
     58     * sequence of events with the {@link SOAPEventType}, by matching the sequences to a state 
     59     * machine. 
     60     * </p> 
     61     *  
     62     * @param sequence 
     63     *            SOAP sequences 
     64     * @param stateMachine 
     65     *            the state machine 
     66     * @return create UML sequences 
     67     */ 
     68    public static List<Event> createUMLTransitionSequence(List<Event> sequence, 
     69                                                          StateMachine stateMachine) 
     70    { 
     71        List<List<Transition>> matchingSequences = 
     72            determineMatchingTransitionSequences(sequence, stateMachine); 
    4773 
    4874        if (matchingSequences.size() != 1) { 
     
    5682        return umlEventSequence; 
    5783    } 
    58      
    59     public static void convertStateMachineToUsageProfile(Collection<List<Event>> sequences, StateMachine stateMachine) { 
     84 
     85    /** 
     86     * <p> 
     87     * Uses a sequences of events with the {@link UMLTransitionType} to determine the transition 
     88     * probabilities for the state machine. 
     89     * </p> 
     90     *  
     91     * @param sequences 
     92     *            UML sequences 
     93     * @param stateMachine 
     94     *            state machine to be converted to a usage profile 
     95     */ 
     96    public static void convertStateMachineToUsageProfile(Collection<List<Event>> sequences, 
     97                                                         StateMachine stateMachine) 
     98    { 
    6099        // 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          
     100        Map<Vertex, Map<Transition, Integer>> stateMap = new HashMap<>(); 
     101        for (Region region : stateMachine.getRegions()) { 
     102            for (Vertex state : region.getSubvertices()) { 
     103                stateMap.put(state, new HashMap<Transition, Integer>()); 
     104            } 
     105        } 
     106 
    68107        // create counters for each transition 
    69         for( List<Event> sequence : sequences) { 
    70             for( Event event : sequence ) { 
    71                 if( event.getType() instanceof UMLTransitionType ) { 
     108        for (List<Event> sequence : sequences) { 
     109            for (Event event : sequence) { 
     110                if (event.getType() instanceof UMLTransitionType) { 
    72111                    Transition transition = ((UMLTransitionType) event.getType()).getTransition(); 
    73                     Map<Transition,Integer> transitionMap = stateMap.get(transition.getSource()); 
     112                    Map<Transition, Integer> transitionMap = stateMap.get(transition.getSource()); 
    74113                    Integer value = transitionMap.get(transition); 
    75                     if( value==null ) { 
     114                    if (value == null) { 
    76115                        value = 0; 
    77116                    } 
    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()); 
     117                    transitionMap.put(transition, value + 1); 
     118                } 
     119                else { 
     120                    throw new RuntimeException( 
     121                                               "Wrong event type. Only UMLTransitionType supported but was: " + 
     122                                                   event.getType().getClass().getName()); 
    82123                } 
    83124            } 
     
    85126 
    86127        // calculate probabilities 
    87         for( Region region : stateMachine.getRegions() ) { 
    88             for( Vertex state : region.getSubvertices() ) { 
    89                 Map<Transition,Integer> transitionMap = stateMap.get(state); 
     128        for (Region region : stateMachine.getRegions()) { 
     129            for (Vertex state : region.getSubvertices()) { 
     130                Map<Transition, Integer> transitionMap = stateMap.get(state); 
    90131                int totalCount = 0; 
    91                 for( Entry<Transition,Integer> entry : transitionMap.entrySet() ) { 
     132                for (Entry<Transition, Integer> entry : transitionMap.entrySet()) { 
    92133                    totalCount += entry.getValue(); 
    93134                } 
    94                 if( totalCount!=0 ) { 
    95                     for( Transition transition : state.getOutgoings() ) { 
     135                if (totalCount != 0) { 
     136                    for (Transition transition : state.getOutgoings()) { 
    96137                        double prob = 0.0d; 
    97                         if( transitionMap.containsKey(transition)) { 
    98                             prob = ((double) transitionMap.get(transition))/totalCount; 
     138                        if (transitionMap.containsKey(transition)) { 
     139                            prob = ((double) transitionMap.get(transition)) / totalCount; 
    99140                        } 
    100141                        Comment comment = transition.createOwnedComment(); 
    101                         comment.setBody("" + prob ); 
    102                     } 
    103                 } else { 
     142                        comment.setBody("" + prob); 
     143                    } 
     144                } 
     145                else { 
    104146                    // system has never been in this state, all transitions equally likely 
    105147                    int numOutgoings = state.getOutgoings().size(); 
    106                     for( Transition transition : state.getOutgoings() ) { 
     148                    for (Transition transition : state.getOutgoings()) { 
    107149                        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) { 
     150                        comment.setBody("" + (1.0d / numOutgoings)); 
     151                    } 
     152                } 
     153            } 
     154        } 
     155    } 
     156 
     157    /** 
     158     * <p> 
     159     * Determines all matching {@link Transition} sequences in a state machine for a given sequence 
     160     * of SOAP events. 
     161     * </p> 
     162     *  
     163     * @param sequence 
     164     *            SOAP sequence 
     165     * @param stateMachine 
     166     *            the state machine 
     167     * @return all matching {@link Transition} sequences 
     168     */ 
     169    public static List<List<Transition>> determineMatchingTransitionSequences(List<Event> sequence, 
     170                                                                              StateMachine stateMachine) 
     171    { 
    116172        EList<Region> regions = stateMachine.getRegions(); 
    117173        EList<Vertex> states = null; 
     
    175231            } 
    176232            else { 
    177                 throw new RuntimeException("Wrong event type. Only UMLTransitionType supported but was: " + 
    178                     event.getType().getClass().getName()); 
     233                throw new RuntimeException( 
     234                                           "Wrong event type. Only UMLTransitionType supported but was: " + 
     235                                               event.getType().getClass().getName()); 
    179236            } 
    180237        } 
    181238        return matchingSequences; 
    182239    } 
    183      
    184     private static List<Transition> matchTransitions(List<Transition> transitions, SOAPEventType eventType) 
     240 
     241    /** 
     242     * <p> 
     243     * Extends a given model with an interaction that represents an observed sequence.  
     244     * </p> 
     245     * 
     246     * @param sequence sequence that is added as sequence diagram 
     247     * @param model UML model to which the interaction is added 
     248     * @param interactionName name of the interaction 
     249     */ 
     250    public static void createInteractionFromEventSequence(List<Event> sequence, Model model, String interactionName) 
     251    { 
     252        Map<String, Class> classMap = new HashMap<>(); 
     253 
     254        EList<Element> elements = model.getOwnedElements(); 
     255        for (Element element : elements) { 
     256            if (element instanceof Class) { 
     257                classMap.put(((Class) element).getName(), (Class) element); 
     258            } 
     259        } 
     260 
     261        Interaction interaction = 
     262            (Interaction) model 
     263                .createPackagedElement(interactionName, UMLPackage.Literals.INTERACTION); 
     264 
     265        Lifeline userLifeline = interaction.createLifeline("user"); 
     266 
     267        int i = 0; 
     268        for (Event event : sequence) { 
     269            if (event.getType() instanceof SOAPEventType) { 
     270                SOAPEventType eventType = (SOAPEventType) event.getType(); 
     271                String serviceName = eventType.getServiceName(); 
     272                String methodName = eventType.getCalledMethod(); 
     273                Class targetClass = classMap.get(serviceName); 
     274                if (targetClass == null) { 
     275                    throw new RuntimeException( 
     276                                               "Could not find class in the UML model that belong to the service: " + 
     277                                                   serviceName); 
     278                } 
     279 
     280                Lifeline targetLifeline = interaction.getLifeline(serviceName); 
     281                if (targetLifeline == null) { 
     282                    targetLifeline = interaction.createLifeline(serviceName); 
     283                    Association association = 
     284                        (Association) model.getPackagedElement("user_" + serviceName, true, 
     285                                                               UMLPackage.Literals.ASSOCIATION, 
     286                                                               true); 
     287                    targetLifeline 
     288                        .setRepresents(association.getMemberEnd(serviceName, 
     289                                                                classMap.get(serviceName))); 
     290                } 
     291                MessageOccurrenceSpecification sendFragment = 
     292                    (MessageOccurrenceSpecification) interaction 
     293                        .createFragment(i + ":" + methodName + "_sendFragment", 
     294                                        UMLPackage.Literals.MESSAGE_OCCURRENCE_SPECIFICATION); 
     295                MessageOccurrenceSpecification recvFragment = 
     296                    (MessageOccurrenceSpecification) interaction 
     297                        .createFragment(i + ":" + methodName + "_recvFragment", 
     298                                        UMLPackage.Literals.MESSAGE_OCCURRENCE_SPECIFICATION); 
     299 
     300                sendFragment.setCovered(userLifeline); 
     301                recvFragment.setCovered(targetLifeline); 
     302 
     303                Message message = interaction.createMessage(methodName); 
     304                message.setSignature(getOperationFromName(targetClass.getOperations(), methodName)); 
     305                message.setSendEvent(sendFragment); 
     306                message.setReceiveEvent(recvFragment); 
     307 
     308                sendFragment.setMessage(message); 
     309                recvFragment.setMessage(message); 
     310            } 
     311            else { 
     312                throw new RuntimeException( 
     313                                           "Wrong event type. Only SOAPEventType supported but was: " + 
     314                                               event.getType().getClass().getName()); 
     315            } 
     316            i++; 
     317        } 
     318    } 
     319 
     320    /** 
     321     * <p> 
     322     * Fetches an operation using only its name from a list of operations. Returns the first match 
     323     * found or null if no match is found. 
     324     * </p> 
     325     *  
     326     * @param operations 
     327     *            list of operations 
     328     * @param name 
     329     *            name of the operation 
     330     * @return first matching operation; null if no match is found 
     331     */ 
     332    private static Operation getOperationFromName(EList<Operation> operations, String name) { 
     333        if (name == null) { 
     334            throw new IllegalArgumentException("name of the operation must not be null"); 
     335        } 
     336        if (operations != null) { 
     337            for (Operation operation : operations) { 
     338                if (operation.getName() != null && operation.getName().equals(name)) { 
     339                    return operation; 
     340                } 
     341            } 
     342        } 
     343        return null; 
     344    } 
     345 
     346    /** 
     347     * <p> 
     348     * Determines which transitions match a given {@link SOAPEventType}. 
     349     * </p> 
     350     *  
     351     * @param transitions 
     352     *            the transitions 
     353     * @param eventType 
     354     *            the SOAP event 
     355     * @return matching transitions 
     356     */ 
     357    private static List<Transition> matchTransitions(List<Transition> transitions, 
     358                                                     SOAPEventType eventType) 
    185359    { 
    186360        List<Transition> matching = new LinkedList<>(); 
     
    194368        return matching; 
    195369    } 
    196      
     370 
    197371} 
  • trunk/autoquest-plugin-uml/src/main/java/de/ugoe/cs/autoquest/plugin/uml/eventcore/UMLTransitionType.java

    r1604 r1624  
     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 
    115package de.ugoe.cs.autoquest.plugin.uml.eventcore; 
    216 
     
    519import de.ugoe.cs.autoquest.eventcore.IEventType; 
    620 
    7 // TODO comment 
     21/** 
     22 * <p> 
     23 * Event type for transitions in UML sequence diagrams 
     24 * </p> 
     25 *  
     26 * @author Steffen Herbold 
     27 */ 
    828public class UMLTransitionType implements IEventType { 
    929 
    10     /**  */ 
     30    /** 
     31     * Id for object serialization. 
     32     */ 
    1133    private static final long serialVersionUID = 1L; 
    12      
     34 
     35    /** 
     36     * associated UML transition 
     37     */ 
    1338    private final Transition transition; 
    14      
     39 
     40    /** 
     41     * <p> 
     42     * Constructor. Creates a new instance. 
     43     * </p> 
     44     *  
     45     * @param transition 
     46     *            the instance 
     47     */ 
    1548    public UMLTransitionType(Transition transition) { 
     49        if (transition == null) { 
     50            throw new IllegalArgumentException("Transition must not be null"); 
     51        } 
    1652        this.transition = transition; 
    1753    } 
    18      
     54 
     55    /** 
     56     * <p> 
     57     * Returns the associated UML element 
     58     * </p> 
     59     *  
     60     * @return 
     61     */ 
    1962    public Transition getTransition() { 
    2063        return transition; 
    2164    } 
    22      
     65 
     66    /* 
     67     * (non-Javadoc) 
     68     *  
     69     * @see java.lang.Object#equals(java.lang.Object) 
     70     */ 
    2371    @Override 
    2472    public boolean equals(Object other) { 
    25         if( other==this ) { 
     73        if (other == this) { 
    2674            return true; 
    2775        } 
    28         if( other instanceof UMLTransitionType ) { 
     76        if (other instanceof UMLTransitionType) { 
    2977            return ((UMLTransitionType) other).transition.equals(transition); 
    3078        } 
    3179        return false; 
    3280    }; 
    33      
     81 
     82    /* 
     83     * (non-Javadoc) 
     84     *  
     85     * @see java.lang.Object#hashCode() 
     86     */ 
    3487    @Override 
    3588    public int hashCode() { 
    3689        return transition.hashCode(); 
    3790    } 
    38      
     91 
     92    /* 
     93     * (non-Javadoc) 
     94     *  
     95     * @see de.ugoe.cs.autoquest.eventcore.IEventType#getName() 
     96     */ 
    3997    @Override 
    4098    public String getName() { 
    41         // TODO Auto-generated method stub 
    42         System.out.println("TODO: implement UMLTransactionType.getName "); 
    43         return null; 
     99        return transition.getName(); 
    44100    } 
    45101 
Note: See TracChangeset for help on using the changeset viewer.