Changeset 1929 for trunk


Ignore:
Timestamp:
03/20/15 16:00:10 (9 years ago)
Author:
sherbold
Message:
  • refactored and commented UMLUtils
  • created UTPUtils
  • moved DOM related methods from UMLUtils to SOAPUtils
Location:
trunk
Files:
1 added
3 edited

Legend:

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

    r1928 r1929  
    1616 
    1717import java.io.StringWriter; 
     18import java.util.ArrayList; 
    1819import java.util.Iterator; 
    1920import java.util.LinkedList; 
     
    2728import javax.xml.transform.stream.StreamResult; 
    2829 
     30import org.w3c.dom.Attr; 
    2931import org.w3c.dom.Element; 
    3032import org.w3c.dom.Node; 
     33import org.w3c.dom.NodeList; 
    3134 
    3235import de.ugoe.cs.autoquest.eventcore.Event; 
     
    4346 */ 
    4447public class SOAPUtils { 
    45      
     48 
    4649    /** 
    4750     * <p> 
     
    6972                                                                      eventType.getServiceName(), 
    7073                                                                      eventType.getClientName(), 
    71                                                                       eventType.getSoapRequestBody()))); 
     74                                                                      eventType 
     75                                                                          .getSoapRequestBody()))); 
    7276                } 
    7377                else { 
     
    8084        return newSequence; 
    8185    } 
    82      
     86 
    8387    /** 
    8488     * <p> 
     
    8993     *            sequence where the events are replaced 
    9094     */ 
    91     public static void removeNonSOAPEvents(List<Event> sequence) 
    92     { 
     95    public static void removeNonSOAPEvents(List<Event> sequence) { 
    9396        for (Iterator<Event> eventIter = sequence.iterator(); eventIter.hasNext();) { 
    9497            Event event = eventIter.next(); 
     
    188191        return requestBody; 
    189192    } 
    190      
    191     /** 
    192      * <p> 
    193      * returns the XML serialization of a DOM node; located here because it is used for SOAP request bodies 
     193 
     194    /** 
     195     * <p> 
     196     * returns the XML serialization of a DOM node; located here because it is used for SOAP request 
     197     * bodies 
    194198     * </p> 
    195199     *  
     
    199203     */ 
    200204    public static String getSerialization(Node node) { 
    201         if( node==null ) { 
     205        if (node == null) { 
    202206            return null; 
    203207        } 
     
    214218        } 
    215219    } 
    216      
     220 
     221    /** 
     222     * <p> 
     223     * Fetches all {@link Element}s that are direct children of the parent node, whose name matches 
     224     * the given name. 
     225     * </p> 
     226     *  
     227     * @param typeNameRaw 
     228     *            name of elements that are looked for 
     229     * @param parentNode 
     230     *            DOM node in which the elements are searched for 
     231     * @return found {@link Element}s 
     232     */ 
     233    public static List<Element> getMatchingChildNode(String typeNameRaw, Element parentNode) { 
     234        List<Element> matchingNodes = new ArrayList<>(); 
     235        Node parameterNode = null; 
     236        if (parentNode != null) { 
     237            NodeList parameterNodes = parentNode.getChildNodes(); 
     238            String[] typeNameSplit = typeNameRaw.split(":"); 
     239            String typeName = typeNameSplit[typeNameSplit.length - 1]; 
     240            for (int i = 0; i < parameterNodes.getLength(); i++) { 
     241                parameterNode = parameterNodes.item(i); 
     242                if (parameterNode.getNodeType() == Node.ELEMENT_NODE) { 
     243                    String[] parameterNodeSplit = parameterNode.getNodeName().split(":"); 
     244                    String parameterNodeName = parameterNodeSplit[parameterNodeSplit.length - 1]; 
     245                    if (typeName.equals(parameterNodeName)) { 
     246                        matchingNodes.add((Element) parameterNode); 
     247                    } 
     248                } 
     249            } 
     250        } 
     251        return matchingNodes; 
     252    } 
     253 
     254    /** 
     255     * <p> 
     256     * Returns the values found in a currentNode for a defined valueName. To this aim, this methods 
     257     * first determines if there is an attribute with the name "valueName". If this is the case, the 
     258     * value of this attribute is returned. Otherwise, the methods looks for {@link Element}s that 
     259     * are direct children of the provided DOM node with the given name and returns the text content 
     260     * of those nodes. 
     261     * </p> 
     262     * <p> 
     263     * In case no values can be found, an empty list is returned 
     264     *  
     265     * @param valueName 
     266     *            name of the value that is retrieved 
     267     * @param node 
     268     *            node for which the value is retrieved 
     269     * @return list of the found values. 
     270     */ 
     271    public static List<String> getValuesFromElement(String valueName, Element node) { 
     272        List<String> attributeValues = new LinkedList<>(); 
     273 
     274        if (node != null) { 
     275            // first check attributes of the node 
     276            Attr attribute = node.getAttributeNode(valueName); 
     277            if (attribute != null) { 
     278                attributeValues.add(attribute.getValue()); 
     279            } 
     280            else { 
     281                // now check elements 
     282                List<Element> elements = getMatchingChildNode(valueName, node); 
     283                for (Element element : elements) { 
     284                    attributeValues.add(element.getTextContent()); 
     285                } 
     286            } 
     287        } 
     288 
     289        return attributeValues; 
     290    } 
     291 
    217292    /** 
    218293     * <p> 
  • trunk/autoquest-plugin-uml-test/src/test/java/de/ugoe/cs/autoquest/plugin/uml/UMLUtilsTest.java

    r1927 r1929  
    1717import java.io.File; 
    1818import java.io.FileInputStream; 
     19import java.io.FileOutputStream; 
    1920import java.util.Collection; 
    2021import java.util.HashSet; 
     
    2930//import static org.junit.Assert.*; 
    3031 
    31 import org.apache.commons.lang.SerializationUtils; 
     32 
     33 
     34 
    3235import org.eclipse.uml2.uml.Interaction; 
    3336import org.eclipse.uml2.uml.Model; 
     
    4346import de.ugoe.cs.autoquest.plugin.http.SOAPUtils; 
    4447import de.ugoe.cs.autoquest.plugin.http.eventcore.SOAPEventType; 
     48import de.ugoe.cs.autoquest.plugin.http.eventcore.SimpleSOAPEventType; 
    4549import de.ugoe.cs.autoquest.testgeneration.RandomWalkGenerator; 
    4650import de.ugoe.cs.autoquest.usageprofiles.FirstOrderMarkovModel; 
    4751import de.ugoe.cs.autoquest.usageprofiles.IStochasticProcess; 
     52import de.ugoe.cs.util.SerializationUtils; 
    4853import de.ugoe.cs.util.console.TextConsole; 
    4954 
     
    5863 
    5964    private final static String OUTPUT_DIR = "target/tmp/test-outputs/"; 
    60      
     65 
     66    private final static boolean DELETE_OUTPUTS = false; 
     67 
    6168    // for RLUS 
    6269    private final static TestData deda_1 = new TestData("deda_rlus_properties.prop", 
    63                                                       "deda_usagejournal.log", 
    64                                                       "deda_rlus_usageprofile.dat", 
    65                                                       "deda_model.uml", 
    66                                                       "deda_rlus_model_testsuite.uml", 
    67                                                       "deda_rlus_model_scheduling.uml"); 
     70                                                        "deda_usagejournal.log", 
     71                                                        "deda_rlus_usageprofile.dat", 
     72                                                        "deda_model.uml", 
     73                                                        "deda_rlus_model_testsuite.uml", 
     74                                                        "deda_rlus_model_scheduling.uml"); 
    6875 
    6976    // for IXS 
    7077    private final static TestData deda_2 = new TestData("deda_ixs_properties.prop", 
    71                                                            "deda_usagejournal.log", 
    72                                                            "deda_ixs_usageprofile.dat", 
    73                                                            "deda_model.uml", 
    74                                                            "deda_ixs_model_testsuite.uml", 
    75                                                            "deda_ixs_model_scheduling.uml"); 
    76  
    77     private final static TestData ita_1 = new TestData("ita_properties.prop", "ita_usagejournal.log", 
    78                                                      "ita_usageprofile.dat", "ita_model.uml", 
    79                                                      "ita_model_testsuite.uml", 
    80                                                      "ita_model_scheduling.uml"); 
    81      
     78                                                        "deda_usagejournal.log", 
     79                                                        "deda_ixs_usageprofile.dat", 
     80                                                        "deda_model.uml", 
     81                                                        "deda_ixs_model_testsuite.uml", 
     82                                                        "deda_ixs_model_scheduling.uml"); 
     83 
     84    private final static TestData ita_1 = new TestData("ita_properties.prop", 
     85                                                       "ita_usagejournal.log", 
     86                                                       "ita_usageprofile.dat", "ita_model.uml", 
     87                                                       "ita_model_testsuite.uml", 
     88                                                       "ita_model_scheduling.uml"); 
     89 
    8290    private static class TestData { 
    8391        public final String propertiesFile; 
     
    8997 
    9098        public TestData(String propertiesFile, 
    91                 String usageJournalFile, 
    92                 String usageProfileFile, 
    93                 String dslModelFile, 
    94                 String testSuiteFile, 
    95                 String schedulingFile) 
     99                        String usageJournalFile, 
     100                        String usageProfileFile, 
     101                        String dslModelFile, 
     102                        String testSuiteFile, 
     103                        String schedulingFile) 
    96104        { 
    97105            this.propertiesFile = propertiesFile; 
     
    101109            this.testSuiteFile = testSuiteFile; 
    102110            this.schedulingFile = schedulingFile; 
    103              
     111 
    104112        } 
    105113 
     
    119127    @BeforeClass 
    120128    public static void setUpBeforeClass() throws Exception { 
    121         new TextConsole(Level.FINE); 
     129        new TextConsole(Level.SEVERE); 
    122130    } 
    123131 
    124132    @After 
    125133    public void tearDown() throws Exception { 
    126         deleteFiles(new File(OUTPUT_DIR)); 
     134        if (DELETE_OUTPUTS) { 
     135            deleteFiles(new File(OUTPUT_DIR)); 
     136        } 
    127137    } 
    128138 
     
    130140    public void testCreateUMLTransitionSequence_ITA_1() throws Exception { 
    131141        TestData testdata = ita_1; 
    132          
     142 
    133143        Properties properties = loadProperties(testdata); 
    134144        Collection<List<Event>> sequences = loadAndPreprocessUsageJournal(testdata, properties); 
     
    137147 
    138148        StateMachine stateMachine = 
    139                 (StateMachine) model.getPackagedElement("StateMachineTransportService", true, 
    140                                                         UMLPackage.Literals.STATE_MACHINE, true); 
    141  
    142             
     149            (StateMachine) model.getPackagedElement("StateMachineTransportService", true, 
     150                                                    UMLPackage.Literals.STATE_MACHINE, true); 
     151 
    143152        Collection<List<Event>> umlSequences = new LinkedList<>(); 
    144          
     153 
    145154        // remove everything but transport from sequences 
    146155        for (List<Event> sequence : sequences) { 
     
    159168    public void testConvertStateMachineToUsageProfile__ITA_1() throws Exception { 
    160169        TestData testdata = ita_1; 
    161          
     170 
    162171        Properties properties = loadProperties(testdata); 
    163172        Collection<List<Event>> sequences = loadAndPreprocessUsageJournal(testdata, properties); 
     
    190199        createInteractionFromEventSequenceWorkflow(deda_1); 
    191200    } 
    192      
     201 
    193202    @Test 
    194203    public void testCreateInteractionFromEventSequence_DEDA_2() throws Exception { 
    195204        createInteractionFromEventSequenceWorkflow(deda_2); 
    196205    } 
    197      
     206 
    198207    @Test 
    199208    public void testCreateInteractionFromEventSequence_ITA_1() throws Exception { 
     
    205214        calculateUsageScoreWorkflow(deda_1); 
    206215    } 
    207      
     216 
    208217    @Test 
    209218    public void testCalculateUsageScore_DEDA_2() throws Exception { 
     
    211220    } 
    212221 
    213      
    214222    @Test 
    215223    public void testCalculateUsageScore_ITA_1() throws Exception { 
     
    221229        createSchedulingWorkflow(deda_1); 
    222230    } 
    223      
     231 
    224232    @Test 
    225233    public void testCreateScheduling_DEDA_2() throws Exception { 
    226234        createSchedulingWorkflow(deda_2); 
    227235    } 
    228      
     236 
    229237    @Test 
    230238    public void testCreateScheduling_ITA() throws Exception { 
     
    236244        validateModelWithLogWorkflow(deda_1); 
    237245    } 
    238      
    239246 
    240247    @Test 
     
    247254        validateModelWithLogWorkflow(ita_1); 
    248255    } 
    249      
     256 
    250257    private void validateModelWithLogWorkflow(TestData testdata) throws Exception { 
    251258        Properties properties = loadProperties(testdata); 
    252259        Collection<List<Event>> sequences = loadAndPreprocessUsageJournal(testdata, properties); 
    253         Model model = ModelUtils.loadModel(ClassLoader.getSystemResourceAsStream(testdata.dslModelFile)); 
    254          
     260        Model model = 
     261            ModelUtils.loadModel(ClassLoader.getSystemResourceAsStream(testdata.dslModelFile)); 
     262 
    255263        // run validation 
    256         int violations = UMLUtils.validateModelWithLog(sequences, model, properties.getProperty("test.context")); 
     264        int violations = 
     265            UMLUtils.validateModelWithLog(sequences, model, properties.getProperty("test.context")); 
    257266        if (violations == 0) { 
    258267            System.out.println("No problems found."); 
     
    262271        } 
    263272    } 
    264      
     273 
    265274    private void createInteractionFromEventSequenceWorkflow(TestData testdata) throws Exception { 
    266275        Properties properties = loadProperties(testdata); 
    267276        Collection<List<Event>> sequences = loadAndPreprocessUsageJournal(testdata, properties); 
    268         Model model = ModelUtils.loadModel(ClassLoader.getSystemResourceAsStream(testdata.dslModelFile)); 
    269          
     277        Model model = 
     278            ModelUtils.loadModel(ClassLoader.getSystemResourceAsStream(testdata.dslModelFile)); 
     279 
    270280        // create a test case for each observed sequence 
    271         int i=0; 
    272         for( List<Event> sequence : sequences ) { 
    273             UMLUtils.createInteractionFromEventSequence(sequence, model, properties.getProperty("testcases.prefix")+"_"+i, 
    274                     properties.getProperty("test.context")); 
     281        int i = 0; 
     282        for (List<Event> sequence : sequences) { 
     283            UMLUtils.createInteractionFromEventSequence(sequence, model, 
     284                                                        properties.getProperty("testcases.prefix") + 
     285                                                            "_" + i, 
     286                                                        properties.getProperty("test.context")); 
    275287            i++; 
    276288        } 
    277     } 
    278      
     289 
     290        ModelUtils.writeModelToFile(model, OUTPUT_DIR + testdata.testSuiteFile); 
     291    } 
     292 
    279293    private void calculateUsageScoreWorkflow(TestData testdata) throws Exception { 
    280294        Properties properties = loadProperties(testdata); 
    281295        Collection<List<Event>> sequences = loadAndPreprocessUsageJournal(testdata, properties); 
    282296        Model model = 
    283             ModelUtils.loadModel(ClassLoader 
    284                 .getSystemResourceAsStream(testdata.dslModelFile)); 
    285         IStochasticProcess usageProfile = createUsageProfile(sequences); 
    286         Collection<List<Event>> generatedSequences = createRandomSequences(usageProfile, properties); 
    287          
     297            ModelUtils.loadModel(ClassLoader.getSystemResourceAsStream(testdata.dslModelFile)); 
     298        IStochasticProcess usageProfile = createUsageProfile(testdata, sequences); 
     299        Collection<List<Event>> generatedSequences = 
     300            createRandomSequences(usageProfile, properties); 
     301 
    288302        int i = 1; 
     303        List<Interaction> interactions = new LinkedList<>(); 
    289304        int[] lengths = new int[generatedSequences.size()]; 
    290305        for (List<Event> sequence : generatedSequences) { 
    291             UMLUtils.createInteractionFromEventSequence(sequence, model, properties.getProperty("testcases.prefix")+"_"+i, 
    292                                                         properties.getProperty("test.context")); 
     306            interactions.add(UMLUtils.createInteractionFromEventSequence(sequence, model, 
     307                                                        properties.getProperty("testcases.prefix") + 
     308                                                            "_" + i, 
     309                                                        properties.getProperty("test.context"))); 
    293310            lengths[i - 1] = sequence.size(); 
    294311            i++; 
    295312        } 
    296         for (int j = 0; j < generatedSequences.size(); j++) { 
    297             Interaction interaction = 
    298                 (Interaction) model.getPackagedElement(properties.getProperty("testcases.prefix") + j, true, 
    299                                                        UMLPackage.Literals.INTERACTION, true); 
    300             double usageScore = UMLUtils.calculateUsageScore(interaction, usageProfile); 
     313        for (int j = 0; j < interactions.size(); j++) { 
     314            double usageScore = UMLUtils.calculateUsageScore(interactions.get(j), usageProfile); 
    301315            System.out.format("usage score %02d: %.2f \t %d\n", j + 1, usageScore, lengths[j]); 
    302316        } 
    303317    } 
    304      
     318 
    305319    private void createSchedulingWorkflow(TestData testdata) throws Exception { 
    306320        Properties properties = loadProperties(testdata); 
    307321        Collection<List<Event>> sequences = loadAndPreprocessUsageJournal(testdata, properties); 
    308         Model model = ModelUtils.loadModel(ClassLoader.getSystemResourceAsStream(testdata.dslModelFile)); 
    309         IStochasticProcess usageProfile = createUsageProfile(sequences); 
    310         Collection<List<Event>> generatedSequences = createRandomSequences(usageProfile, properties); 
     322        Model model = 
     323            ModelUtils.loadModel(ClassLoader.getSystemResourceAsStream(testdata.dslModelFile)); 
     324        IStochasticProcess usageProfile = createUsageProfile(testdata, sequences); 
     325        Collection<List<Event>> generatedSequences = 
     326            createRandomSequences(usageProfile, properties); 
    311327        int i = 1; 
    312328        for (List<Event> sequence : generatedSequences) { 
    313             UMLUtils.createInteractionFromEventSequence(sequence, model, properties.getProperty("testcases.prefix")+"_"+i, 
     329            UMLUtils.createInteractionFromEventSequence(sequence, model, 
     330                                                        properties.getProperty("testcases.prefix") + 
     331                                                            "_" + i, 
    314332                                                        properties.getProperty("test.context")); 
    315333            i++; 
    316334        } 
    317          
    318         UMLUtils.createScheduling(model, usageProfile, null); 
    319  
    320         //ModelUtils.writeModelToFile(model, OUTPUT_DIR + "testCreateScheduling_1_result.uml"); 
    321     } 
    322      
     335 
     336        UMLUtils.createScheduling(model, usageProfile, properties.getProperty("test.context")); 
     337 
     338        ModelUtils.writeModelToFile(model, OUTPUT_DIR + testdata.schedulingFile); 
     339    } 
     340 
    323341    private Properties loadProperties(TestData testdata) throws Exception { 
    324342        Properties properties = new Properties(); 
    325         properties.load(new FileInputStream(ClassLoader.getSystemResource(testdata.propertiesFile).getFile())); 
     343        properties.load(new FileInputStream(ClassLoader.getSystemResource(testdata.propertiesFile) 
     344            .getFile())); 
    326345        return properties; 
    327346    } 
    328      
    329     private Collection<List<Event>> loadAndPreprocessUsageJournal(TestData testdata, Properties properties) throws Exception { 
     347 
     348    private Collection<List<Event>> loadAndPreprocessUsageJournal(TestData testdata, 
     349                                                                  Properties properties) 
     350        throws Exception 
     351    { 
    330352        // load usage journal 
    331353        HTTPLogParser parser = 
    332354            new HTTPLogParser(new File(ClassLoader.getSystemResource(testdata.propertiesFile) 
    333355                .getFile())); 
    334         parser 
    335             .parseFile(new File(ClassLoader 
    336                 .getSystemResource(testdata.usageJournalFile) 
    337                 .getFile())); 
     356        parser.parseFile(new File(ClassLoader.getSystemResource(testdata.usageJournalFile) 
     357            .getFile())); 
    338358        Collection<List<Event>> sequences = parser.getSequences(); 
    339359 
    340         // remove non SOAP events 
     360        // remove non SOAP events and convert to SimpleSOAPEventType 
     361        Collection<List<Event>> simpleSOAPSequences = new LinkedList<>(); 
    341362        for (List<Event> sequence : sequences) { 
    342             SOAPUtils.removeNonSOAPEvents(sequence); 
    343         } 
    344          
     363            simpleSOAPSequences.add(SOAPUtils.convertToSimpleSOAPEvent(sequence, true)); 
     364        } 
     365 
    345366        // remove calls to ingored services 
    346367        Set<String> ignoredServices = new HashSet<>(); 
    347368        String ignoredServicesString = properties.getProperty("test.ignored.services"); 
    348         if( ignoredServicesString!=null ) { 
    349             for( String service : ignoredServicesString.split(",") ) { 
     369        if (ignoredServicesString != null) { 
     370            for (String service : ignoredServicesString.split(",")) { 
    350371                ignoredServices.add(service.trim()); 
    351372            } 
    352373        } 
    353          
    354         for (List<Event> sequence : sequences) { 
     374 
     375        for (List<Event> sequence : simpleSOAPSequences) { 
    355376            for (Iterator<Event> eventIter = sequence.iterator(); eventIter.hasNext();) { 
    356377                Event event = eventIter.next(); 
    357                 SOAPEventType eventType = (SOAPEventType) event.getType(); 
     378                SimpleSOAPEventType eventType = (SimpleSOAPEventType) event.getType(); 
    358379                if (ignoredServices.contains(eventType.getServiceName())) { 
    359380                    eventIter.remove(); 
     
    361382            } 
    362383        } 
    363         return sequences; 
    364     } 
    365      
    366     private IStochasticProcess createUsageProfile(Collection<List<Event>> sequences) throws Exception { 
    367         Collection<List<Event>> simpleSOAPSequences = new LinkedList<>(); 
    368         for (List<Event> sequence : sequences) { 
    369             simpleSOAPSequences.add(SOAPUtils.convertToSimpleSOAPEvent(sequence, true)); 
    370         } 
    371  
     384        return simpleSOAPSequences; 
     385    } 
     386 
     387    private IStochasticProcess createUsageProfile(TestData testdata, Collection<List<Event>> sequences) 
     388        throws Exception 
     389    { 
    372390        FirstOrderMarkovModel usageProfile = new FirstOrderMarkovModel(new Random(1)); 
    373         usageProfile.train(simpleSOAPSequences); 
     391        usageProfile.train(sequences); 
     392        FileOutputStream fos = new FileOutputStream(OUTPUT_DIR + testdata.usageProfileFile); 
     393        SerializationUtils.serialize(usageProfile, fos); 
     394        fos.close(); 
    374395        return usageProfile; 
    375396    } 
    376      
    377     private Collection<List<Event>> createRandomSequences(IStochasticProcess usageProfile, Properties properties) throws Exception { 
     397 
     398    private Collection<List<Event>> createRandomSequences(IStochasticProcess usageProfile, 
     399                                                          Properties properties) throws Exception 
     400    { 
    378401        int numberOfTestCases = Integer.parseInt(properties.getProperty("testcases.number")); 
    379402        int testCaseMinLength = Integer.parseInt(properties.getProperty("testcases.minlenth", "1")); 
    380         int testCaseMaxLength = Integer.parseInt(properties.getProperty("testcases.maxlenth", "100")); 
     403        int testCaseMaxLength = 
     404            Integer.parseInt(properties.getProperty("testcases.maxlenth", "100")); 
    381405        int maxIter = numberOfTestCases * 100; 
    382         RandomWalkGenerator testGenerator = new RandomWalkGenerator(numberOfTestCases, testCaseMinLength, testCaseMaxLength, true, maxIter); 
     406        RandomWalkGenerator testGenerator = 
     407            new RandomWalkGenerator(numberOfTestCases, testCaseMinLength, testCaseMaxLength, true, 
     408                                    maxIter); 
    383409        return testGenerator.generateTestSuite(usageProfile); 
    384410    } 
    385      
     411 
    386412    private void deleteFiles(File file) { 
    387413        if (file.exists()) { 
  • trunk/autoquest-plugin-uml/src/main/java/de/ugoe/cs/autoquest/plugin/uml/UMLUtils.java

    r1926 r1929  
    1515package de.ugoe.cs.autoquest.plugin.uml; 
    1616 
    17 import java.io.StringWriter; 
    18 import java.util.ArrayList; 
    1917import java.util.Collection; 
    2018import java.util.Collections; 
     
    3230import java.util.TreeSet; 
    3331 
    34 import javax.xml.transform.Transformer; 
    35 import javax.xml.transform.TransformerException; 
    36 import javax.xml.transform.TransformerFactory; 
    37 import javax.xml.transform.TransformerFactoryConfigurationError; 
    38 import javax.xml.transform.dom.DOMSource; 
    39 import javax.xml.transform.stream.StreamResult; 
    40  
    4132import org.eclipse.emf.common.util.EList; 
    42 import org.eclipse.emf.common.util.URI; 
    4333import org.eclipse.uml2.uml.Activity; 
    4434import org.eclipse.uml2.uml.ActivityEdge; 
     
    7464import org.eclipse.uml2.uml.Port; 
    7565import org.eclipse.uml2.uml.PrimitiveType; 
    76 import org.eclipse.uml2.uml.Profile; 
    7766import org.eclipse.uml2.uml.Property; 
    7867import org.eclipse.uml2.uml.Region; 
     
    8372import org.eclipse.uml2.uml.Transition; 
    8473import org.eclipse.uml2.uml.Trigger; 
    85 import org.eclipse.uml2.uml.Type; 
    8674import org.eclipse.uml2.uml.UMLPackage; 
     75import org.eclipse.uml2.uml.ValueSpecification; 
    8776import org.eclipse.uml2.uml.Vertex; 
    88 import org.w3c.dom.Attr; 
    89 import org.w3c.dom.Node; 
    90 import org.w3c.dom.NodeList; 
    9177 
    9278import de.ugoe.cs.autoquest.eventcore.Event; 
     
    11399    final static int MAX_MULTIPLICITY = 10; 
    114100 
    115     final public static URI UML_PRIMITIVE_TYPES_URI = URI 
    116         .createURI("pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml", true); 
    117  
    118101    /** 
    119102     * <p> 
     
    134117                                           String testContextName) 
    135118    { 
    136         final Profile utpProfile = model.getAppliedProfile("utp"); 
    137         final Stereotype utpTestComponent = (Stereotype) utpProfile.getOwnedMember("TestComponent"); 
    138         final Stereotype utpSUT = (Stereotype) utpProfile.getOwnedMember("SUT"); 
    139         final Stereotype utpTestContext = (Stereotype) utpProfile.getOwnedMember("TestContext"); 
    140  
    141119        int violationCount = 0; 
    142         Component testContext = fetchTestContext(model, utpTestContext, testContextName); 
     120        Component testContext = fetchTestContext(model, testContextName); 
    143121        if (testContext == null) { 
    144122            violationCount++; 
     
    186164        // fetch all SUTs and TestComponents 
    187165        HashMap<String, Property> properties = new HashMap<>(); 
    188         for (Property property : testContext.getAllAttributes()) { 
    189             if (property.getAppliedStereotypes().contains(utpSUT)) { 
    190                 properties.put(property.getName(), property); 
    191             } 
    192             else if (property.getType().getAppliedStereotypes().contains(utpTestComponent)) { 
    193                 properties.put(property.getName(), property); 
    194             } 
     166        for (Property property : fetchAllSUTProperties(testContext)) { 
     167            properties.put(property.getName(), property); 
     168        } 
     169        for (Property property : fetchAllTestComponentProperties(testContext)) { 
     170            properties.put(property.getName(), property); 
    195171        } 
    196172        Console.traceln(Level.INFO, "Found the following services in the TestConfiguration:"); 
     
    455431     *            test context found is used. 
    456432     */ 
    457     public static void createInteractionFromEventSequence(List<Event> sequence, 
    458                                                           Model model, 
    459                                                           String interactionName, 
    460                                                           String testContextName) 
     433    public static Interaction createInteractionFromEventSequence(List<Event> sequence, 
     434                                                                 Model model, 
     435                                                                 String interactionName, 
     436                                                                 String testContextName) 
    461437    { 
    462         final Profile utpProfile = model.getAppliedProfile("utp"); 
    463         final Stereotype utpTestCase = (Stereotype) utpProfile.getOwnedMember("TestCase"); 
    464         final Stereotype utpTestComponent = (Stereotype) utpProfile.getOwnedMember("TestComponent"); 
    465         final Stereotype utpSUT = (Stereotype) utpProfile.getOwnedMember("SUT"); 
    466         final Stereotype utpTestContext = (Stereotype) utpProfile.getOwnedMember("TestContext"); 
    467  
    468         // add UML Primitive types 
    469         // final UMLResource umlRes = (UMLResource) 
    470         // model.eResource().getResourceSet().getResource(UML_PRIMITIVE_TYPES_URI, true); 
    471         // model = (Model) umlRes.getContents().get(0); 
    472  
    473         Component testContext = fetchTestContext(model, utpTestContext, testContextName); 
     438        final Component testContext = fetchTestContext(model, testContextName); 
    474439        if (testContext == null) { 
    475440            throw new RuntimeException("Could not find any test context in the model"); 
    476441        } 
    477442 
    478         Operation operation = testContext.createOwnedOperation(interactionName, null, null); 
    479         operation.applyStereotype(utpTestCase); 
    480  
    481         Interaction interaction = 
     443        final Operation operation = testContext.createOwnedOperation(interactionName, null, null); 
     444        operation.applyStereotype(UTPUtils.getTestCaseStereotype(model)); 
     445 
     446        final Interaction interaction = 
    482447            (Interaction) testContext.createPackagedElement(interactionName + "_Impl", 
    483448                                                            UMLPackage.Literals.INTERACTION); 
     
    487452        Lifeline userLifeline = null; 
    488453 
    489         for (Property property : testContext.getAllAttributes()) { 
    490             if (property.getAppliedStereotypes().contains(utpSUT)) { 
    491                 String serviceName = property.getName(); 
    492                 Lifeline targetLifeline = interaction.createLifeline(serviceName); 
    493                 targetLifeline.setRepresents(property); 
    494             } 
    495             else if (property.getType().getAppliedStereotypes().contains(utpTestComponent)) { 
    496                 if (userLifeline != null) { 
    497                     throw new RuntimeException( 
    498                                                "TestContext must only have one TestComponent for the application of usage-based testing."); 
    499                 } 
    500                 userLifeline = interaction.createLifeline(property.getName()); 
    501                 userLifeline.setRepresents(property); 
    502             } 
    503         } 
     454        for (Property property : fetchAllSUTProperties(testContext)) { 
     455            String serviceName = property.getName(); 
     456            Lifeline targetLifeline = interaction.createLifeline(serviceName); 
     457            targetLifeline.setRepresents(property); 
     458        } 
     459        for (Property property : fetchAllTestComponentProperties(testContext)) { 
     460            // TODO check if this is still required 
     461            if (userLifeline != null) { 
     462                throw new RuntimeException( 
     463                                           "TestContext must only have one TestComponent for the application of usage-based testing."); 
     464            } 
     465            userLifeline = interaction.createLifeline(property.getName()); 
     466            userLifeline.setRepresents(property); 
     467        } 
     468 
    504469        if (userLifeline == null) { 
    505470            throw new RuntimeException("No TestComponent found, could not create user lifeline."); 
     
    580545                callRecvFragment.setCovered(msgTargetLifeline); 
    581546 
     547                // get connector 
     548                Connector connector = inferConnector(msgSourceLifeline, msgTargetLifeline); 
     549 
    582550                // create call 
    583                 Message callMessage = interaction.createMessage(methodName); 
     551                Message callMessage = interaction.createMessage(prefix + "call"); 
    584552                callMessage.setSignature(calledOperation); 
    585                 setMessageParameters(callMessage, calledOperation, event, prefix); 
    586                 callMessage.setConnector(inferConnector(msgSourceLifeline, msgTargetLifeline)); 
     553                setCallMessageParameters(callMessage, calledOperation, event, prefix); 
     554                callMessage.setConnector(connector); 
    587555                callMessage.setSendEvent(callSendFragment); 
    588556                callMessage.setReceiveEvent(callRecvFragment); 
     
    632600 
    633601                    // create reply 
    634                     Message replyMessage = interaction.createMessage(methodName + "_reply"); 
     602                    Message replyMessage = interaction.createMessage(prefix + "_reply"); 
    635603                    replyMessage.setMessageSort(MessageSort.REPLY_LITERAL); 
    636604                    replyMessage.setSignature(calledOperation); 
     605                    setReplyMessageParameters(replyMessage, calledOperation); 
     606                    replyMessage.setConnector(connector); 
    637607                    replyMessage.setSendEvent(replySendFragment); 
    638608                    replyMessage.setReceiveEvent(replyRecvFragment); 
     
    644614            } 
    645615        } 
     616        return interaction; 
    646617    } 
    647618 
     
    662633    { 
    663634        double usageScore = 0.0d; 
    664  
    665635        EList<InteractionFragment> interactionFragments = interaction.getFragments(); 
    666636        List<Event> eventSequence = new LinkedList<>(); 
    667637        eventSequence.add(Event.STARTEVENT); 
    668638        for (InteractionFragment interactionFragment : interactionFragments) { 
    669             if (interactionFragment.getName() != null && 
    670                 interactionFragment.getName().endsWith("_recvFragment")) // TODO must be more 
    671                                                                          // generic 
    672             { 
    673                 String serviceName = 
    674                     interactionFragment.getCovereds().get(0).getRepresents().getName().split("_")[0]; 
    675                 String methodName = "UNKNOWN"; 
    676                 if (interactionFragment instanceof MessageOccurrenceSpecification) { 
    677                     methodName = 
    678                         ((MessageOccurrenceSpecification) interactionFragment).getMessage() 
    679                             .getName(); 
    680                 } 
    681                 // eventSequence.add(new Event(new SimpleSOAPEventType(methodName, serviceName, "", 
    682                 // ))); // TODO 
    683                 // add 
    684                 // client 
    685                 // name 
     639            if (interactionFragment instanceof MessageOccurrenceSpecification) { 
     640                Message message = 
     641                    ((MessageOccurrenceSpecification) interactionFragment).getMessage(); 
     642                if (message.getReceiveEvent().equals(interactionFragment) && isCallMessage(message)) 
     643                { 
     644                    String clientName = 
     645                        ((MessageOccurrenceSpecification) message.getSendEvent()).getCovereds() 
     646                            .get(0).getName(); 
     647                    String serviceName = 
     648                        ((MessageOccurrenceSpecification) message.getReceiveEvent()).getCovereds() 
     649                            .get(0).getName(); 
     650                    String methodName = message.getSignature().getName(); 
     651                    eventSequence.add(new Event(new SimpleSOAPEventType(methodName, serviceName, 
     652                                                                        clientName, null))); 
     653                } 
    686654            } 
    687655        } 
     
    707675                                        String testContextName) 
    708676    { 
    709  
    710         final Profile utpProfile = model.getAppliedProfile("utp"); 
    711         final Stereotype utpTestCase = (Stereotype) utpProfile.getOwnedMember("TestCase"); 
    712         final Stereotype utpTestContext = (Stereotype) utpProfile.getOwnedMember("TestContext"); 
    713  
    714         Component testContext = fetchTestContext(model, utpTestContext, testContextName); 
     677        final Component testContext = fetchTestContext(model, testContextName); 
    715678        if (testContext == null) { 
    716679            throw new RuntimeException("Could not find any test context in the model"); 
     
    720683 
    721684        // first, we determine all test cases and calculate their usage scores 
     685        final Stereotype utpTestCase = UTPUtils.getTestCaseStereotype(model); 
    722686        for (Operation operation : testContext.getAllOperations()) { 
    723             if (operation.getAppliedStereotypes().contains(utpTestCase)) { 
     687            if (operation.getAppliedStereotypes().contains(utpTestCase) && 
     688                !operation.getMethods().isEmpty()) 
     689            { 
    724690                Interaction interaction = (Interaction) operation.getMethods().get(0); 
    725691                usageScoreMapUnsorted 
     
    764730        edge.setSource(currentOperationNode); 
    765731        edge.setTarget(finalNode); 
    766     } 
    767  
    768     /** 
    769      * From 
    770      * http://stackoverflow.com/questions/109383/how-to-sort-a-mapkey-value-on-the-values-in-java 
    771      * and adapted to do an inverse sorting 
    772      */ 
    773     public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) { 
    774         List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet()); 
    775         Collections.sort(list, new Comparator<Map.Entry<K, V>>() { 
    776             @Override 
    777             public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) { 
    778                 return -1 * (o1.getValue()).compareTo(o2.getValue()); 
    779             } 
    780         }); 
    781  
    782         Map<K, V> result = new LinkedHashMap<>(); 
    783         for (Map.Entry<K, V> entry : list) { 
    784             result.put(entry.getKey(), entry.getValue()); 
    785         } 
    786         return result; 
    787732    } 
    788733 
     
    862807    } 
    863808 
     809    /** 
     810     * <p> 
     811     * Fetches all realized interfaces from the type of a UML {@link Property} (i.e., 
     812     * property.getType()). If no interfaces are realized, an empty set is returned. 
     813     * </p> 
     814     *  
     815     * @param property 
     816     *            property, of the whose realized interfaces of the type are determined 
     817     * @return realized interfaces 
     818     */ 
    864819    private static Set<Interface> getRealizedInterfacesFromProperty(Property property) { 
    865820        return getRealizedInterfaceFromComponent((Component) property.getType()); 
    866821    } 
    867822 
    868     private static Set<Interface> getRealizedInterfaceFromComponent(Component comp) { 
     823    /** 
     824     * <p> 
     825     * Fetches all realized interfaces from a UML {@link Component}. If no interfaces are realized, 
     826     * an empty set is returned. 
     827     * </p> 
     828     *  
     829     * @param comp 
     830     *            component whose realized interfaces are determined 
     831     * @return realized interfaces 
     832     */ 
     833    private static Set<Interface> getRealizedInterfaceFromComponent(Component component) { 
    869834        Set<Interface> interfaces = new HashSet<>(); 
    870835        // Interface myInterface = null; 
    871         for (Property property : comp.getAttributes()) { 
     836        for (Property property : component.getAttributes()) { 
    872837            if (property instanceof Port) { 
    873838                Port port = (Port) property; 
     
    880845    } 
    881846 
    882     private static Component fetchTestContext(Package pkg, 
    883                                               Stereotype utpTestContext, 
    884                                               String testContextName) 
    885     { 
    886         List<Component> testContexts = fetchTestContextRecursively(pkg, utpTestContext); 
     847    /** 
     848     * <p> 
     849     * Determines searches within a {@link Package} for a component to which the UTP TestContext 
     850     * stereotype is applied. 
     851     * <ul> 
     852     * <li>If no testContextName is provided, the first test context found is returned.</li> 
     853     * <li>In case no test context is found, null is returned.</li> 
     854     * </p> 
     855     *  
     856     * @param pkg 
     857     *            package where the test context is being locked for 
     858     * @param testContextName 
     859     *            name of the test context; in case no test name is specified, use null and not the 
     860     *            empty String. 
     861     * @return {@link Component} to which the TestContext stereotype is applied 
     862     */ 
     863    private static Component fetchTestContext(final Package pkg, final String testContextName) { 
     864        List<Component> testContexts = fetchAllTestContexts(pkg); 
    887865        if (testContexts.isEmpty()) { 
    888866            return null; 
     
    901879    } 
    902880 
    903     private static List<Component> fetchTestContextRecursively(Package pkg, 
    904                                                                Stereotype utpTestContext) 
    905     { 
    906         List<Component> testContexts = new LinkedList<>(); 
     881    /** 
     882     * <p> 
     883     * Retrieves all UML {@link Component}s to which the UTP TestContext stereotype is applied from 
     884     * a package. This method calls itself recursively to include all components contained in 
     885     * sub-packages. 
     886     * </p> 
     887     * <p> 
     888     * In case no test context is found, an empty list is returned. 
     889     * </p> 
     890     *  
     891     * @param pkg 
     892     *            package from which the test contexts are retrieved 
     893     * @return {@link List} of test contexts 
     894     */ 
     895    private static List<Component> fetchAllTestContexts(final Package pkg) { 
     896        final Stereotype utpTestContext = UTPUtils.getTestContextStereotype(pkg.getModel()); 
     897        final List<Component> testContexts = new LinkedList<>(); 
    907898        for (Element element : pkg.getOwnedElements()) { 
    908899            if (element instanceof Package) { 
    909                 testContexts.addAll(fetchTestContextRecursively((Package) element, utpTestContext)); 
     900                testContexts.addAll(fetchAllTestContexts((Package) element)); 
    910901            } 
    911902            if (element instanceof Component && 
     
    920911    /** 
    921912     * <p> 
    922      * Infers connector between two lifelines. TODO: currently assumes only one connector between 
    923      * two lifelines possible. I need to make sure this assumption is valid. 
    924      * </p> 
    925      *  
    926      * @param userAttributes 
     913     * Retrieves all properties that represent a UTP TestComponent from a test context. 
     914     * </p> 
     915     *  
     916     * @param testContext 
     917     *            test context from which the properties are retrieved 
     918     * @return properties that represent test components 
     919     */ 
     920    private static Set<Property> fetchAllTestComponentProperties(final Component testContext) { 
     921        // fetch all SUTs and TestComponents 
     922        final Stereotype utpTestComponent = 
     923            UTPUtils.getTestComponentStereotype(testContext.getModel()); 
     924        final Set<Property> properties = new HashSet<>(); 
     925        for (Property property : testContext.getAllAttributes()) { 
     926            if (property.getType().getAppliedStereotypes().contains(utpTestComponent)) { 
     927                properties.add(property); 
     928            } 
     929        } 
     930        return properties; 
     931    } 
     932 
     933    /** 
     934     * <p> 
     935     * Retrieves all properties that represent a UTP SUT from a test context. 
     936     * </p> 
     937     *  
     938     * @param testContext 
     939     *            test context from which the properties are retrieved 
     940     * @return properties that represent the SUTs 
     941     */ 
     942    private static Set<Property> fetchAllSUTProperties(final Component testContext) { 
     943        // fetch all SUTs and TestComponents 
     944        final Stereotype utpSUT = UTPUtils.getSUTStereotype(testContext.getModel()); 
     945        final Set<Property> properties = new HashSet<>(); 
     946        for (Property property : testContext.getAllAttributes()) { 
     947            if (property.getAppliedStereotypes().contains(utpSUT)) { 
     948                properties.add(property); 
     949            } 
     950        } 
     951        return properties; 
     952    } 
     953 
     954    /** 
     955     * <p> 
     956     * Infers connector between two lifelines. 
     957     * </p> 
     958     * <p> 
     959     * TODO: Currently assumes only one connector between two lifelines possible. This assumption is 
     960     * invalid as soon as there are two ports that connect the same two properties. 
     961     * </p> 
     962     *  
     963     * @param msgSourceLifeline 
     964     *            source lifeline of the message 
    927965     * @param targetAttributes 
     966     *            target lifeline of the message 
    928967     */ 
    929968    private static Connector inferConnector(Lifeline msgSourceLifeline, Lifeline msgTargetLifeline) 
     
    955994    } 
    956995 
     996    /** 
     997     * <p> 
     998     * Creates a map that maps the interfaces to the properties, i.e., services that they are 
     999     * represented by. 
     1000     * </p> 
     1001     * <p> 
     1002     * TODO: currently assumes that each interfaces is only realized by one property 
     1003     * </p> 
     1004     *  
     1005     * @param model 
     1006     *            model for which the interface->service map is created 
     1007     * @return the map 
     1008     */ 
    9571009    private static Map<Interface, String> createInterfaceServiceMap(Model model) { 
    9581010        Map<Interface, String> interfaceServiceMap = new HashMap<>(); 
    959         final Profile utpProfile = model.getModel().getAppliedProfile("utp"); 
    960         final Stereotype utpTestComponent = (Stereotype) utpProfile.getOwnedMember("TestComponent"); 
    961         final Stereotype utpSUT = (Stereotype) utpProfile.getOwnedMember("SUT"); 
    962         final Stereotype utpTestContext = (Stereotype) utpProfile.getOwnedMember("TestContext"); 
    963         List<Component> testContexts = 
    964             fetchTestContextRecursively(model.getModel(), utpTestContext); 
     1011        List<Component> testContexts = fetchAllTestContexts(model.getModel()); 
    9651012        for (Component testContext : testContexts) { 
    966             for (Property property : testContext.getAllAttributes()) { 
    967                 if (property.getAppliedStereotypes().contains(utpSUT) || 
    968                     property.getType().getAppliedStereotypes().contains(utpTestComponent)) 
    969                 { 
    970                     for (Interface intface : getRealizedInterfacesFromProperty(property)) { 
    971                         interfaceServiceMap.put(intface, property.getName()); 
    972                     } 
     1013            for (Property property : fetchAllSUTProperties(testContext)) { 
     1014                for (Interface intface : getRealizedInterfacesFromProperty(property)) { 
     1015                    interfaceServiceMap.put(intface, property.getName()); 
     1016                } 
     1017            } 
     1018            for (Property property : fetchAllTestComponentProperties(testContext)) { 
     1019                for (Interface intface : getRealizedInterfacesFromProperty(property)) { 
     1020                    interfaceServiceMap.put(intface, property.getName()); 
    9731021                } 
    9741022            } 
     
    9771025    } 
    9781026 
    979     private static void setMessageParameters(Message callMessage, 
    980                                              Operation calledOperation, 
    981                                              Event event, 
    982                                              String prefix) 
     1027    /** 
     1028     * <p> 
     1029     * Sets values for the parameters of a call message. The values are, if possible, inferred from 
     1030     * the event that is provided. 
     1031     * </p> 
     1032     *  
     1033     * @param callMessage 
     1034     *            call message for which the parameters are set 
     1035     * @param calledOperation 
     1036     *            operation that is called by the message 
     1037     * @param event 
     1038     *            event that provides the parameters; in case of null, default values are assumed 
     1039     * @param prefix 
     1040     *            prefix of the call message; used to create good warnings and debugging information 
     1041     */ 
     1042    private static void setCallMessageParameters(Message callMessage, 
     1043                                                 Operation calledOperation, 
     1044                                                 Event event, 
     1045                                                 String prefix) 
    9831046    { 
    9841047        org.w3c.dom.Element requestBody = SOAPUtils.getSoapRequestBodyFromEvent(event); 
     1048        Package instSpecPkg = null; 
    9851049 
    9861050        // Set parameters of operation 
    9871051        for (Parameter param : calledOperation.getOwnedParameters()) { 
     1052            if (instSpecPkg == null) { 
     1053                instSpecPkg = getOrCreateInstanceSpecificationPackage(param.getModel(), event); 
     1054            } 
     1055 
     1056            String path = calledOperation.getName() + ":" + param.getName(); 
    9881057            Expression argument = 
    9891058                (Expression) callMessage.createArgument(param.getName(), param.getType(), 
    9901059                                                        UMLPackage.Literals.EXPRESSION); 
    9911060 
    992             if (param.getDirection() == ParameterDirectionKind.IN_LITERAL || 
    993                 param.getDirection() == ParameterDirectionKind.INOUT_LITERAL) 
    994             { 
     1061            if (isInParameter(param)) { 
    9951062                if (param.getType() instanceof DataType) { 
    9961063                    List<org.w3c.dom.Element> paramNodes = 
    997                         getMatchingChildNode((DataType) param.getType(), requestBody); 
    998                     for (org.w3c.dom.Element paramNode : paramNodes) { 
     1064                        SOAPUtils.getMatchingChildNode(param.getType().getName(), requestBody); 
     1065                    int multiplicityChosen = paramNodes.size(); 
     1066 
     1067                    if (multiplicityChosen == 0 && param.getLower() > 0) { 
     1068                        Console.traceln(Level.WARNING, 
     1069                                        "required attribute not found in SOAP message: " + path); 
     1070                        Console 
     1071                            .traceln(Level.WARNING, 
     1072                                     "setting default values for this attribute and all its children"); 
     1073                        Console.traceln(Level.FINE, "XML structure of path:" + StringTools.ENDLINE + 
     1074                            SOAPUtils.getSerialization(requestBody)); 
     1075                        multiplicityChosen = param.getLower(); 
     1076                    } 
     1077                    for (int i = 0; i < multiplicityChosen; i++) { 
     1078                        org.w3c.dom.Element paramNode = null; 
     1079                        if (!paramNodes.isEmpty()) { 
     1080                            paramNode = paramNodes.get(i); 
     1081                        } 
    9991082                        InstanceSpecification instSpec = 
    1000                             createInstanceSpecification((DataType) param.getType(), event, prefix, 
    1001                                                         paramNode, ""); 
     1083                            createInstanceSpecification((DataType) param.getType(), instSpecPkg, 
     1084                                                        prefix, paramNode, path); 
    10021085 
    10031086                        InstanceValue value = 
     
    10091092                } 
    10101093                else if (param.getType() instanceof PrimitiveType) { 
    1011                     createOperandPrimitiveType(param, argument, requestBody); 
     1094                    createOperandPrimitiveType(param, argument, requestBody, path); 
    10121095                } 
    10131096            } 
     
    10191102    } 
    10201103 
     1104    /** 
     1105     * <p> 
     1106     * Creates an {@link InstanceSpecification} for a data type in the given package. The values are 
     1107     * inferred, if possible, from the DOM node. The prefix and the path are used for naming the 
     1108     * instance specification and to provide good warnings and debug information in case of 
     1109     * problems. 
     1110     * </p> 
     1111     *  
     1112     * @param type 
     1113     *            DataType for which the {@link InstanceSpecification} is created 
     1114     * @param pkg 
     1115     *            package in which the {@link InstanceSpecification} is created 
     1116     * @param prefix 
     1117     *            prefix used for naming the {@link InstanceSpecification} 
     1118     * @param currentNode 
     1119     *            node of a DOM from which values are inferred 
     1120     * @param path 
     1121     *            used for warnings and debug information 
     1122     * @return {@link InstanceSpecification} for the given type 
     1123     */ 
    10211124    private static InstanceSpecification createInstanceSpecification(DataType type, 
    1022                                                                      Event event, 
     1125                                                                     Package pkg, 
    10231126                                                                     String prefix, 
    10241127                                                                     org.w3c.dom.Element currentNode, 
     
    10281131            path = type.getName(); 
    10291132        } 
    1030         // System.out.println(path); 
    1031         String pkgUBTInstSpecs = "UBT_InstanceSpecifications"; 
    1032         Model model = type.getModel(); 
    1033         Package ubtInstSpecPkg = (Package) model.getOwnedMember(pkgUBTInstSpecs); 
    1034         if (ubtInstSpecPkg == null) { 
    1035             ubtInstSpecPkg = 
    1036                 (Package) type.getModel().createPackagedElement(pkgUBTInstSpecs, 
    1037                                                                 UMLPackage.Literals.PACKAGE); 
    1038         } 
    1039         String serviceName = SOAPUtils.getServiceNameFromEvent(event); 
    1040         Package serviceInstSpecPkg = (Package) ubtInstSpecPkg.getOwnedMember(serviceName); 
    1041         if (serviceInstSpecPkg == null) { 
    1042             serviceInstSpecPkg = 
    1043                 (Package) ubtInstSpecPkg.createPackagedElement(serviceName, 
    1044                                                                UMLPackage.Literals.PACKAGE); 
    1045         } 
    10461133 
    10471134        InstanceSpecification instSpec = 
    1048             (InstanceSpecification) serviceInstSpecPkg.createPackagedElement(prefix + "instspec_" + 
    1049                 type.getName(), UMLPackage.Literals.INSTANCE_SPECIFICATION); 
     1135            (InstanceSpecification) pkg 
     1136                .createPackagedElement(prefix + "instspec_" + type.getName(), 
     1137                                       UMLPackage.Literals.INSTANCE_SPECIFICATION); 
    10501138        instSpec.getClassifiers().add(type); 
    10511139        for (Property prop : type.getAllAttributes()) { 
     
    10571145                int multiplicityChosen = 0; 
    10581146                if (currentNode != null) { 
    1059                     attributeNodes = getMatchingChildNode(prop, currentNode); 
     1147                    attributeNodes = SOAPUtils.getMatchingChildNode(prop.getName(), currentNode); 
    10601148                    multiplicityChosen = attributeNodes.size(); 
    10611149                } 
     
    10861174                        (InstanceValue) slot.createValue(prop.getName() + "_" + i, prop.getType(), 
    10871175                                                         UMLPackage.Literals.INSTANCE_VALUE); 
    1088                     value.setInstance(createInstanceSpecification((DataType) prop.getType(), event, 
     1176                    value.setInstance(createInstanceSpecification((DataType) prop.getType(), pkg, 
    10891177                                                                  prefix, attributeNode, path + 
    10901178                                                                      "." + prop.getName())); 
     
    11001188    } 
    11011189 
     1190    /** 
     1191     * <p> 
     1192     * Gets or creates a {@link Package} for {@link InstanceSpecification} created by the 
     1193     * usage-based testing. Each service gets its own sub-package within a package called 
     1194     * UBT_InstanceSpecifications. " 
     1195     * </p> 
     1196     *  
     1197     * @param model 
     1198     *            model in which the package is generated 
     1199     * @param event 
     1200     *            event from which the service name is inferred 
     1201     * @return package for the {@link InstanceSpecification}s 
     1202     */ 
     1203    private static Package getOrCreateInstanceSpecificationPackage(Model model, Event event) { 
     1204        String pkgUBTInstSpecs = "UBT_InstanceSpecifications"; 
     1205        Package ubtInstSpecPkg = (Package) model.getOwnedMember(pkgUBTInstSpecs); 
     1206        if (ubtInstSpecPkg == null) { 
     1207            ubtInstSpecPkg = 
     1208                (Package) model.createPackagedElement(pkgUBTInstSpecs, UMLPackage.Literals.PACKAGE); 
     1209        } 
     1210        String serviceName = SOAPUtils.getServiceNameFromEvent(event); 
     1211        Package serviceInstSpecPkg = (Package) ubtInstSpecPkg.getOwnedMember(serviceName); 
     1212        if (serviceInstSpecPkg == null) { 
     1213            serviceInstSpecPkg = 
     1214                (Package) ubtInstSpecPkg.createPackagedElement(serviceName, 
     1215                                                               UMLPackage.Literals.PACKAGE); 
     1216        } 
     1217        return serviceInstSpecPkg; 
     1218    } 
     1219 
     1220    /** 
     1221     * <p> 
     1222     * Creates an operand that defines a {@link PrimitiveType}. 
     1223     * </p> 
     1224     * <p> 
     1225     * TODO: Currently does nothing in case of multiplicity 0. I am not sure if, in that case, one 
     1226     * has to define LiteralNull instead. 
     1227     * </p> 
     1228     *  
     1229     * @param param 
     1230     *            parameter for which the operand is created 
     1231     * @param argument 
     1232     *            argument to which the operand is added 
     1233     * @param currentNode 
     1234     *            DOM node from which is value for the operand is inferred 
     1235     * @param path 
     1236     *            used for warnings and debug information 
     1237     */ 
    11021238    private static void createOperandPrimitiveType(Parameter param, 
    11031239                                                   Expression argument, 
    1104                                                    org.w3c.dom.Element currentNode) 
     1240                                                   org.w3c.dom.Element currentNode, 
     1241                                                   String path) 
    11051242    { 
    1106         if ("String".equals(param.getType().getName())) { 
    1107             LiteralString spec = 
    1108                 (LiteralString) argument.createOperand(param.getName(), null, 
    1109                                                        UMLPackage.Literals.LITERAL_STRING); 
    1110             spec.setValue("foobar"); // TODO needs to be real value 
    1111         } 
    1112         else if ("Integer".equals(param.getType().getName())) { 
    1113             LiteralInteger spec = 
    1114                 (LiteralInteger) argument.createOperand(param.getName(), null, 
    1115                                                         UMLPackage.Literals.LITERAL_INTEGER); 
    1116             spec.setValue(42); // TODO needs to be real value 
    1117         } 
    1118         else if ("Boolean".equals(param.getType().getName())) { 
    1119             LiteralBoolean spec = 
    1120                 (LiteralBoolean) argument.createOperand(param.getName(), null, 
    1121                                                         UMLPackage.Literals.LITERAL_BOOLEAN); 
    1122             spec.setValue(true); // TODO needs to be real value 
    1123         } 
    1124         else if ("Real".equals(param.getType().getName())) { 
    1125             LiteralReal spec = 
    1126                 (LiteralReal) argument.createOperand(param.getName(), null, 
    1127                                                      UMLPackage.Literals.LITERAL_REAL); 
    1128             spec.setValue(3.14); // TODO needs to be real value 
    1129         } 
    1130     } 
    1131  
     1243        List<String> attributeValues = SOAPUtils.getValuesFromElement(param.getName(), currentNode); 
     1244 
     1245        if (attributeValues.isEmpty()) { 
     1246            if (param.getLower() == 0) { 
     1247                // ignoring optional attribute 
     1248                return; 
     1249            } 
     1250            else { 
     1251                if (currentNode != null) { 
     1252                    Console.traceln(Level.WARNING, 
     1253                                    "required attribute not found in SOAP message: " + path + "." + 
     1254                                        param.getName()); 
     1255                    Console.traceln(Level.WARNING, "setting default values for this attribute"); 
     1256                    Console.traceln(Level.FINE, "XML structure of path:" + StringTools.ENDLINE + 
     1257                        SOAPUtils.getSerialization(currentNode)); 
     1258                } 
     1259                attributeValues.add(null); 
     1260            } 
     1261        } 
     1262        for (String attributeValue : attributeValues) { 
     1263            if ("String".equals(param.getType().getName())) { 
     1264                LiteralString spec = 
     1265                    (LiteralString) argument.createOperand(param.getName(), null, 
     1266                                                           UMLPackage.Literals.LITERAL_STRING); 
     1267                if (attributeValue != null) { 
     1268                    spec.setValue(attributeValue); 
     1269                } 
     1270                else { 
     1271                    spec.setValue("foobar"); 
     1272                } 
     1273            } 
     1274            else if ("Integer".equals(param.getType().getName())) { 
     1275                LiteralInteger spec = 
     1276                    (LiteralInteger) argument.createOperand(param.getName(), null, 
     1277                                                            UMLPackage.Literals.LITERAL_INTEGER); 
     1278                if (attributeValue != null) { 
     1279                    spec.setValue(Integer.parseInt(attributeValue)); 
     1280                } 
     1281                else { 
     1282                    spec.setValue(42); 
     1283                } 
     1284            } 
     1285            else if ("Boolean".equals(param.getType().getName())) { 
     1286                LiteralBoolean spec = 
     1287                    (LiteralBoolean) argument.createOperand(param.getName(), null, 
     1288                                                            UMLPackage.Literals.LITERAL_BOOLEAN); 
     1289                if (attributeValue != null) { 
     1290                    spec.setValue(Boolean.parseBoolean(attributeValue)); 
     1291                } 
     1292                else { 
     1293                    spec.setValue(true); 
     1294                } 
     1295            } 
     1296            else if ("Real".equals(param.getType().getName())) { 
     1297                LiteralReal spec = 
     1298                    (LiteralReal) argument.createOperand(param.getName(), null, 
     1299                                                         UMLPackage.Literals.LITERAL_REAL); 
     1300                if (attributeValue != null) { 
     1301                    spec.setValue(Double.parseDouble(attributeValue)); 
     1302                } 
     1303                else { 
     1304                    spec.setValue(3.14); 
     1305                } 
     1306            } 
     1307        } 
     1308    } 
     1309 
     1310    /** 
     1311     * <p> 
     1312     * Creates a {@link Slot} in an {@link InstanceSpecification} for a primitive type. 
     1313     * </p> 
     1314     *  
     1315     * @param instSpec 
     1316     *            instance specification to which the slot is added 
     1317     * @param prop 
     1318     *            property that describes the slot 
     1319     * @param currentNode 
     1320     *            DOM node from which is value for the slot is inferred 
     1321     * @param path 
     1322     *            used for warnings and debug information 
     1323     */ 
    11321324    private static void createSlotPrimitiveType(InstanceSpecification instSpec, 
    11331325                                                Property prop, 
     
    11351327                                                String path) 
    11361328    { 
    1137         List<String> attributeValues = getPrimitiveTypeValuesFromElement(prop, currentNode); 
     1329        List<String> attributeValues = SOAPUtils.getValuesFromElement(prop.getName(), currentNode); 
    11381330 
    11391331        if (attributeValues.isEmpty()) { 
     
    11481340                                        prop.getName()); 
    11491341                    Console.traceln(Level.WARNING, "setting default values for this attribute"); 
    1150                 } 
    1151                 Console.traceln(Level.FINE, "XML structure of path:" + StringTools.ENDLINE + 
    1152                     SOAPUtils.getSerialization(currentNode)); 
     1342                    Console.traceln(Level.FINE, "XML structure of path:" + StringTools.ENDLINE + 
     1343                        SOAPUtils.getSerialization(currentNode)); 
     1344                } 
    11531345                attributeValues.add(null); 
    11541346            } 
     
    11981390                } 
    11991391                else { 
    1200                     value.setValue(3.14); // TODO needs to be real value 
     1392                    value.setValue(3.14); 
    12011393                } 
    12021394            } 
     
    12091401    } 
    12101402 
    1211     // TODO comment 
    1212     private static List<org.w3c.dom.Element> getMatchingChildNode(Type type, 
    1213                                                                   org.w3c.dom.Element parentNode) 
    1214     { 
    1215         return getMachingChildNode(type.getName(), parentNode); 
    1216     } 
    1217  
    1218     // TODO comment 
    1219     private static List<org.w3c.dom.Element> getMatchingChildNode(Property prop, 
    1220                                                                   org.w3c.dom.Element parentNode) 
    1221     { 
    1222         return getMachingChildNode(prop.getName(), parentNode); 
    1223     } 
    1224  
    1225     // TODO comment 
    1226     private static List<org.w3c.dom.Element> getMachingChildNode(String typeNameRaw, 
    1227                                                                  org.w3c.dom.Element parentNode) 
    1228     { 
    1229         List<org.w3c.dom.Element> matchingNodes = new ArrayList<>(); 
    1230         Node parameterNode = null; 
    1231         if (parentNode != null) { 
    1232             NodeList parameterNodes = parentNode.getChildNodes(); 
    1233             String[] typeNameSplit = typeNameRaw.split(":"); 
    1234             String typeName = typeNameSplit[typeNameSplit.length - 1]; 
    1235             for (int i = 0; i < parameterNodes.getLength(); i++) { 
    1236                 parameterNode = parameterNodes.item(i); 
    1237                 if (parameterNode.getNodeType() == Node.ELEMENT_NODE) { 
    1238                     String[] parameterNodeSplit = parameterNode.getNodeName().split(":"); 
    1239                     String parameterNodeName = parameterNodeSplit[parameterNodeSplit.length - 1]; 
    1240                     if (typeName.equals(parameterNodeName)) { 
    1241                         matchingNodes.add((org.w3c.dom.Element) parameterNode); 
    1242                     } 
    1243                 } 
    1244             } 
    1245             /* 
    1246              * if( !matchingSOAPFound) { Console.traceln(Level.WARNING, 
    1247              * "could not look up name of parameter in SOAP request: " + typeName); if( 
    1248              * elementCount==0 ) { Console.traceln(Level.INFO, "\tno parameters found"); } else { 
    1249              * Console.traceln(Level.INFO, "\tparameters found:"); for( int i=0 ; 
    1250              * i<parameterNodes.getLength(); i++ ) { if( 
    1251              * parameterNodes.item(i).getNodeType()==Node.ELEMENT_NODE ) { 
    1252              * Console.traceln(Level.INFO, "\t\t" + parameterNodes.item(i).getNodeName()); } } } 
    1253              * Console.traceln(Level.WARNING, 
    1254              * "using dummy values for this parameter (and nested values) instead"); } 
    1255              */ 
    1256         } 
    1257         return matchingNodes; 
    1258     } 
    1259  
    1260     // TODO 
    1261     private static List<String> getPrimitiveTypeValuesFromElement(Property prop, 
    1262                                                                   org.w3c.dom.Element currentNode) 
    1263     { 
    1264         List<String> attributeValues = new LinkedList<>(); 
    1265  
    1266         if (currentNode != null) { 
    1267             // first check attributes of the node 
    1268             Attr attribute = currentNode.getAttributeNode(prop.getName()); 
    1269             if (attribute != null) { 
    1270                 attributeValues.add(attribute.getValue()); 
     1403    /** 
     1404     * <p> 
     1405     * Sets values for the parameters of a reply message. The values are, all LiterealNull and to 
     1406     * the INOUT, OUT and REPLY parameters, the UTP stereotype LiteralAny is applied. 
     1407     * </p> 
     1408     *  
     1409     * @param replyMessage 
     1410     *            reply message for which the parameters are set 
     1411     * @param calledOperation 
     1412     *            operation that is replied for by the message 
     1413     */ 
     1414    private static void setReplyMessageParameters(Message replyMessage, Operation calledOperation) { 
     1415        for (Parameter param : calledOperation.getOwnedParameters()) { 
     1416            Expression argument = 
     1417                (Expression) replyMessage.createArgument(param.getName(), param.getType(), 
     1418                                                         UMLPackage.Literals.EXPRESSION); 
     1419            if (isOutParameter(param)) { 
     1420                ValueSpecification operand = 
     1421                    argument.createOperand(null, param.getType(), UMLPackage.Literals.LITERAL_NULL); 
     1422                operand.applyStereotype(UTPUtils.getLiteralAnyStereotype(param.getModel())); 
    12711423            } 
    12721424            else { 
    1273                 // now check elements 
    1274                 List<org.w3c.dom.Element> elements = getMatchingChildNode(prop, currentNode); 
    1275                 for (org.w3c.dom.Element element : elements) { 
    1276                     attributeValues.add(element.getTextContent()); 
    1277                 } 
    1278             } 
    1279         } 
    1280  
    1281         return attributeValues; 
    1282     } 
    1283  
     1425                argument.createOperand(null, param.getType(), UMLPackage.Literals.LITERAL_NULL); 
     1426            } 
     1427        } 
     1428    } 
     1429 
     1430    /** 
     1431     * <p> 
     1432     * Checks if a parameter has the direction IN or INOUT 
     1433     * </p> 
     1434     *  
     1435     * @param parameter 
     1436     *            parameter that is checked 
     1437     * @return true if the direction is IN or INOUT; false otherwise 
     1438     */ 
     1439    private static boolean isInParameter(Parameter parameter) { 
     1440        return parameter.getDirection() == ParameterDirectionKind.IN_LITERAL || 
     1441            parameter.getDirection() == ParameterDirectionKind.INOUT_LITERAL; 
     1442    } 
     1443 
     1444    /** 
     1445     * <p> 
     1446     * Checks if a parameter has the direction RETURN, OUT or INOUT 
     1447     * </p> 
     1448     *  
     1449     * @param parameter 
     1450     *            parameter that is checked 
     1451     * @return true if the direction is RETURN, OUT, or INOUT; false otherwise 
     1452     */ 
     1453    private static boolean isOutParameter(Parameter parameter) { 
     1454        return parameter.getDirection() == ParameterDirectionKind.RETURN_LITERAL || 
     1455            parameter.getDirection() == ParameterDirectionKind.OUT_LITERAL || 
     1456            parameter.getDirection() == ParameterDirectionKind.INOUT_LITERAL; 
     1457    } 
     1458 
     1459    /** 
     1460     * <p> 
     1461     * Checks if the {@link MessageSort} of a message is a call message, i.e., ASYNCH_CALL or 
     1462     * SYNCH_CALL. 
     1463     * </p> 
     1464     *  
     1465     * @param message 
     1466     *            message that is checked 
     1467     * @return true if the message is a call message; false otherwise 
     1468     */ 
     1469    private static boolean isCallMessage(Message message) { 
     1470        if (message == null) { 
     1471            return false; 
     1472        } 
     1473        MessageSort msgSort = message.getMessageSort(); 
     1474        return msgSort == MessageSort.ASYNCH_CALL_LITERAL || 
     1475            msgSort == MessageSort.SYNCH_CALL_LITERAL; 
     1476    } 
     1477 
     1478    /** 
     1479     * <p> 
     1480     * inverse-sorts the values of a map. Has been adapted from <a href= 
     1481     * "http://stackoverflow.com/questions/109383/how-to-sort-a-mapkey-value-on-the-values-in-java" 
     1482     * >this</a> StackOverflow post. 
     1483     * </p> 
     1484     *  
     1485     * @param map 
     1486     *            map whose values are sorted 
     1487     * @return sorted version of the map 
     1488     */ 
     1489    private static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) { 
     1490        // TODO possibly move to another class 
     1491        List<Map.Entry<K, V>> list = new LinkedList<>(map.entrySet()); 
     1492        Collections.sort(list, new Comparator<Map.Entry<K, V>>() { 
     1493            @Override 
     1494            public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) { 
     1495                return -1 * (o1.getValue()).compareTo(o2.getValue()); 
     1496            } 
     1497        }); 
     1498 
     1499        Map<K, V> result = new LinkedHashMap<>(); 
     1500        for (Map.Entry<K, V> entry : list) { 
     1501            result.put(entry.getKey(), entry.getValue()); 
     1502        } 
     1503        return result; 
     1504    } 
    12841505} 
Note: See TracChangeset for help on using the changeset viewer.