Skip to main content
summaryrefslogtreecommitdiffstats
blob: 11be8bbe97edad2df49b346f7c529c0eab50dd39 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
/*****************************************************************************
 * Copyright (c) 2010 CEA
 *
 *    
 * 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
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Atos Origin - Initial API and implementation
 *
 *****************************************************************************/
package org.eclipse.papyrus.uml.diagram.sequence.util;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.commands.UnexecutableCommand;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.diagram.core.commands.DeleteCommand;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionNodeEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IBorderItemEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand;
import org.eclipse.gmf.runtime.emf.type.core.commands.DestroyElementCommand;
import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils;
import org.eclipse.papyrus.infra.services.edit.service.IElementEditService;
import org.eclipse.papyrus.uml.diagram.common.util.DiagramEditPartsUtil;
import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.LifelineEditPart;
import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.ObservationLinkEditPart;
import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.TimeObservationLabelEditPart;
import org.eclipse.uml2.uml.DestructionOccurrenceSpecification;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.ExecutionSpecification;
import org.eclipse.uml2.uml.Lifeline;
import org.eclipse.uml2.uml.Message;
import org.eclipse.uml2.uml.MessageEnd;
import org.eclipse.uml2.uml.OccurrenceSpecification;
import org.eclipse.uml2.uml.TimeObservation;

/**
 * An Helper to get deleting command for the sequence diagram elements.
 */

public class SequenceDeleteHelper {

	/**
	 * Complete an ICommand which destroys an DestructionEvent element to also destroy dependent time/duration constraint/observation linked with
	 * these ends
	 * 
	 * @param deleteViewsCmd
	 *        the command to complete
	 * @param editingDomain
	 *        the editing domain
	 * @param destructionEventPart
	 *        the execution specification edit part on which the request is called
	 * @return the deletion command deleteViewsCmd for convenience
	 */
	public static CompoundCommand completeDeleteDestructionOccurenceViewCommand(CompoundCommand deleteViewsCmd, TransactionalEditingDomain editingDomain, EditPart destructionEventPart) {
		if(destructionEventPart instanceof IGraphicalEditPart) {
			EObject obj = ((IGraphicalEditPart)destructionEventPart).resolveSemanticElement();

			if(obj instanceof DestructionOccurrenceSpecification) {
				LifelineEditPart lifelinePart = SequenceUtil.getParentLifelinePart(destructionEventPart);
				if(lifelinePart != null) {
					for(Object lifelineChild : lifelinePart.getChildren()) {
						if(lifelineChild instanceof IBorderItemEditPart) {
							final IBorderItemEditPart timePart = (IBorderItemEditPart)lifelineChild;
							//At most one destruction event. Only parts linked to it can not move for now.
							boolean isNotLinked = OccurrenceSpecificationMoveHelper.canTimeElementPartBeYMoved(timePart);
							if(!isNotLinked) {
								// time part is linked, delete the view
								Command deleteTimeViewCommand = new ICommandProxy(new DeleteCommand(editingDomain, (View)timePart.getModel()));
								deleteViewsCmd.add(deleteTimeViewCommand);
							}
						}
					}
				}
			}
		}
		return deleteViewsCmd;
	}

	/**
	 * Complete an ICommand which destroys an ExecutionSpecification element to also destroy dependent finish and start events and time/duration
	 * constraint/observation linked with these ends
	 * 
	 * @param deleteViewsCmd
	 *        the command to complete
	 * @param editingDomain
	 *        the editing domain
	 * @param executionPart
	 *        the execution specification edit part on which the request is called
	 * @return the deletion command deleteViewsCmd for convenience
	 */
	public static CompoundCommand completeDeleteMessageViewCommand(CompoundCommand deleteViewsCmd, TransactionalEditingDomain editingDomain, EditPart messagePart) {
		if(messagePart instanceof IGraphicalEditPart) {
			EObject obj = ((IGraphicalEditPart)messagePart).resolveSemanticElement();
			if(obj instanceof Message) {
				Message message = (Message)obj;
				LifelineEditPart srcLifelinePart = SequenceUtil.getParentLifelinePart(((ConnectionNodeEditPart)messagePart).getSource());
				MessageEnd send = message.getSendEvent();
				addDeleteRelatedTimePartsToCommand(deleteViewsCmd, editingDomain, srcLifelinePart, send);

				LifelineEditPart tgtLifelinePart = SequenceUtil.getParentLifelinePart(((ConnectionNodeEditPart)messagePart).getTarget());
				MessageEnd receive = message.getReceiveEvent();
				addDeleteRelatedTimePartsToCommand(deleteViewsCmd, editingDomain, tgtLifelinePart, receive);
				
				// also delete time observation links which are related to message end
				if (send instanceof OccurrenceSpecification) {
					addDeleteRelatedTimeObservationLinkCommand(deleteViewsCmd, editingDomain,(OccurrenceSpecification) send, srcLifelinePart,false);
				}
				if (receive instanceof OccurrenceSpecification) {
					addDeleteRelatedTimeObservationLinkCommand(deleteViewsCmd, editingDomain,(OccurrenceSpecification) receive, tgtLifelinePart,false);
				}
			}
		}
		return deleteViewsCmd;
	}

	private static void addDeleteRelatedTimePartsToCommand(CompoundCommand deleteViewsCmd, TransactionalEditingDomain editingDomain, LifelineEditPart lifelineEP, MessageEnd messageEnd) {
		if(lifelineEP != null && messageEnd instanceof OccurrenceSpecification) {
			for(Object lifelineChild : lifelineEP.getChildren()) {
				if(lifelineChild instanceof IBorderItemEditPart) {
					final IBorderItemEditPart timePart = (IBorderItemEditPart)lifelineChild;
					int positionForEvent = SequenceUtil.positionWhereEventIsLinkedToPart((OccurrenceSpecification)messageEnd, timePart);
					if(positionForEvent != PositionConstants.NONE) {
						// time part is linked, delete the view
						Command deleteTimeViewCommand = new ICommandProxy(new DeleteCommand(editingDomain, (View)timePart.getModel()));
						deleteViewsCmd.add(deleteTimeViewCommand);
					}
				}
			}
		}
	}

	/**
	 * Complete an ICommand which destroys an ExecutionSpecification element to also destroy dependent finish and start events and time/duration
	 * constraint/observation linked with these ends
	 * 
	 * @param deleteViewsCmd
	 *        the command to complete
	 * @param editingDomain
	 *        the editing domain
	 * @param executionPart
	 *        the execution specification edit part on which the request is called
	 * @return the deletion command deleteViewsCmd for convenience
	 */
	public static CompoundCommand completeDeleteExecutionSpecificationViewCommand(CompoundCommand deleteViewsCmd, TransactionalEditingDomain editingDomain, EditPart executionPart) {
		if(executionPart instanceof IGraphicalEditPart) {
			EObject obj = ((IGraphicalEditPart)executionPart).resolveSemanticElement();

			if(obj instanceof ExecutionSpecification) {
				ExecutionSpecification execution = (ExecutionSpecification)obj;
				LifelineEditPart lifelinePart = SequenceUtil.getParentLifelinePart(executionPart);
				if(lifelinePart != null) {
					for(Object lifelineChild : lifelinePart.getChildren()) {
						if(lifelineChild instanceof IBorderItemEditPart) {
							final IBorderItemEditPart timePart = (IBorderItemEditPart)lifelineChild;
							OccurrenceSpecification start = execution.getStart();
							OccurrenceSpecification finish = execution.getStart();
							int positionForStart = SequenceUtil.positionWhereEventIsLinkedToPart(start, timePart);
							int positionForFinish = SequenceUtil.positionWhereEventIsLinkedToPart(finish, timePart);
							if(positionForStart != PositionConstants.NONE || positionForFinish != PositionConstants.NONE) {
								// time part is linked, delete the view
								Command deleteTimeViewCommand = new ICommandProxy(new DeleteCommand(editingDomain, (View)timePart.getModel()));
								deleteViewsCmd.add(deleteTimeViewCommand);
							}
						}
					}
					
					// delete each observation linked time element
					for(Object targetConnection : lifelinePart.getTargetConnections()){
						if(targetConnection instanceof ObservationLinkEditPart){
							ObservationLinkEditPart observationLinkEditPart = (ObservationLinkEditPart)targetConnection;
							TimeObservationLabelEditPart source = (TimeObservationLabelEditPart)observationLinkEditPart.getSource();
							OccurrenceSpecification start = execution.getStart();
							OccurrenceSpecification finish = execution.getFinish();
							int positionForStart = SequenceUtil.positionWhereEventIsLinkedToPart(start, source);
							int positionForFinish = SequenceUtil.positionWhereEventIsLinkedToPart(finish, source);
							if(positionForStart != PositionConstants.NONE) {
								// time part is linked, delete the view
								//Command deleteTimeViewCommand = new ICommandProxy(new DeleteCommand(editingDomain, (View)source.getModel()));
								//deleteViewsCmd.add(deleteTimeViewCommand);
								addDeleteRelatedTimeObservationLinkCommand(deleteViewsCmd,
										editingDomain, start, lifelinePart,false);
							}
							if(positionForFinish != PositionConstants.NONE) {
								addDeleteRelatedTimeObservationLinkCommand(deleteViewsCmd,
										editingDomain, finish, lifelinePart,false);
							}
						}
					}
				}
			}
		}
		return deleteViewsCmd;
	}

	/**
	 * Delete the views associated with a list of elements.
	 * 
	 * @param cmd
	 *        the CompositeTransactionalCommand
	 * @param element
	 *        the list of model elements
	 * @param editingDomain
	 *        the editing domain to use.
	 */
	public static void deleteView(CompositeTransactionalCommand cmd, List<Element> elements, TransactionalEditingDomain editingDomain) {
		for(Element element : elements) {
			deleteView(cmd, element, editingDomain);
		}
	}

	/**
	 * Delete the views associated with an element.
	 * 
	 * @param cmd
	 *        the CompositeTransactionalCommand
	 * @param element
	 *        the model element referenced by the views
	 * @param editingDomain
	 *        the editing domain to use.
	 */
	public static void deleteView(CompositeTransactionalCommand cmd, Element element, TransactionalEditingDomain editingDomain) {
		// Destroy its views
		@SuppressWarnings("rawtypes")
		List views = DiagramEditPartsUtil.getEObjectViews(element);
		for(Object object : views) {
			if(object instanceof View) {
				cmd.add(new DeleteCommand(editingDomain, (View)object));
			}
		}
	}
	
	/**
	 * Add complete delete message command
	 * @param req
	 * @param editPart
	 * @return Command
	 */
	public static Command completeDeleteMessageCommand(DestroyElementRequest req,EditPart editPart) {
		EObject selectedEObject = req.getElementToDestroy();
		IElementEditService provider = ElementEditServiceUtils
				.getCommandProvider(selectedEObject);
		if (provider != null) {
			// Retrieve delete command from the Element Edit service
			ICommand deleteCommand = provider.getEditCommand(req);
			if (deleteCommand != null) {
				CompositeCommand command = new CompositeCommand(
						deleteCommand.getLabel());
				command.add(deleteCommand);
				Message message = (Message) selectedEObject;
				MessageEnd receiveEvent = message.getReceiveEvent();
				if (receiveEvent != null) {
					DestroyElementRequest myReq = new DestroyElementRequest(
							req.getEditingDomain(), receiveEvent, false);
					command.add(new DestroyElementCommand(myReq));
				}
				MessageEnd sendEvent = message.getSendEvent();
				if (sendEvent != null) {
					DestroyElementRequest myReq = new DestroyElementRequest(
							req.getEditingDomain(), sendEvent, false);
					command.add(new DestroyElementCommand(myReq));
				}
				
				addDeleteMessageRelatedTimeObservationLinkCommand(req.getEditingDomain(), editPart, command,
						receiveEvent,true);
				addDeleteMessageRelatedTimeObservationLinkCommand(req.getEditingDomain(), editPart, command,
						sendEvent,true);

				return new ICommandProxy(command);
			}
		}

		return UnexecutableCommand.INSTANCE;
	}
	
	/**
	 * Add delete message related time observation link command
	 * @param editingDomain
	 * @param editPart
	 * @param command
	 * @param messageEnd
	 * @param deleteRelatedEvent
	 */
	public static void addDeleteMessageRelatedTimeObservationLinkCommand(
			TransactionalEditingDomain editingDomain, EditPart editPart,
			CompositeCommand command, MessageEnd messageEnd,boolean deleteRelatedEvent) {
		//Bug fix: messageEnd maybe a Gate instance.
		if(messageEnd != null && messageEnd instanceof OccurrenceSpecification){
			OccurrenceSpecification occurrenceSpecification = (OccurrenceSpecification) messageEnd;
			EList<Lifeline> receiveCovereds = occurrenceSpecification.getCovereds();
			CompoundCommand CompoundCommand = new CompoundCommand();
			CompoundCommand.add(new ICommandProxy(command));
			LifelineEditPart srcLifelinePart = (LifelineEditPart) SequenceUtil.getEditPart(editPart,receiveCovereds.get(0), LifelineEditPart.class);
			addDeleteRelatedTimeObservationLinkCommand(CompoundCommand, editingDomain, occurrenceSpecification, srcLifelinePart,deleteRelatedEvent);
		}
	}

	/**
	 * Add command for deleting time observation link which related to occurence specification
	 * @param deleteViewsCmd
	 * @param editingDomain
	 * @param os
	 * @param srcLifelinePart
	 * @param deleteRelatedEvent
	 */
	private static void addDeleteRelatedTimeObservationLinkCommand(
			CompoundCommand deleteViewsCmd,
			TransactionalEditingDomain editingDomain, OccurrenceSpecification os,
			LifelineEditPart srcLifelinePart,boolean deleteRelatedEvent) {
		List<OccurrenceSpecification> oss = new ArrayList<OccurrenceSpecification>();
		oss.add(os);
		addDeleteRelatedTimeObservationLinkCommand(deleteViewsCmd, editingDomain,srcLifelinePart, oss,deleteRelatedEvent);
	}
	
	/**
	 * Add command for deleting time observation link which related to occurence specification
	 * @param deleteViewsCmd
	 * @param editingDomain
	 * @param srcLifelinePart
	 * @param oss
	 * @param deleteRelatedEvent
	 */
	public static void addDeleteRelatedTimeObservationLinkCommand(
			CompoundCommand deleteViewsCmd,
			TransactionalEditingDomain editingDomain,LifelineEditPart srcLifelinePart,List<OccurrenceSpecification> oss,boolean deleteRelatedEvent) {
		List<TimeObservationLabelEditPart> timeObservationEditParts = SequenceUtil.findOccurenceSpecificationRelatedTimeObservationPart(srcLifelinePart,oss);
		for (final TimeObservationLabelEditPart timeObservationEditPart : timeObservationEditParts) {
			View view = (View) timeObservationEditPart.getModel();
			EList sourceEdges = view.getSourceEdges();
			for (Object sourceEdge : sourceEdges) {
				Command deleteTimeViewCommand = new ICommandProxy(
						new DeleteCommand(editingDomain, (View) sourceEdge));
				deleteViewsCmd.add(deleteTimeViewCommand);
			}
			if(deleteRelatedEvent){
				deleteViewsCmd.add(new ICommandProxy(new AbstractTransactionalCommand(editingDomain,"Remove TimeObservation related event",null){
					@Override
					protected CommandResult doExecuteWithResult(
							IProgressMonitor monitor, IAdaptable info)
							throws ExecutionException {
						TimeObservation timeObservation = (TimeObservation)(timeObservationEditPart.resolveSemanticElement());
						timeObservation.setEvent(null);
						return CommandResult.newOKCommandResult();
					}
				}));
			}
		}
	}
	
}

Back to the top