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

Last change on this file since 1926 was 1926, checked in by sherbold, 9 years ago
  • UMLUtils now add real values to test cases based on the observations in the event sequence
  • test updated
  • Property svn:mime-type set to text/plain
File size: 58.5 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.plugin.uml;
16
17import java.io.StringWriter;
18import java.util.ArrayList;
19import java.util.Collection;
20import java.util.Collections;
21import java.util.Comparator;
22import java.util.HashMap;
23import java.util.HashSet;
24import java.util.Iterator;
25import java.util.LinkedHashMap;
26import java.util.LinkedList;
27import java.util.List;
28import java.util.Map;
29import java.util.Map.Entry;
30import java.util.logging.Level;
31import java.util.Set;
32import java.util.TreeSet;
33
34import javax.xml.transform.Transformer;
35import javax.xml.transform.TransformerException;
36import javax.xml.transform.TransformerFactory;
37import javax.xml.transform.TransformerFactoryConfigurationError;
38import javax.xml.transform.dom.DOMSource;
39import javax.xml.transform.stream.StreamResult;
40
41import org.eclipse.emf.common.util.EList;
42import org.eclipse.emf.common.util.URI;
43import org.eclipse.uml2.uml.Activity;
44import org.eclipse.uml2.uml.ActivityEdge;
45import org.eclipse.uml2.uml.ActivityNode;
46import org.eclipse.uml2.uml.CallConcurrencyKind;
47import org.eclipse.uml2.uml.CallEvent;
48import org.eclipse.uml2.uml.CallOperationAction;
49import org.eclipse.uml2.uml.Comment;
50import org.eclipse.uml2.uml.Component;
51import org.eclipse.uml2.uml.Connector;
52import org.eclipse.uml2.uml.ConnectorEnd;
53import org.eclipse.uml2.uml.DataType;
54import org.eclipse.uml2.uml.Element;
55import org.eclipse.uml2.uml.Expression;
56import org.eclipse.uml2.uml.InstanceSpecification;
57import org.eclipse.uml2.uml.InstanceValue;
58import org.eclipse.uml2.uml.Interaction;
59import org.eclipse.uml2.uml.InteractionFragment;
60import org.eclipse.uml2.uml.Interface;
61import org.eclipse.uml2.uml.Lifeline;
62import org.eclipse.uml2.uml.LiteralBoolean;
63import org.eclipse.uml2.uml.LiteralInteger;
64import org.eclipse.uml2.uml.LiteralReal;
65import org.eclipse.uml2.uml.LiteralString;
66import org.eclipse.uml2.uml.Message;
67import org.eclipse.uml2.uml.MessageOccurrenceSpecification;
68import org.eclipse.uml2.uml.MessageSort;
69import org.eclipse.uml2.uml.Model;
70import org.eclipse.uml2.uml.Operation;
71import org.eclipse.uml2.uml.Package;
72import org.eclipse.uml2.uml.Parameter;
73import org.eclipse.uml2.uml.ParameterDirectionKind;
74import org.eclipse.uml2.uml.Port;
75import org.eclipse.uml2.uml.PrimitiveType;
76import org.eclipse.uml2.uml.Profile;
77import org.eclipse.uml2.uml.Property;
78import org.eclipse.uml2.uml.Region;
79import org.eclipse.uml2.uml.Relationship;
80import org.eclipse.uml2.uml.Slot;
81import org.eclipse.uml2.uml.StateMachine;
82import org.eclipse.uml2.uml.Stereotype;
83import org.eclipse.uml2.uml.Transition;
84import org.eclipse.uml2.uml.Trigger;
85import org.eclipse.uml2.uml.Type;
86import org.eclipse.uml2.uml.UMLPackage;
87import org.eclipse.uml2.uml.Vertex;
88import org.w3c.dom.Attr;
89import org.w3c.dom.Node;
90import org.w3c.dom.NodeList;
91
92import de.ugoe.cs.autoquest.eventcore.Event;
93import de.ugoe.cs.autoquest.plugin.http.SOAPUtils;
94import de.ugoe.cs.autoquest.plugin.http.eventcore.SOAPEventType;
95import de.ugoe.cs.autoquest.plugin.http.eventcore.SimpleSOAPEventType;
96import de.ugoe.cs.autoquest.plugin.uml.eventcore.UMLTransitionType;
97import de.ugoe.cs.autoquest.usageprofiles.IStochasticProcess;
98import de.ugoe.cs.util.StringTools;
99import de.ugoe.cs.util.console.Console;
100
101/**
102 * <p>
103 * Utilities for working with UML.
104 * </p>
105 *
106 * @author Steffen Herbold
107 */
108public class UMLUtils {
109
110    /**
111     * In case a multiplicity is defined as *, this value defines the highest one that can be picked
112     */
113    final static int MAX_MULTIPLICITY = 10;
114
115    final public static URI UML_PRIMITIVE_TYPES_URI = URI
116        .createURI("pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml", true);
117
118    /**
119     * <p>
120     * Method for checking if the information in a usage journal can be mapped to the SUT model. In
121     * case this is not possible, the violations are reported.
122     * </p>
123     *
124     * @param sequences
125     *            sequences of the usage journal
126     * @param model
127     *            SUT model that is validated
128     * @param testContextName
129     *            name of the test context to be used; if null, the first test context found is used
130     * @return number of violations
131     */
132    public static int validateModelWithLog(Collection<List<Event>> sequences,
133                                           Model model,
134                                           String testContextName)
135    {
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
141        int violationCount = 0;
142        Component testContext = fetchTestContext(model, utpTestContext, testContextName);
143        if (testContext == null) {
144            violationCount++;
145            if (testContextName == null) {
146                Console.traceln(Level.SEVERE, "Could not find any TestContext in the model.");
147
148            }
149            else {
150                Console.traceln(Level.SEVERE, "Could not find TestContext in the model: " +
151                    testContextName);
152            }
153            Console
154                .traceln(Level.SEVERE,
155                         "Hint: Check if you have applied the TestContext stereotype correctly in the model.");
156            Console.traceln(Level.SEVERE, "Aborting");
157            return violationCount;
158        }
159
160        // Create list of unique methods calls
161        HashMap<String, Set<String>> calledMethods = new HashMap<>();
162        for (List<Event> sequence : sequences) {
163            for (Event event : sequence) {
164                String serviceName = SOAPUtils.getServiceNameFromEvent(event);
165                String calledMethod = SOAPUtils.getCalledMethodFromEvent(event);
166                if (serviceName != null) {
167                    Set<String> curCalledMethods = calledMethods.get(serviceName);
168                    if (curCalledMethods == null) {
169                        curCalledMethods = new TreeSet<>();
170                        calledMethods.put(serviceName, curCalledMethods);
171                    }
172                    curCalledMethods.add(calledMethod);
173                }
174            }
175        }
176
177        Console.traceln(Level.INFO,
178                        "Found the following services and operations in the usage data: ");
179        for (Entry<String, Set<String>> entry : calledMethods.entrySet()) {
180            Console.traceln(Level.INFO, "\tService \"" + entry.getKey() + "\": ");
181            for (String method : entry.getValue()) {
182                Console.traceln(Level.INFO, "\t\t" + method);
183            }
184        }
185
186        // fetch all SUTs and TestComponents
187        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            }
195        }
196        Console.traceln(Level.INFO, "Found the following services in the TestConfiguration:");
197        for (Entry<String, Property> entry : properties.entrySet()) {
198            Console.traceln(Level.INFO, "\t" + entry.getKey());
199        }
200
201        for (Entry<String, Set<String>> entry : calledMethods.entrySet()) {
202            String serviceName = entry.getKey();
203            Console.traceln(Level.INFO, "Checking service: " + serviceName);
204            Set<String> methodNames = entry.getValue();
205            Property property = properties.get(serviceName);
206            if (property == null) {
207                violationCount++;
208                Console.traceln(Level.SEVERE, "\tCould not find property for service: " +
209                    serviceName);
210                Console
211                    .traceln(Level.SEVERE,
212                             "\tHint: Check service name map and/or model if the service is present and spelled correctly.");
213                Console
214                    .traceln(Level.SEVERE,
215                             "\tHint: Check if the SUT/TestComponent stereotype has been applied correctly in this TestContext.");
216            }
217            else {
218                Set<Interface> interfaces = getRealizedInterfacesFromProperty(property);
219                if (interfaces.isEmpty()) {
220                    violationCount++;
221                    Console
222                        .traceln(Level.SEVERE,
223                                 "\tCould not find any interfaces implementing the property for service: " +
224                                     serviceName);
225                    Console
226                        .traceln(Level.SEVERE,
227                                 "\tHint: Check if the property correctly realizes the interfaces in the model.");
228                }
229                else {
230                    Console.traceln(Level.INFO,
231                                    "\tFound the following realized interfaces for the service \"" +
232                                        serviceName + "\": ");
233                    for (Interface intface : interfaces) {
234                        Console.traceln(Level.INFO, "\t" + intface.getName());
235                        for (Operation operation : intface.getAllOperations()) {
236                            Console.traceln(Level.INFO, "\t\t" + operation.getName());
237                        }
238                    }
239                    for (String methodName : methodNames) {
240                        boolean methodFound = false;
241                        for (Interface intface : interfaces) {
242                            if (getOperationFromName(intface.getOperations(), methodName) != null) {
243                                // interface found
244                                Console.traceln(Level.INFO, "\tMethod " + methodName +
245                                    " found in interface " + intface.getName());
246                                methodFound = true;
247                            }
248                        }
249                        if (!methodFound) {
250                            violationCount++;
251                            Console.traceln(Level.SEVERE, "\tCould not find operation: " +
252                                methodName);
253                        }
254                    }
255                }
256            }
257        }
258        return violationCount;
259    }
260
261    /**
262     * <p>
263     * Creates a sequence of events with {@link UMLTransitionType} as event type from a given
264     * sequence of events with the {@link SOAPEventType} or {@link SimpleSOAPEventType}, by matching
265     * the sequences to a state machine.
266     * </p>
267     *
268     * @param sequence
269     *            SOAP sequences
270     * @param stateMachine
271     *            the state machine
272     * @return create UML sequences
273     */
274    public static List<Event> createUMLTransitionSequence(List<Event> sequence,
275                                                          StateMachine stateMachine)
276    {
277        System.out.println("foo");
278        List<List<Transition>> matchingSequences =
279            determineMatchingTransitionSequences(sequence, stateMachine);
280        System.out.println(matchingSequences.size());
281
282        if (matchingSequences.size() != 1) {
283            throw new RuntimeException("no unique match found; " + matchingSequences.size() +
284                " matches");
285        }
286        List<Event> umlEventSequence = new LinkedList<>();
287        for (Transition transition : matchingSequences.get(0)) {
288            umlEventSequence.add(new Event(new UMLTransitionType(transition)));
289        }
290        return umlEventSequence;
291    }
292
293    /**
294     * <p>
295     * Uses a sequences of events with the {@link UMLTransitionType} to determine the transition
296     * probabilities for the state machine.
297     * </p>
298     *
299     * @param sequences
300     *            UML sequences
301     * @param stateMachine
302     *            state machine to be converted to a usage profile
303     */
304    public static void convertStateMachineToUsageProfile(Collection<List<Event>> sequences,
305                                                         StateMachine stateMachine)
306    {
307        // create state->outgoings hashmap
308        Map<Vertex, Map<Transition, Integer>> stateMap = new HashMap<>();
309        for (Region region : stateMachine.getRegions()) {
310            for (Vertex state : region.getSubvertices()) {
311                stateMap.put(state, new HashMap<Transition, Integer>());
312            }
313        }
314
315        // create counters for each transition
316        for (List<Event> sequence : sequences) {
317            for (Event event : sequence) {
318                if (event.getType() instanceof UMLTransitionType) {
319                    Transition transition = ((UMLTransitionType) event.getType()).getTransition();
320                    Map<Transition, Integer> transitionMap = stateMap.get(transition.getSource());
321                    Integer value = transitionMap.get(transition);
322                    if (value == null) {
323                        value = 0;
324                    }
325                    transitionMap.put(transition, value + 1);
326                }
327                else {
328                    throw new RuntimeException(
329                                               "Wrong event type. Only UMLTransitionType supported but was: " +
330                                                   event.getType().getClass().getName());
331                }
332            }
333        }
334
335        // calculate probabilities
336        for (Region region : stateMachine.getRegions()) {
337            for (Vertex state : region.getSubvertices()) {
338                Map<Transition, Integer> transitionMap = stateMap.get(state);
339                int totalCount = 0;
340                for (Entry<Transition, Integer> entry : transitionMap.entrySet()) {
341                    totalCount += entry.getValue();
342                }
343                if (totalCount != 0) {
344                    for (Transition transition : state.getOutgoings()) {
345                        double prob = 0.0d;
346                        if (transitionMap.containsKey(transition)) {
347                            prob = ((double) transitionMap.get(transition)) / totalCount;
348                        }
349                        Comment comment = transition.createOwnedComment();
350                        comment.setBody("" + prob);
351                    }
352                }
353                else {
354                    // system has never been in this state, all transitions equally likely
355                    int numOutgoings = state.getOutgoings().size();
356                    for (Transition transition : state.getOutgoings()) {
357                        Comment comment = transition.createOwnedComment();
358                        comment.setBody("" + (1.0d / numOutgoings));
359                    }
360                }
361            }
362        }
363    }
364
365    /**
366     * <p>
367     * Determines all matching {@link Transition} sequences in a state machine for a given sequence
368     * of SOAP events.
369     * </p>
370     *
371     * @param sequence
372     *            SOAP sequence
373     * @param stateMachine
374     *            the state machine
375     * @return all matching {@link Transition} sequences
376     */
377    public static List<List<Transition>> determineMatchingTransitionSequences(List<Event> sequence,
378                                                                              StateMachine stateMachine)
379    {
380        EList<Region> regions = stateMachine.getRegions();
381        EList<Vertex> states = null;
382        for (Region region : regions) {
383            if (states == null) {
384                states = region.getSubvertices();
385            }
386            else {
387                states.addAll(region.getSubvertices());
388            }
389        }
390        List<Transition> allTransitions = new LinkedList<>();
391        for (Vertex state : states) {
392            allTransitions.addAll(state.getOutgoings());
393        }
394
395        List<List<Transition>> matchingSequences = null;
396        List<Transition> currentTransitions = null;
397
398        // first, we try to find a single unique transition that we can match using the method name
399        for (Iterator<Event> eventIterator = sequence.iterator(); eventIterator.hasNext();) {
400            Event event = eventIterator.next();
401            System.out.println(event);
402            System.out.println(matchingSequences);
403            if (matchingSequences == null) {
404                matchingSequences = new LinkedList<>();
405                List<Transition> initialMatches = matchTransitions(allTransitions, event);
406                for (Transition transition : initialMatches) {
407                    List<Transition> candidate = new LinkedList<>();
408                    candidate.add(transition);
409                    matchingSequences.add(candidate);
410                }
411                currentTransitions = initialMatches;
412            }
413            else {
414                List<List<Transition>> nextMatchingSequences = new LinkedList<>();
415                List<Transition> nextCurrentTransitions = new LinkedList<>();
416                Iterator<Transition> currentTransitionIterator = currentTransitions.iterator();
417                Iterator<List<Transition>> currentMatchingSequencesIterator =
418                    matchingSequences.iterator();
419                while (currentTransitionIterator.hasNext()) {
420                    Transition currentTransition = currentTransitionIterator.next();
421                    List<Transition> currentMatch = currentMatchingSequencesIterator.next();
422
423                    List<Transition> matches =
424                        matchTransitions(currentTransition.getTarget().getOutgoings(), event);
425                    if (matches.isEmpty()) {
426                        throw new RuntimeException("no matches found");
427                    }
428                    for (Transition matchingTransition : matches) {
429                        List<Transition> candidate = new LinkedList<>(currentMatch);
430                        candidate.add(matchingTransition);
431                        nextMatchingSequences.add(candidate);
432                        nextCurrentTransitions.add(matchingTransition);
433                    }
434                }
435                matchingSequences = nextMatchingSequences;
436                currentTransitions = nextCurrentTransitions;
437            }
438        }
439        return matchingSequences;
440    }
441
442    /**
443     * <p>
444     * Extends a given model with an interaction that represents an observed sequence.
445     * </p>
446     *
447     * @param sequence
448     *            sequence that is added as sequence diagram
449     * @param model
450     *            UML model to which the interaction is added
451     * @param interactionName
452     *            name of the interaction
453     * @param testContextName
454     *            Name of the test context that should be used. If this value is null, the first
455     *            test context found is used.
456     */
457    public static void createInteractionFromEventSequence(List<Event> sequence,
458                                                          Model model,
459                                                          String interactionName,
460                                                          String testContextName)
461    {
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);
474        if (testContext == null) {
475            throw new RuntimeException("Could not find any test context in the model");
476        }
477
478        Operation operation = testContext.createOwnedOperation(interactionName, null, null);
479        operation.applyStereotype(utpTestCase);
480
481        Interaction interaction =
482            (Interaction) testContext.createPackagedElement(interactionName + "_Impl",
483                                                            UMLPackage.Literals.INTERACTION);
484        operation.getMethods().add(interaction);
485
486        // create lifelines
487        Lifeline userLifeline = null;
488
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        }
504        if (userLifeline == null) {
505            throw new RuntimeException("No TestComponent found, could not create user lifeline.");
506        }
507        if (interaction.getLifelines().size() < 2) {
508            throw new RuntimeException("Fewer than two lifelines created. No SUT found.");
509        }
510
511        int i = 0;
512        for (Event event : sequence) {
513            if (!(event.equals(Event.STARTEVENT) || event.equals(Event.ENDEVENT))) {
514                String serviceName = SOAPUtils.getServiceNameFromEvent(event);
515                String methodName = SOAPUtils.getCalledMethodFromEvent(event);
516                String clientName = SOAPUtils.getClientNameFromEvent(event);
517                String prefix = interactionName + ":" + i + ":" + methodName + "_";
518                // determine lifelines
519                Lifeline msgTargetLifeline;
520                Lifeline msgSourceLifeline;
521
522                msgSourceLifeline = interaction.getLifeline(clientName);
523                msgTargetLifeline = interaction.getLifeline(serviceName);
524
525                if (msgSourceLifeline == null) {
526                    throw new RuntimeException(
527                                               "Error creating message: could not determine source lifeline for component: " +
528                                                   clientName);
529                }
530                if (msgTargetLifeline == null) {
531                    throw new RuntimeException(
532                                               "Error creating message: could not determine target lifeline for component: " +
533                                                   serviceName);
534                }
535                // determine correct target interface
536                Set<Interface> targetInterfaces =
537                    getRealizedInterfacesFromProperty((Property) msgTargetLifeline.getRepresents());
538                if (targetInterfaces.isEmpty()) {
539                    throw new RuntimeException("no interface associated with the property " +
540                        msgTargetLifeline.getRepresents().getName());
541                }
542                Interface targetInterface = null;
543                for (Interface intface : targetInterfaces) {
544                    if (getOperationFromName(intface.getOperations(), methodName) != null) {
545                        // interface found
546                        targetInterface = intface;
547                        break;
548                    }
549                }
550                if (targetInterface == null) {
551                    StringBuilder errStrBuilder = new StringBuilder();
552                    errStrBuilder
553                        .append("Error creating message: operation not found in the implementing interfaces (");
554                    Iterator<Interface> iter = targetInterfaces.iterator();
555                    while (iter.hasNext()) {
556                        String interfaceName = iter.next().getName();
557                        errStrBuilder.append(interfaceName);
558                        if (iter.hasNext()) {
559                            errStrBuilder.append(",");
560                        }
561                        else {
562                            errStrBuilder.append("): " + methodName);
563                        }
564                    }
565                    throw new RuntimeException(errStrBuilder.toString());
566                }
567
568                Operation calledOperation =
569                    getOperationFromName(targetInterface.getOperations(), methodName);
570
571                // setup for both SYNCH and ASYNCH calls
572                MessageOccurrenceSpecification callSendFragment =
573                    (MessageOccurrenceSpecification) interaction.createFragment(prefix +
574                        "callSendFragment", UMLPackage.Literals.MESSAGE_OCCURRENCE_SPECIFICATION);
575                MessageOccurrenceSpecification callRecvFragment =
576                    (MessageOccurrenceSpecification) interaction.createFragment(prefix +
577                        "callRecvFragment", UMLPackage.Literals.MESSAGE_OCCURRENCE_SPECIFICATION);
578
579                callSendFragment.setCovered(msgSourceLifeline);
580                callRecvFragment.setCovered(msgTargetLifeline);
581
582                // create call
583                Message callMessage = interaction.createMessage(methodName);
584                callMessage.setSignature(calledOperation);
585                setMessageParameters(callMessage, calledOperation, event, prefix);
586                callMessage.setConnector(inferConnector(msgSourceLifeline, msgTargetLifeline));
587                callMessage.setSendEvent(callSendFragment);
588                callMessage.setReceiveEvent(callRecvFragment);
589                callSendFragment.setMessage(callMessage);
590                callRecvFragment.setMessage(callMessage);
591
592                boolean asynch = false;
593                if (calledOperation.getConcurrency() == CallConcurrencyKind.CONCURRENT_LITERAL) {
594                    asynch = true;
595                }
596                if (asynch) {
597                    // Create ASYNCH call
598                    callMessage.setMessageSort(MessageSort.ASYNCH_CALL_LITERAL);
599                }
600                else {
601                    // SYNCH call
602                    callMessage.setMessageSort(MessageSort.SYNCH_CALL_LITERAL);
603
604                    // setup reply and behavior execution specifications
605                    MessageOccurrenceSpecification replySendFragment =
606                        (MessageOccurrenceSpecification) interaction
607                            .createFragment(prefix + "replySendFragment",
608                                            UMLPackage.Literals.MESSAGE_OCCURRENCE_SPECIFICATION);
609                    MessageOccurrenceSpecification replyRecvFragment =
610                        (MessageOccurrenceSpecification) interaction
611                            .createFragment(prefix + "replyRecvFragment",
612                                            UMLPackage.Literals.MESSAGE_OCCURRENCE_SPECIFICATION);
613
614                    replySendFragment.setCovered(msgTargetLifeline);
615                    replyRecvFragment.setCovered(msgSourceLifeline);
616
617                    /*
618                     * BehaviorExecutionSpecification sourceBehaviorExecutionSpecification =
619                     * (BehaviorExecutionSpecification) interaction .createFragment(":" + methodName
620                     * + "_sourceBhvExecSpec",
621                     * UMLPackage.Literals.BEHAVIOR_EXECUTION_SPECIFICATION);
622                     * BehaviorExecutionSpecification targetBehaviorExecutionSpecification =
623                     * (BehaviorExecutionSpecification) interaction .createFragment(":" + methodName
624                     * + "_targetBhvExecSpec",
625                     * UMLPackage.Literals.BEHAVIOR_EXECUTION_SPECIFICATION);
626                     *
627                     * sourceBehaviorExecutionSpecification.setStart(callSendFragment);
628                     * sourceBehaviorExecutionSpecification.setFinish(replyRecvFragment);
629                     * targetBehaviorExecutionSpecification.setStart(callRecvFragment);
630                     * targetBehaviorExecutionSpecification.setFinish(replySendFragment);
631                     */
632
633                    // create reply
634                    Message replyMessage = interaction.createMessage(methodName + "_reply");
635                    replyMessage.setMessageSort(MessageSort.REPLY_LITERAL);
636                    replyMessage.setSignature(calledOperation);
637                    replyMessage.setSendEvent(replySendFragment);
638                    replyMessage.setReceiveEvent(replyRecvFragment);
639                    replySendFragment.setMessage(replyMessage);
640                    replyRecvFragment.setMessage(replyMessage);
641                }
642
643                i++;
644            }
645        }
646    }
647
648    /**
649     * <p>
650     * Calculates the usage score of an interaction as the logsum of the event probabilities
651     * multiplied with the length of the interaction.
652     * </p>
653     *
654     * @param interaction
655     *            interaction for which the score is calculated
656     * @param usageProfile
657     *            usage profile used for the calculation
658     * @return calculated usage score
659     */
660    public static double calculateUsageScore(Interaction interaction,
661                                             IStochasticProcess usageProfile)
662    {
663        double usageScore = 0.0d;
664
665        EList<InteractionFragment> interactionFragments = interaction.getFragments();
666        List<Event> eventSequence = new LinkedList<>();
667        eventSequence.add(Event.STARTEVENT);
668        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
686            }
687        }
688        eventSequence.add(Event.ENDEVENT);
689        double prob = usageProfile.getLogSum(eventSequence);
690        usageScore = eventSequence.size() * prob;
691
692        return usageScore;
693    }
694
695    /**
696     * <p>
697     * Extends the given model with an activity for usage-based scheduling of the test cases.
698     * </p>
699     *
700     * @param model
701     *            model to be extended
702     * @param usageProfile
703     *            usage profile used as foundation
704     */
705    public static void createScheduling(Model model,
706                                        IStochasticProcess usageProfile,
707                                        String testContextName)
708    {
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);
715        if (testContext == null) {
716            throw new RuntimeException("Could not find any test context in the model");
717        }
718
719        Map<Operation, Double> usageScoreMapUnsorted = new HashMap<>();
720
721        // first, we determine all test cases and calculate their usage scores
722        for (Operation operation : testContext.getAllOperations()) {
723            if (operation.getAppliedStereotypes().contains(utpTestCase)) {
724                Interaction interaction = (Interaction) operation.getMethods().get(0);
725                usageScoreMapUnsorted
726                    .put(operation, calculateUsageScore(interaction, usageProfile));
727            }
728        }
729        Map<Operation, Double> usageScoreMapSorted = sortByValue(usageScoreMapUnsorted);
730
731        // now we create the scheduling
732        Activity schedulingActivity =
733            (Activity) testContext.createOwnedBehavior("UsageBasedScheduling",
734                                                       UMLPackage.Literals.ACTIVITY);
735        testContext.setClassifierBehavior(schedulingActivity);
736
737        ActivityNode startNode =
738            schedulingActivity.createOwnedNode("final", UMLPackage.Literals.INITIAL_NODE);
739        ActivityNode finalNode =
740            schedulingActivity.createOwnedNode("final", UMLPackage.Literals.ACTIVITY_FINAL_NODE);
741
742        ActivityNode currentOperationNode = startNode;
743
744        for (Entry<Operation, Double> entry : usageScoreMapSorted.entrySet()) {
745            Operation operation = entry.getKey();
746            CallOperationAction nextOperationNode =
747                (CallOperationAction) schedulingActivity
748                    .createOwnedNode(operation.getName(), UMLPackage.Literals.CALL_OPERATION_ACTION);
749            nextOperationNode.setOperation(operation);
750
751            ActivityEdge edge =
752                schedulingActivity.createEdge(currentOperationNode.getName() + "_to_" +
753                    nextOperationNode.getName(), UMLPackage.Literals.CONTROL_FLOW);
754            edge.setSource(currentOperationNode);
755            edge.setTarget(nextOperationNode);
756
757            currentOperationNode = nextOperationNode;
758        }
759
760        ActivityEdge edge =
761            schedulingActivity
762                .createEdge(currentOperationNode.getName() + "_to_" + finalNode.getName(),
763                            UMLPackage.Literals.CONTROL_FLOW);
764        edge.setSource(currentOperationNode);
765        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;
787    }
788
789    /**
790     * <p>
791     * Fetches an operation using only its name from a list of operations. Returns the first match
792     * found or null if no match is found.
793     * </p>
794     *
795     * @param operations
796     *            list of operations
797     * @param name
798     *            name of the operation
799     * @return first matching operation; null if no match is found
800     */
801    private static Operation getOperationFromName(EList<Operation> operations, String name) {
802        if (name == null) {
803            throw new IllegalArgumentException("name of the operation must not be null");
804        }
805        if (operations != null) {
806            for (Operation operation : operations) {
807                if (operation.getName() != null && operation.getName().equals(name)) {
808                    return operation;
809                }
810            }
811        }
812        return null;
813    }
814
815    /**
816     * <p>
817     * Determines which transitions match a given {@link SOAPEventType}.
818     * </p>
819     *
820     * @param transitions
821     *            the transitions
822     * @param eventType
823     *            the SOAP event
824     * @return matching transitions
825     */
826    private static List<Transition> matchTransitions(List<Transition> transitions, Event event) {
827        String eventService = SOAPUtils.getServiceNameFromEvent(event);
828        String eventMethod = SOAPUtils.getCalledMethodFromEvent(event);
829
830        Map<Interface, String> interfaceServiceMap =
831            createInterfaceServiceMap(transitions.get(0).getModel());
832
833        List<Transition> matching = new LinkedList<>();
834        for (Transition transition : transitions) {
835            EList<Trigger> triggers = transition.getTriggers();
836            if (triggers.size() == 1) {
837                if (triggers.get(0).getEvent() instanceof CallEvent) {
838                    CallEvent callEvent = (CallEvent) triggers.get(0).getEvent();
839                    String transitionMethod = callEvent.getOperation().getName();
840
841                    Interface intface = callEvent.getOperation().getInterface();
842                    for (Relationship relationship : intface.getRelationships()) {
843                        for (Element element : relationship.getRelatedElements()) {
844                            if (element instanceof Component) {
845
846                            }
847                        }
848                    }
849
850                    String transitionService =
851                        interfaceServiceMap.get(callEvent.getOperation().getInterface());
852                    if (eventMethod.equals(transitionMethod) &&
853                        eventService.equals(transitionService))
854                    {
855                        matching.add(transition);
856                    }
857                }
858            }
859
860        }
861        return matching;
862    }
863
864    private static Set<Interface> getRealizedInterfacesFromProperty(Property property) {
865        return getRealizedInterfaceFromComponent((Component) property.getType());
866    }
867
868    private static Set<Interface> getRealizedInterfaceFromComponent(Component comp) {
869        Set<Interface> interfaces = new HashSet<>();
870        // Interface myInterface = null;
871        for (Property property : comp.getAttributes()) {
872            if (property instanceof Port) {
873                Port port = (Port) property;
874                if (!port.isConjugated()) {
875                    interfaces.addAll(port.getProvideds());
876                }
877            }
878        }
879        return interfaces;
880    }
881
882    private static Component fetchTestContext(Package pkg,
883                                              Stereotype utpTestContext,
884                                              String testContextName)
885    {
886        List<Component> testContexts = fetchTestContextRecursively(pkg, utpTestContext);
887        if (testContexts.isEmpty()) {
888            return null;
889        }
890        if (testContextName != null) {
891            for (Component testContext : testContexts) {
892                if (testContextName.equals(testContext.getName())) {
893                    return testContext;
894                }
895            }
896            return null;
897        }
898        else {
899            return testContexts.get(0);
900        }
901    }
902
903    private static List<Component> fetchTestContextRecursively(Package pkg,
904                                                               Stereotype utpTestContext)
905    {
906        List<Component> testContexts = new LinkedList<>();
907        for (Element element : pkg.getOwnedElements()) {
908            if (element instanceof Package) {
909                testContexts.addAll(fetchTestContextRecursively((Package) element, utpTestContext));
910            }
911            if (element instanceof Component &&
912                element.getAppliedStereotypes().contains(utpTestContext))
913            {
914                testContexts.add((Component) element);
915            }
916        }
917        return testContexts;
918    }
919
920    /**
921     * <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
927     * @param targetAttributes
928     */
929    private static Connector inferConnector(Lifeline msgSourceLifeline, Lifeline msgTargetLifeline)
930    {
931        EList<Property> userAttributes =
932            ((Component) msgSourceLifeline.getRepresents().getType()).getAttributes();
933        EList<Property> targetAttributes =
934            ((Component) msgTargetLifeline.getRepresents().getType()).getAttributes();
935        for (Property userAttribute : userAttributes) {
936            if (userAttribute instanceof Port) {
937                EList<ConnectorEnd> userEnds = ((Port) userAttribute).getEnds();
938                for (ConnectorEnd userEnd : userEnds) {
939                    Connector userConnector = (Connector) userEnd.eContainer();
940                    for (Property targetAttribute : targetAttributes) {
941                        if (targetAttribute instanceof Port) {
942                            EList<ConnectorEnd> targetEnds = ((Port) targetAttribute).getEnds();
943                            for (ConnectorEnd targetEnd : targetEnds) {
944                                Connector targetConnector = (Connector) targetEnd.eContainer();
945                                if (targetConnector == userConnector) {
946                                    return targetConnector;
947                                }
948                            }
949                        }
950                    }
951                }
952            }
953        }
954        return null;
955    }
956
957    private static Map<Interface, String> createInterfaceServiceMap(Model model) {
958        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);
965        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                    }
973                }
974            }
975        }
976        return interfaceServiceMap;
977    }
978
979    private static void setMessageParameters(Message callMessage,
980                                             Operation calledOperation,
981                                             Event event,
982                                             String prefix)
983    {
984        org.w3c.dom.Element requestBody = SOAPUtils.getSoapRequestBodyFromEvent(event);
985
986        // Set parameters of operation
987        for (Parameter param : calledOperation.getOwnedParameters()) {
988            Expression argument =
989                (Expression) callMessage.createArgument(param.getName(), param.getType(),
990                                                        UMLPackage.Literals.EXPRESSION);
991
992            if (param.getDirection() == ParameterDirectionKind.IN_LITERAL ||
993                param.getDirection() == ParameterDirectionKind.INOUT_LITERAL)
994            {
995                if (param.getType() instanceof DataType) {
996                    List<org.w3c.dom.Element> paramNodes =
997                        getMatchingChildNode((DataType) param.getType(), requestBody);
998                    for (org.w3c.dom.Element paramNode : paramNodes) {
999                        InstanceSpecification instSpec =
1000                            createInstanceSpecification((DataType) param.getType(), event, prefix,
1001                                                        paramNode, "");
1002
1003                        InstanceValue value =
1004                            (InstanceValue) argument
1005                                .createOperand(null, param.getType(),
1006                                               UMLPackage.Literals.INSTANCE_VALUE);
1007                        value.setInstance(instSpec);
1008                    }
1009                }
1010                else if (param.getType() instanceof PrimitiveType) {
1011                    createOperandPrimitiveType(param, argument, requestBody);
1012                }
1013            }
1014            else {
1015                // set literalNull for out and return parameters
1016                argument.createOperand(null, param.getType(), UMLPackage.Literals.LITERAL_NULL);
1017            }
1018        }
1019    }
1020
1021    private static InstanceSpecification createInstanceSpecification(DataType type,
1022                                                                     Event event,
1023                                                                     String prefix,
1024                                                                     org.w3c.dom.Element currentNode,
1025                                                                     String path)
1026    {
1027        if ("".equals(path)) {
1028            path = type.getName();
1029        }
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        }
1046
1047        InstanceSpecification instSpec =
1048            (InstanceSpecification) serviceInstSpecPkg.createPackagedElement(prefix + "instspec_" +
1049                type.getName(), UMLPackage.Literals.INSTANCE_SPECIFICATION);
1050        instSpec.getClassifiers().add(type);
1051        for (Property prop : type.getAllAttributes()) {
1052            if (prop.getType() instanceof PrimitiveType) {
1053                createSlotPrimitiveType(instSpec, prop, currentNode, path);
1054            }
1055            else if (prop.getType() instanceof DataType) {
1056                List<org.w3c.dom.Element> attributeNodes = null;
1057                int multiplicityChosen = 0;
1058                if (currentNode != null) {
1059                    attributeNodes = getMatchingChildNode(prop, currentNode);
1060                    multiplicityChosen = attributeNodes.size();
1061                }
1062
1063                if (multiplicityChosen == 0 && prop.getLower() > 0) {
1064                    if (currentNode != null) {
1065                        Console.traceln(Level.WARNING,
1066                                        "required attribute not found in SOAP message: " + path +
1067                                            "." + prop.getName());
1068                        Console
1069                            .traceln(Level.WARNING,
1070                                     "setting default values for this attribute and all its children");
1071                        Console.traceln(Level.FINE, "XML structure of path:" + StringTools.ENDLINE +
1072                            SOAPUtils.getSerialization(currentNode));
1073                    }
1074                    multiplicityChosen = prop.getLower();
1075                }
1076                for (int i = 0; i < multiplicityChosen; i++) {
1077                    org.w3c.dom.Element attributeNode = null;
1078                    if (attributeNodes != null && !attributeNodes.isEmpty()) {
1079                        attributeNode = attributeNodes.get(i);
1080                    }
1081
1082                    Slot slot = instSpec.createSlot();
1083                    slot.setDefiningFeature(prop);
1084
1085                    InstanceValue value =
1086                        (InstanceValue) slot.createValue(prop.getName() + "_" + i, prop.getType(),
1087                                                         UMLPackage.Literals.INSTANCE_VALUE);
1088                    value.setInstance(createInstanceSpecification((DataType) prop.getType(), event,
1089                                                                  prefix, attributeNode, path +
1090                                                                      "." + prop.getName()));
1091                }
1092            }
1093            else {
1094                Console.traceln(Level.SEVERE, "property neither DataType nor PrimitiveType: " +
1095                    prop.getType());
1096                // TODO abort?
1097            }
1098        }
1099        return instSpec;
1100    }
1101
1102    private static void createOperandPrimitiveType(Parameter param,
1103                                                   Expression argument,
1104                                                   org.w3c.dom.Element currentNode)
1105    {
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
1132    private static void createSlotPrimitiveType(InstanceSpecification instSpec,
1133                                                Property prop,
1134                                                org.w3c.dom.Element currentNode,
1135                                                String path)
1136    {
1137        List<String> attributeValues = getPrimitiveTypeValuesFromElement(prop, currentNode);
1138
1139        if (attributeValues.isEmpty()) {
1140            if (prop.getLower() == 0) {
1141                // ignoring optional attribute
1142                return;
1143            }
1144            else {
1145                if (currentNode != null) {
1146                    Console.traceln(Level.WARNING,
1147                                    "required attribute not found in SOAP message: " + path + "." +
1148                                        prop.getName());
1149                    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));
1153                attributeValues.add(null);
1154            }
1155        }
1156        for (String attributeValue : attributeValues) {
1157            Slot slot = instSpec.createSlot();
1158            slot.setDefiningFeature(prop);
1159            if ("String".equals(prop.getType().getName())) {
1160                LiteralString value =
1161                    (LiteralString) slot.createValue(prop.getName(), null,
1162                                                     UMLPackage.Literals.LITERAL_STRING);
1163                if (attributeValue != null) {
1164                    value.setValue(attributeValue);
1165                }
1166                else {
1167                    value.setValue("foobar");
1168                }
1169            }
1170            else if ("Integer".equals(prop.getType().getName())) {
1171                LiteralInteger value =
1172                    (LiteralInteger) slot.createValue(prop.getName(), null,
1173                                                      UMLPackage.Literals.LITERAL_INTEGER);
1174                if (attributeValue != null) {
1175                    value.setValue(Integer.parseInt(attributeValue));
1176                }
1177                else {
1178                    value.setValue(42);
1179                }
1180            }
1181            else if ("Boolean".equals(prop.getType().getName())) {
1182                LiteralBoolean value =
1183                    (LiteralBoolean) slot.createValue(prop.getName(), null,
1184                                                      UMLPackage.Literals.LITERAL_BOOLEAN);
1185                if (attributeValue != null) {
1186                    value.setValue(Boolean.parseBoolean(attributeValue));
1187                }
1188                else {
1189                    value.setValue(true);
1190                }
1191            }
1192            else if ("Real".equals(prop.getType().getName())) {
1193                LiteralReal value =
1194                    (LiteralReal) slot.createValue(prop.getName(), null,
1195                                                   UMLPackage.Literals.LITERAL_REAL);
1196                if (attributeValue != null) {
1197                    value.setValue(Double.parseDouble(attributeValue));
1198                }
1199                else {
1200                    value.setValue(3.14); // TODO needs to be real value
1201                }
1202            }
1203            else {
1204                Console.traceln(Level.SEVERE, "could not create literal for primitive type: " +
1205                    prop.getType().getName());
1206                // TODO abort?
1207            }
1208        }
1209    }
1210
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());
1271            }
1272            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
1284}
Note: See TracBrowser for help on using the repository browser.