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

Last change on this file since 2008 was 2008, checked in by sherbold, 9 years ago
  • moved logic for the creation of Interactions from event sequences from the UML utils to a separate class
  • Property svn:mime-type set to text/plain
File size: 30.3 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.plugin.uml;
16
17import java.util.Iterator;
18import java.util.List;
19import java.util.Set;
20import java.util.logging.Level;
21
22import org.apache.commons.lang.mutable.MutableInt;
23import org.eclipse.uml2.uml.CallConcurrencyKind;
24import org.eclipse.uml2.uml.Component;
25import org.eclipse.uml2.uml.Connector;
26import org.eclipse.uml2.uml.DataType;
27import org.eclipse.uml2.uml.InstanceSpecification;
28import org.eclipse.uml2.uml.InstanceValue;
29import org.eclipse.uml2.uml.Interaction;
30import org.eclipse.uml2.uml.Interface;
31import org.eclipse.uml2.uml.Lifeline;
32import org.eclipse.uml2.uml.LiteralBoolean;
33import org.eclipse.uml2.uml.LiteralInteger;
34import org.eclipse.uml2.uml.LiteralReal;
35import org.eclipse.uml2.uml.LiteralString;
36import org.eclipse.uml2.uml.Message;
37import org.eclipse.uml2.uml.MessageOccurrenceSpecification;
38import org.eclipse.uml2.uml.MessageSort;
39import org.eclipse.uml2.uml.Model;
40import org.eclipse.uml2.uml.Operation;
41import org.eclipse.uml2.uml.Package;
42import org.eclipse.uml2.uml.Parameter;
43import org.eclipse.uml2.uml.PrimitiveType;
44import org.eclipse.uml2.uml.Property;
45import org.eclipse.uml2.uml.Slot;
46import org.eclipse.uml2.uml.UMLPackage;
47
48import de.ugoe.cs.autoquest.eventcore.Event;
49import de.ugoe.cs.autoquest.plugin.http.SOAPUtils;
50import de.ugoe.cs.autoquest.plugin.http.eventcore.SimpleSOAPEventType.CallType;
51import de.ugoe.cs.util.StringTools;
52import de.ugoe.cs.util.console.Console;
53
54/**
55 * <p>
56 * Utility class to create UML Interactions from event sequences
57 * </p>
58 *
59 * @author Steffen Herbold
60 */
61class UMLInteractionCreator {
62
63    /**
64     * model for which the interactions are created
65     */
66    private final Model model;
67
68    /**
69     * name of the test context in which the interactions are created
70     */
71    private final String testContextName;
72
73    /**
74     * defines whether random message bodies are used or the ones associated with the SOAP events
75     */
76    private final boolean useRandomMsgBodies;
77
78    /**
79     * <p>
80     * Creates a new UMLInteractionCreator
81     * </p>
82     *
83     * @param model
84     *            UML model to which the interaction is added
85     * @param testContextName
86     *            Name of the test context that should be used. If this value is null, the first
87     *            test context found is used.
88     * @param useRandomRequestBodies
89     *            defines is random request bodies are used or the body of the associated event
90     */
91    public UMLInteractionCreator(Model model, String testContextName, boolean useRandomMsgBodies) {
92        this.model = model;
93        this.testContextName = testContextName;
94        this.useRandomMsgBodies = useRandomMsgBodies;
95    }
96
97    /**
98     * <p>
99     * Creates the UML Interaction for the given sequence
100     * </p>
101     *
102     * @param sequence
103     *            for which the interaction is created
104     * @param interactionName
105     *            name of the interaction
106     * @return created interaction
107     */
108    public Interaction createInteraction(List<Event> sequence, String interactionName) {
109        final Component testContext = UMLUtils.fetchTestContext(model, testContextName);
110        if (testContext == null) {
111            throw new RuntimeException("Could not find any test context in the model");
112        }
113
114        final Operation operation = testContext.createOwnedOperation(interactionName, null, null);
115        operation.applyStereotype(UTPUtils.getTestCaseStereotype(model));
116
117        final Interaction interaction =
118            (Interaction) testContext.createPackagedElement(interactionName + "_Impl",
119                                                            UMLPackage.Literals.INTERACTION);
120        operation.getMethods().add(interaction);
121
122        // create lifelines
123        Lifeline userLifeline = null;
124
125        for (Property property : UMLUtils.fetchAllSUTProperties(testContext)) {
126            String serviceName = property.getName();
127            Lifeline targetLifeline = interaction.createLifeline(serviceName);
128            targetLifeline.setRepresents(property);
129        }
130        for (Property property : UMLUtils.fetchAllTestComponentProperties(testContext)) {
131            userLifeline = interaction.createLifeline(property.getName());
132            userLifeline.setRepresents(property);
133        }
134
135        if (userLifeline == null) {
136            throw new RuntimeException("No TestComponent found, could not create user lifeline.");
137        }
138        if (interaction.getLifelines().size() < 2) {
139            throw new RuntimeException("Fewer than two lifelines created. No SUT found.");
140        }
141
142        int i = 0;
143        for (Event event : sequence) {
144            if (!(event.equals(Event.STARTEVENT) || event.equals(Event.ENDEVENT))) {
145                String serviceName = SOAPUtils.getServiceNameFromEvent(event);
146                String methodName = SOAPUtils.getCalledMethodFromEvent(event);
147                String clientName = SOAPUtils.getClientNameFromEvent(event);
148                String prefix = interactionName + "_" + i + "_" + methodName + "_";
149                // determine lifelines
150                Lifeline msgTargetLifeline;
151                Lifeline msgSourceLifeline;
152
153                msgSourceLifeline = interaction.getLifeline(clientName);
154                msgTargetLifeline = interaction.getLifeline(serviceName);
155
156                if (msgSourceLifeline == null) {
157                    throw new RuntimeException(
158                                               "Error creating message: could not determine source lifeline for component: " +
159                                                   clientName);
160                }
161                if (msgTargetLifeline == null) {
162                    throw new RuntimeException(
163                                               "Error creating message: could not determine target lifeline for component: " +
164                                                   serviceName);
165                }
166                // determine correct target interface
167                Set<Interface> targetInterfaces =
168                    UMLUtils.getRealizedInterfacesFromProperty((Property) msgTargetLifeline
169                        .getRepresents());
170                if (targetInterfaces.isEmpty()) {
171                    throw new RuntimeException("no interface associated with the property " +
172                        msgTargetLifeline.getRepresents().getName());
173                }
174                Interface targetInterface = null;
175                for (Interface intface : targetInterfaces) {
176                    if (UMLUtils.getOperationFromName(intface.getOperations(), methodName) != null)
177                    {
178                        // interface found
179                        targetInterface = intface;
180                        break;
181                    }
182                }
183                if (targetInterface == null) {
184                    StringBuilder errStrBuilder = new StringBuilder();
185                    errStrBuilder
186                        .append("Error creating message: operation not found in the implementing interfaces (");
187                    Iterator<Interface> iter = targetInterfaces.iterator();
188                    while (iter.hasNext()) {
189                        String interfaceName = iter.next().getName();
190                        errStrBuilder.append(interfaceName);
191                        if (iter.hasNext()) {
192                            errStrBuilder.append(",");
193                        }
194                        else {
195                            errStrBuilder.append("): " + methodName);
196                        }
197                    }
198                    throw new RuntimeException(errStrBuilder.toString());
199                }
200
201                Operation calledOperation =
202                    UMLUtils.getOperationFromName(targetInterface.getOperations(), methodName);
203                // get connector
204                Connector connector =
205                    UMLUtils.inferConnector(msgSourceLifeline, msgTargetLifeline, targetInterface);
206                if (connector == null) {
207                    throw new RuntimeException(
208                                               "Error creating message: could not find connector between the two life lines that supports the target interface at the target lifeline");
209                }
210
211                boolean asynch = false;
212                if (calledOperation.getConcurrency() == CallConcurrencyKind.CONCURRENT_LITERAL) {
213                    asynch = true;
214                }
215
216                if (SOAPUtils.isSOAPRequest(event)) {
217                    // setup for both SYNCH and ASYNCH calls
218                    MessageOccurrenceSpecification callSendFragment =
219                        (MessageOccurrenceSpecification) interaction
220                            .createFragment(prefix + "callSendFragment",
221                                            UMLPackage.Literals.MESSAGE_OCCURRENCE_SPECIFICATION);
222                    MessageOccurrenceSpecification callRecvFragment =
223                        (MessageOccurrenceSpecification) interaction
224                            .createFragment(prefix + "callRecvFragment",
225                                            UMLPackage.Literals.MESSAGE_OCCURRENCE_SPECIFICATION);
226
227                    callSendFragment.setCovered(msgSourceLifeline);
228                    callRecvFragment.setCovered(msgTargetLifeline);
229
230                    // create call
231                    Message callMessage = interaction.createMessage(prefix + "call");
232                    callMessage.setSignature(calledOperation);
233                    setMessageParameters(callMessage, calledOperation, event, prefix);
234                    callMessage.setConnector(connector);
235                    callMessage.setSendEvent(callSendFragment);
236                    callMessage.setReceiveEvent(callRecvFragment);
237                    callSendFragment.setMessage(callMessage);
238                    callRecvFragment.setMessage(callMessage);
239
240                    if (asynch) {
241                        // Create ASYNCH call
242                        callMessage.setMessageSort(MessageSort.ASYNCH_CALL_LITERAL);
243                    }
244                    else {
245                        // SYNCH call
246                        callMessage.setMessageSort(MessageSort.SYNCH_CALL_LITERAL);
247                    }
248                }
249                if (!asynch && SOAPUtils.isSOAPResponse(event)) {
250                    // setup reply and behavior execution specifications
251                    MessageOccurrenceSpecification replySendFragment =
252                        (MessageOccurrenceSpecification) interaction
253                            .createFragment(prefix + "replySendFragment",
254                                            UMLPackage.Literals.MESSAGE_OCCURRENCE_SPECIFICATION);
255                    MessageOccurrenceSpecification replyRecvFragment =
256                        (MessageOccurrenceSpecification) interaction
257                            .createFragment(prefix + "replyRecvFragment",
258                                            UMLPackage.Literals.MESSAGE_OCCURRENCE_SPECIFICATION);
259
260                    replySendFragment.setCovered(msgTargetLifeline);
261                    replyRecvFragment.setCovered(msgSourceLifeline);
262
263                    /*
264                     * BehaviorExecutionSpecification sourceBehaviorExecutionSpecification =
265                     * (BehaviorExecutionSpecification) interaction .createFragment(":" + methodName
266                     * + "_sourceBhvExecSpec",
267                     * UMLPackage.Literals.BEHAVIOR_EXECUTION_SPECIFICATION);
268                     * BehaviorExecutionSpecification targetBehaviorExecutionSpecification =
269                     * (BehaviorExecutionSpecification) interaction .createFragment(":" + methodName
270                     * + "_targetBhvExecSpec",
271                     * UMLPackage.Literals.BEHAVIOR_EXECUTION_SPECIFICATION);
272                     *
273                     * sourceBehaviorExecutionSpecification.setStart(callSendFragment);
274                     * sourceBehaviorExecutionSpecification.setFinish(replyRecvFragment);
275                     * targetBehaviorExecutionSpecification.setStart(callRecvFragment);
276                     * targetBehaviorExecutionSpecification.setFinish(replySendFragment);
277                     */
278
279                    // create reply
280                    Message replyMessage = interaction.createMessage(prefix + "_reply");
281                    replyMessage.setMessageSort(MessageSort.REPLY_LITERAL);
282                    replyMessage.setSignature(calledOperation);
283                    // setReplyMessageParameters(replyMessage, calledOperation);
284                    setMessageParameters(replyMessage, calledOperation, event, prefix);
285                    replyMessage.setConnector(connector);
286                    replyMessage.setSendEvent(replySendFragment);
287                    replyMessage.setReceiveEvent(replyRecvFragment);
288                    replySendFragment.setMessage(replyMessage);
289                    replyRecvFragment.setMessage(replyMessage);
290                }
291
292                i++;
293            }
294        }
295        return interaction;
296    }
297
298    /**
299     * <p>
300     * Sets values for the parameters of a call message. The values are, if possible, inferred from
301     * the event that is provided.
302     * </p>
303     *
304     * @param message
305     *            call message for which the parameters are set
306     * @param calledOperation
307     *            operation that is called by the message
308     * @param event
309     *            event that provides the parameters; in case of null, default values are assumed
310     * @param prefix
311     *            prefix of the call message; used to create good warnings and debugging information
312     */
313    private void setMessageParameters(Message message,
314                                      Operation calledOperation,
315                                      Event event,
316                                      String prefix)
317    {
318        org.w3c.dom.Element requestBody;
319        if (SOAPUtils.isSOAPRequest(event)) {
320            requestBody =
321                SOAPUtils.getSoapBodyFromEvent(event, useRandomMsgBodies, CallType.REQUEST);
322        }
323        else {
324            requestBody =
325                SOAPUtils.getSoapBodyFromEvent(event, useRandomMsgBodies, CallType.RESPONSE);
326        }
327        Package instSpecPkg = null;
328        MutableInt instSpecNumber = new MutableInt(0);
329
330        // Set parameters of operation
331        for (Parameter param : calledOperation.getOwnedParameters()) {
332            if (instSpecPkg == null) {
333                instSpecPkg = getOrCreateInstanceSpecificationPackage(event);
334            }
335
336            String path = calledOperation.getName() + ":" + param.getType().getName();
337            if ((UMLUtils.isInParameter(param) && SOAPUtils.isSOAPRequest(event)) ||
338                (UMLUtils.isOutParameter(param) && SOAPUtils.isSOAPResponse(event)))
339            {
340
341                // create parameters node
342                if (!(param.getType() instanceof DataType)) {
343                    throw new RuntimeException("TODO error handling; parameters missing");
344                }
345                DataType parametersNode = (DataType) param.getType();
346                InstanceSpecification instSpecParameters =
347                    (InstanceSpecification) instSpecPkg
348                        .createPackagedElement(prefix + "instspec" + instSpecNumber.intValue() +
349                                                   "_" + param.getType().getName(),
350                                               UMLPackage.Literals.INSTANCE_SPECIFICATION);
351                instSpecParameters.getClassifiers().add((DataType) param.getType());
352                instSpecNumber.setValue(instSpecNumber.intValue() + 1);
353                InstanceValue instanceValue =
354                    (InstanceValue) message.createArgument(param.getName(), param.getType(),
355                                                           UMLPackage.Literals.INSTANCE_VALUE);
356                instanceValue.setInstance(instSpecParameters);
357
358                for (Property internalParameter : parametersNode.getAllAttributes()) {
359                    if (internalParameter.getType() instanceof DataType) {
360                        List<org.w3c.dom.Element> paramNodes =
361                            SOAPUtils.getMatchingChildNode(internalParameter.getType().getName(),
362                                                           requestBody);
363                        int multiplicityChosen = paramNodes.size();
364
365                        if (multiplicityChosen == 0 && internalParameter.getLower() > 0) {
366                            Console
367                                .traceln(Level.WARNING,
368                                         "required attribute not found in SOAP message: " + path);
369                            Console
370                                .traceln(Level.WARNING,
371                                         "setting default values for this attribute and all its children");
372                            Console.traceln(Level.FINE, "XML structure of path:" +
373                                StringTools.ENDLINE + SOAPUtils.getSerialization(requestBody));
374                            multiplicityChosen = internalParameter.getLower();
375                        }
376                        for (int i = 0; i < multiplicityChosen; i++) {
377                            org.w3c.dom.Element paramNode = null;
378                            if (!paramNodes.isEmpty()) {
379                                paramNode = paramNodes.get(i);
380                            }
381
382                            Slot slot = instSpecParameters.createSlot();
383                            slot.setDefiningFeature(internalParameter);
384
385                            InstanceValue value =
386                                (InstanceValue) slot
387                                    .createValue(internalParameter.getName() + "_" + i,
388                                                 internalParameter.getType(),
389                                                 UMLPackage.Literals.INSTANCE_VALUE);
390                            value
391                                .setInstance(createInstanceSpecification((DataType) internalParameter
392                                                                             .getType(),
393                                                                         instSpecPkg, prefix,
394                                                                         instSpecNumber, paramNode,
395                                                                         path));
396                            /*
397                             * InstanceValue value = (InstanceValue) argument .createOperand(null,
398                             * internalParameter.getType(), UMLPackage.Literals.INSTANCE_VALUE);
399                             * value.setInstance(instSpec);
400                             */
401                        }
402                    }
403                    else if (internalParameter.getType() instanceof PrimitiveType) {
404                        createSlotPrimitiveType(instSpecParameters, internalParameter, requestBody,
405                                                path);
406                    }
407                }
408            }
409            else {
410                // set literalNull for out and return parameters
411                // argument.createOperand(null, param.getType(), UMLPackage.Literals.LITERAL_NULL);
412                message.createArgument(param.getName(), param.getType(),
413                                       UMLPackage.Literals.LITERAL_NULL);
414            }
415        }
416    }
417
418    /**
419     * <p>
420     * Creates an {@link InstanceSpecification} for a data type in the given package. The values are
421     * inferred, if possible, from the DOM node. The prefix and the path are used for naming the
422     * instance specification and to provide good warnings and debug information in case of
423     * problems.
424     * </p>
425     *
426     * @param type
427     *            DataType for which the {@link InstanceSpecification} is created
428     * @param pkg
429     *            package in which the {@link InstanceSpecification} is created
430     * @param prefix
431     *            prefix used for naming the {@link InstanceSpecification}
432     * @param currentNode
433     *            node of a DOM from which values are inferred
434     * @param path
435     *            used for warnings and debug information
436     * @return {@link InstanceSpecification} for the given type
437     */
438    private InstanceSpecification createInstanceSpecification(DataType type,
439                                                              Package pkg,
440                                                              String prefix,
441                                                              MutableInt instSpecNumber,
442                                                              org.w3c.dom.Element currentNode,
443                                                              String path)
444    {
445        if ("".equals(path)) {
446            path = type.getName();
447        }
448
449        InstanceSpecification instSpec =
450            (InstanceSpecification) pkg
451                .createPackagedElement(prefix + "instspec" + instSpecNumber.intValue() + "_" +
452                                           type.getName(),
453                                       UMLPackage.Literals.INSTANCE_SPECIFICATION);
454        instSpec.getClassifiers().add(type);
455        instSpecNumber.setValue(instSpecNumber.intValue() + 1);
456        for (Property prop : type.getAllAttributes()) {
457            if (prop.getType() instanceof PrimitiveType) {
458                createSlotPrimitiveType(instSpec, prop, currentNode, path);
459            }
460            else if (prop.getType() instanceof DataType) {
461                List<org.w3c.dom.Element> attributeNodes = null;
462                int multiplicityChosen = 0;
463                if (currentNode != null) {
464                    attributeNodes = SOAPUtils.getMatchingChildNode(prop.getName(), currentNode);
465                    multiplicityChosen = attributeNodes.size();
466                }
467
468                if (multiplicityChosen == 0 && prop.getLower() > 0) {
469                    if (currentNode != null) {
470                        Console.traceln(Level.WARNING,
471                                        "required attribute not found in SOAP message: " + path +
472                                            "." + prop.getName());
473                        Console
474                            .traceln(Level.WARNING,
475                                     "setting default values for this attribute and all its children");
476                        Console.traceln(Level.FINE, "XML structure of path:" + StringTools.ENDLINE +
477                            SOAPUtils.getSerialization(currentNode));
478                    }
479                    multiplicityChosen = prop.getLower();
480                }
481                for (int i = 0; i < multiplicityChosen; i++) {
482                    org.w3c.dom.Element attributeNode = null;
483                    if (attributeNodes != null && !attributeNodes.isEmpty()) {
484                        attributeNode = attributeNodes.get(i);
485                    }
486
487                    Slot slot = instSpec.createSlot();
488                    slot.setDefiningFeature(prop);
489
490                    InstanceValue value =
491                        (InstanceValue) slot.createValue(prop.getName() + "_" + i, prop.getType(),
492                                                         UMLPackage.Literals.INSTANCE_VALUE);
493                    value.setInstance(createInstanceSpecification((DataType) prop.getType(), pkg,
494                                                                  prefix, instSpecNumber,
495                                                                  attributeNode,
496                                                                  path + "." + prop.getName()));
497                }
498            }
499            else {
500                Console.traceln(Level.SEVERE, "property neither DataType nor PrimitiveType: " +
501                    prop.getType());
502                throw new RuntimeException(
503                                           "can only handle DataType and PrimitiveType properties but was: " +
504                                               prop.getType().getClass().getName());
505            }
506        }
507        return instSpec;
508    }
509
510    /**
511     * <p>
512     * Creates a {@link Slot} in an {@link InstanceSpecification} for a primitive type.
513     * </p>
514     *
515     * @param instSpec
516     *            instance specification to which the slot is added
517     * @param prop
518     *            property that describes the slot
519     * @param currentNode
520     *            DOM node from which is value for the slot is inferred
521     * @param path
522     *            used for warnings and debug information
523     */
524    private static void createSlotPrimitiveType(InstanceSpecification instSpec,
525                                                Property prop,
526                                                org.w3c.dom.Element currentNode,
527                                                String path)
528    {
529        List<String> attributeValues = SOAPUtils.getValuesFromElement(prop.getName(), currentNode);
530
531        if (attributeValues.isEmpty()) {
532            if (prop.getLower() == 0) {
533                // ignoring optional attribute
534                return;
535            }
536            else {
537                if (currentNode != null) {
538                    Console.traceln(Level.WARNING,
539                                    "required attribute not found in SOAP message: " + path + "." +
540                                        prop.getName());
541                    Console.traceln(Level.WARNING, "setting default values for this attribute");
542                    Console.traceln(Level.FINE, "XML structure of path:" + StringTools.ENDLINE +
543                        SOAPUtils.getSerialization(currentNode));
544                }
545                attributeValues.add(null);
546            }
547        }
548        for (String attributeValue : attributeValues) {
549            Slot slot = instSpec.createSlot();
550            slot.setDefiningFeature(prop);
551            if ("String".equals(prop.getType().getName())) {
552                LiteralString value =
553                    (LiteralString) slot.createValue(prop.getName(), null,
554                                                     UMLPackage.Literals.LITERAL_STRING);
555                if (attributeValue != null) {
556                    value.setValue(attributeValue);
557                }
558                else {
559                    value.setValue("foobar");
560                }
561            }
562            else if ("Integer".equals(prop.getType().getName())) {
563                LiteralInteger value =
564                    (LiteralInteger) slot.createValue(prop.getName(), null,
565                                                      UMLPackage.Literals.LITERAL_INTEGER);
566                if (attributeValue != null) {
567                    value.setValue(Integer.parseInt(attributeValue));
568                }
569                else {
570                    value.setValue(42);
571                }
572            }
573            else if ("Boolean".equals(prop.getType().getName())) {
574                LiteralBoolean value =
575                    (LiteralBoolean) slot.createValue(prop.getName(), null,
576                                                      UMLPackage.Literals.LITERAL_BOOLEAN);
577                if (attributeValue != null) {
578                    value.setValue(Boolean.parseBoolean(attributeValue));
579                }
580                else {
581                    value.setValue(true);
582                }
583            }
584            else if ("Real".equals(prop.getType().getName())) {
585                LiteralReal value =
586                    (LiteralReal) slot.createValue(prop.getName(), null,
587                                                   UMLPackage.Literals.LITERAL_REAL);
588                if (attributeValue != null) {
589                    value.setValue(Double.parseDouble(attributeValue));
590                }
591                else {
592                    value.setValue(3.14);
593                }
594            }
595            else {
596                Console.traceln(Level.SEVERE, "could not create literal for primitive type: " +
597                    prop.getType().getName());
598                throw new RuntimeException("unknown primitive type: " + prop.getType().getName());
599            }
600        }
601    }
602
603    /**
604     * <p>
605     * Gets or creates a {@link Package} for {@link InstanceSpecification} created by the
606     * usage-based testing. Each service gets its own sub-package within a package called
607     * UBT_InstanceSpecifications. "
608     * </p>
609     *
610     * @param event
611     *            event from which the service name is inferred
612     * @return package for the {@link InstanceSpecification}s
613     */
614    private Package getOrCreateInstanceSpecificationPackage(Event event) {
615        String pkgUBTInstSpecs = "UBT_InstanceSpecifications";
616        Package ubtInstSpecPkg = (Package) model.getOwnedMember(pkgUBTInstSpecs);
617        if (ubtInstSpecPkg == null) {
618            ubtInstSpecPkg =
619                (Package) model.createPackagedElement(pkgUBTInstSpecs, UMLPackage.Literals.PACKAGE);
620        }
621        String serviceName = SOAPUtils.getServiceNameFromEvent(event);
622        Package serviceInstSpecPkg = (Package) ubtInstSpecPkg.getOwnedMember(serviceName);
623        if (serviceInstSpecPkg == null) {
624            serviceInstSpecPkg =
625                (Package) ubtInstSpecPkg.createPackagedElement(serviceName,
626                                                               UMLPackage.Literals.PACKAGE);
627        }
628        return serviceInstSpecPkg;
629    }
630
631}
Note: See TracBrowser for help on using the repository browser.