Author: mvw
Date: 2010-06-16 00:49:22-0700
New Revision: 18449

Modified:
   
trunk/src/argouml-app/src/org/argouml/notation/providers/uml/TransitionNotationUml.java
   
trunk/src/argouml-app/tests/org/argouml/notation/providers/uml/TestTransitionNotationUml.java

Log:
Fix for issue 5988: Reuse trigger events when entered with notation.

Modified: 
trunk/src/argouml-app/src/org/argouml/notation/providers/uml/TransitionNotationUml.java
Url: 
http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/notation/providers/uml/TransitionNotationUml.java?view=diff&pathrev=18449&r1=18448&r2=18449
==============================================================================
--- 
trunk/src/argouml-app/src/org/argouml/notation/providers/uml/TransitionNotationUml.java
     (original)
+++ 
trunk/src/argouml-app/src/org/argouml/notation/providers/uml/TransitionNotationUml.java
     2010-06-16 00:49:22-0700
@@ -215,7 +215,7 @@
          * 3. A trigger is not given. None exists yet.
          * 4. The name of the trigger was present, but is removed.
          * The reaction in these cases should be:
-         * 1. Create a new trigger, name it, and hook it to the transition.
+         * 1. Find the referred trigger (issue 5988) or create a new one, and 
hook it to the transition.
          * 2. Rename the trigger.
          * 3. Nop.
          * 4. Unhook and erase the existing trigger.
@@ -228,17 +228,17 @@
                 .findNamespaceForEvent(trans, null);
         StateMachinesFactory sMFactory =
                 Model.getStateMachinesFactory();
-        boolean createdEvent = false;
+        boolean weHaveAnEvent = false;
         if (trigger.length() > 0) {
             // case 1 and 2
             if (evt == null) {
                 // case 1
                 if (timeEvent) { // after(...)
-                    evt = sMFactory.buildTimeEvent(s, ns);
+                    evt = findOrBuildTimeEvent(s, ns);
                     /* Do not set the name. */
                 }
                 if (changeEvent) { // when(...)
-                    evt = sMFactory.buildChangeEvent(s, ns);
+                    evt = findOrBuildChangeEvent(s, ns);
                     /* Do not set the name. */
                 }
                 if (callEvent) { // operation(paramlist)
@@ -246,27 +246,38 @@
                         trigger.indexOf("(") > 0
                         ? trigger.substring(0, trigger.indexOf("(")).trim()
                         : trigger;
-                    evt = sMFactory.buildCallEvent(trans, triggerName, ns);
-                    // and parse the parameter list
-                    NotationUtilityUml.parseParamList(evt, s, 0);
+                    /* This case is a bit different, because of the 
parameters. 
+                     * If the event already exists, the parameters are 
ignored. */
+                    evt = findCallEvent(triggerName, ns);
+                    if (evt == null) {
+                        evt = sMFactory.buildCallEvent(trans, triggerName, ns);
+                        // and parse the parameter list
+                        NotationUtilityUml.parseParamList(evt, s, 0);
+                    }
                 }
                 if (signalEvent) { // signalname
-                    evt = sMFactory.buildSignalEvent(trigger, ns);
+                    evt = findOrBuildSignalEvent(trigger, ns);
                 }
-                createdEvent = true;
+                weHaveAnEvent = true;
             } else {
                 // case 2
                 if (timeEvent) {
                     if (Model.getFacade().isATimeEvent(evt)) {
                         /* Just change the time expression */
                         Object timeExpr = Model.getFacade().getWhen(evt);
-                        Model.getDataTypesHelper().setBody(timeExpr, s);
+                        if (timeExpr == null) {
+                            // we have an event without expression
+                            timeExpr = 
Model.getDataTypesFactory().createTimeExpression("", s);
+                            Model.getStateMachinesHelper().setWhen(evt, 
timeExpr);
+                        } else {
+                            Model.getDataTypesHelper().setBody(timeExpr, s);
+                        }
                     } else {
                         /* It's a time-event now,
                          * but was of another type before! */
                         delete(evt); /* TODO: What if used elsewhere? */
                         evt = sMFactory.buildTimeEvent(s, ns);
-                        createdEvent = true;
+                        weHaveAnEvent = true;
                     }
                 }
                 if (changeEvent) {
@@ -288,7 +299,7 @@
                          * but the model contains another type! */
                         delete(evt); /* TODO: What if used elsewhere? */
                         evt = sMFactory.buildChangeEvent(s, ns);
-                        createdEvent = true;
+                        weHaveAnEvent = true;
                     }
                 }
                 if (callEvent) {
@@ -308,7 +319,7 @@
                         evt = sMFactory.buildCallEvent(trans, trigger, ns);
                         // and parse the parameter list
                         NotationUtilityUml.parseParamList(evt, s, 0);
-                        createdEvent = true;
+                        weHaveAnEvent = true;
                     }
                 }
                 if (signalEvent) {
@@ -321,11 +332,11 @@
                     } else {
                         delete(evt); /* TODO: What if used elsewhere? */
                         evt = sMFactory.buildSignalEvent(trigger, ns);
-                        createdEvent = true;
+                        weHaveAnEvent = true;
                     }
                 }
             }
-            if (createdEvent && (evt != null)) {
+            if (weHaveAnEvent && (evt != null)) {
                 Model.getStateMachinesHelper().setEventAsTrigger(trans, evt);
             }
         } else {
@@ -338,6 +349,93 @@
             }
         }
     }
+    
+    protected Object findOrBuildSignalEvent(String trigger, Object ns) {
+        StateMachinesFactory sMFactory = Model.getStateMachinesFactory();
+        if ((trigger == null) || ("".equals(trigger.trim()))) {
+            return sMFactory.buildSignalEvent(trigger, ns);
+        }
+        Object result = null;
+        Object type = Model.getMetaTypes().getSignalEvent();
+        Collection events = Model.getModelManagementHelper()
+            .getAllModelElementsOfKind(ns, type);
+        for (Object event : events) {
+            if (trigger.equals(Model.getFacade().getName(event))) {
+                result = event;
+                break;
+            }
+        }
+        if (result == null) {
+            result = sMFactory.buildSignalEvent(trigger, ns);
+        }
+        return result;
+    }
+    
+    protected Object findOrBuildTimeEvent(String timeexpr, Object ns) {
+        StateMachinesFactory sMFactory = Model.getStateMachinesFactory();
+        if ((timeexpr == null) || ("".equals(timeexpr.trim()))) {
+            return sMFactory.buildTimeEvent(timeexpr, ns);
+        }
+        Object result = null;
+        Object type = Model.getMetaTypes().getTimeEvent();
+        Collection events = Model.getModelManagementHelper()
+            .getAllModelElementsOfKind(ns, type);
+        for (Object event : events) {
+            Object expression = Model.getFacade().getExpression(event);
+            if (expression != null) {
+                if (timeexpr.equals(Model.getFacade().getBody(expression))) {
+                    result = event;
+                    break;
+                }
+            }
+        }
+        if (result == null) {
+            result = sMFactory.buildTimeEvent(timeexpr, ns);
+        }
+        return result;
+    }
+    
+    protected Object findOrBuildChangeEvent(String changeexpr, Object ns) {
+        StateMachinesFactory sMFactory = Model.getStateMachinesFactory();
+        if ((changeexpr == null) || ("".equals(changeexpr.trim()))) {
+            return sMFactory.buildChangeEvent(changeexpr, ns);
+        }
+        Object result = null;
+        Object type = Model.getMetaTypes().getChangeEvent();
+        Collection events = Model.getModelManagementHelper()
+            .getAllModelElementsOfKind(ns, type);
+        for (Object event : events) {
+            Object expression = Model.getFacade().getExpression(event);
+            if (expression != null) {
+                if (changeexpr.equals(Model.getFacade().getBody(expression))) {
+                    result = event;
+                    break;
+                }
+            }
+        }
+        if (result == null) {
+            result = sMFactory.buildChangeEvent(changeexpr, ns);
+        }
+        return result;
+    }
+    
+    protected Object findCallEvent(String callexpr, Object ns) {
+        if ((callexpr == null) || ("".equals(callexpr.trim()))) {
+            return null;
+        }
+        Object result = null;
+        Object type = Model.getMetaTypes().getCallEvent();
+        Collection events = Model.getModelManagementHelper()
+            .getAllModelElementsOfKind(ns, type);
+        for (Object event : events) {
+            if (callexpr.equals(Model.getFacade().getName(event))) {
+                /* Do not check if the parameters match. */
+                result = event;
+                break;
+            }
+        }
+        return result;
+    }
 
     /**
      * Handle the Guard of a Transition.<p>

Modified: 
trunk/src/argouml-app/tests/org/argouml/notation/providers/uml/TestTransitionNotationUml.java
Url: 
http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/tests/org/argouml/notation/providers/uml/TestTransitionNotationUml.java?view=diff&pathrev=18449&r1=18448&r2=18449
==============================================================================
--- 
trunk/src/argouml-app/tests/org/argouml/notation/providers/uml/TestTransitionNotationUml.java
       (original)
+++ 
trunk/src/argouml-app/tests/org/argouml/notation/providers/uml/TestTransitionNotationUml.java
       2010-06-16 00:49:22-0700
@@ -1,6 +1,6 @@
 /* $Id$
  *****************************************************************************
- * Copyright (c) 2009 Contributors - see below
+ * Copyright (c) 2009-2010 Contributors - see below
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
  *
  * Contributors:
  *    tfmorris
+ *    mvw
  *****************************************************************************
  *
  * Some portions of this file was previously release using the BSD License:
@@ -96,6 +97,64 @@
         ProfileFacade.reset();
         super.tearDown();
     }
+    
+    /**
+     * Test the reuse of events when a transition notation is parsed. 
+     * See issue 5988.
+     */
+    public void testParseEventsReuse() {
+        // reuse signal event:
+        Object t1s = checkGenerated(aState, "trigger1[guard]/effect", 
+                true, true, true, false);
+        Object t2s = checkGenerated(aState, "trigger1[guard]/effect", 
+                true, true, true, false);
+        Object t3s = checkGenerated(aState, "trigger2[guard]/effect", 
+                true, true, true, false);
+        Object trigger1s = Model.getFacade().getTrigger(t1s);
+        Object trigger2s = Model.getFacade().getTrigger(t2s);
+        Object trigger3s = Model.getFacade().getTrigger(t3s);
+        assertTrue("No reuse of a signal event.", trigger1s == trigger2s);
+        assertTrue("Unexpected reuse of a signal event.",  trigger1s != 
trigger3s);
+        
+        // reuse call event:
+        Object t1c = checkGenerated(aState, "trigger1()[guard]/effect", 
+                true, true, true, false);
+        Object t2c = checkGenerated(aState, "trigger1()[guard]/effect", 
+                true, true, true, false);
+        Object t3c = checkGenerated(aState, "trigger2()[guard]/effect", 
+                true, true, true, false);
+        Object trigger1c = Model.getFacade().getTrigger(t1c);
+        Object trigger2c = Model.getFacade().getTrigger(t2c);
+        Object trigger3c = Model.getFacade().getTrigger(t3c);
+        assertTrue("No reuse of a call event.", trigger1c == trigger2c);
+        assertTrue("Unexpected reuse of a call event.", trigger1c != 
trigger3c);
+        
+        // reuse time event:
+        Object t1t = checkGenerated(aState, "after(1s)[guard]/effect", 
+                true, true, true, false);
+        Object t2t = checkGenerated(aState, "after(1s)[guard]/effect", 
+                true, true, true, false);
+        Object t3t = checkGenerated(aState, "after(2s)[guard]/effect", 
+                true, true, true, false);
+        Object trigger1t = Model.getFacade().getTrigger(t1t);
+        Object trigger2t = Model.getFacade().getTrigger(t2t);
+        Object trigger3t = Model.getFacade().getTrigger(t3t);
+        assertTrue("No reuse of a time event.", trigger1t == trigger2t);
+        assertTrue("Unexpected reuse of a time event.", trigger1t != 
trigger3t);
+        
+        // reuse change event:
+        Object t1g = checkGenerated(aState, "when(condition1)[guard]/effect", 
+                true, true, true, false);
+        Object t2g = checkGenerated(aState, "when(condition1)[guard]/effect", 
+                true, true, true, false);
+        Object t3g = checkGenerated(aState, "when(condition2)[guard]/effect", 
+                true, true, true, false);
+        Object trigger1g = Model.getFacade().getTrigger(t1g);
+        Object trigger2g = Model.getFacade().getTrigger(t2g);
+        Object trigger3g = Model.getFacade().getTrigger(t3g);
+        assertTrue("No reuse of a change event.", trigger1g == trigger2g);
+        assertTrue("Unexpected reuse of a change event.", trigger1g != 
trigger3g);
+    }
 
     /**
      * Test for the parseTransition() method.

------------------------------------------------------
http://argouml.tigris.org/ds/viewMessage.do?dsForumId=5905&dsMessageId=2622293

To unsubscribe from this discussion, e-mail: 
[[email protected]].

Reply via email to