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]].
