Skip to main content
summaryrefslogtreecommitdiffstats
blob: d37d7c6f7c62af445bea321ba5db11d4f4109cc5 (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
/*****************************************************************************
 * Copyright (c) 2012 CEA LIST.
 *
 *
 * 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
 *
 *****************************************************************************/
package org.eclipse.papyrus.uml.diagram.timing.custom.parts;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.Tool;
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.ICommand;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateConnectionViewAndElementRequest.ConnectionViewAndElementDescriptor;
import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.gmf.runtime.notation.Connector;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.papyrus.infra.gmfdiag.common.service.palette.AspectUnspecifiedTypeConnectionTool;
import org.eclipse.papyrus.infra.gmfdiag.common.service.palette.AspectUnspecifiedTypeConnectionTool.CreateAspectUnspecifiedTypeConnectionRequest;
import org.eclipse.papyrus.infra.gmfdiag.common.service.palette.AspectUnspecifiedTypeCreationTool;
import org.eclipse.papyrus.infra.gmfdiag.common.utils.FigureUtils;
import org.eclipse.papyrus.uml.diagram.timing.custom.Messages;
import org.eclipse.papyrus.uml.diagram.timing.custom.utils.EditPartUtils;
import org.eclipse.papyrus.uml.diagram.timing.custom.utils.MessageUtils;
import org.eclipse.papyrus.uml.diagram.timing.edit.parts.FullLifelineStateDefinitionCompartmentEditPartCN;
import org.eclipse.papyrus.uml.diagram.timing.part.UMLPaletteFactory;
import org.eclipse.papyrus.uml.diagram.timing.providers.UMLElementTypes;
import org.eclipse.uml2.uml.UMLPackage;

public class CustomPaletteFactory extends UMLPaletteFactory {

	private final static String CREATEOCCURRENCESPECIFICATIONCREATIONTOOL = "createOccurrenceSpecificationCreationTool"; //$NON-NLS-1$

	private final static String CREATEDESTRUCTIONOCCURRENCESPECIFICATIONCREATIONTOOL = "createDestructionOccurrenceSpecificationCreationTool"; //$NON-NLS-1$

	private final static String CREATESTATEDEFINITIONCREATIONTOOL = "createStateDefinitionCreationTool"; //$NON-NLS-1$

	private final static String CREATEMESSAGESYNCCREATIONTOOL = "createMessageSyncCreationTool"; //$NON-NLS-1$

	private final static String CREATEMESSAGEASYNCCREATIONTOOL = "createMessageAsyncCreationTool"; //$NON-NLS-1$

	private final static String CREATEMESSAGEREPLYCREATIONTOOL = "createMessageReplyCreationTool"; //$NON-NLS-1$

	private final static String CREATECREATEMESSAGECREATIONTOOL = "createCreateMessageCreationTool"; //$NON-NLS-1$

	private final static String CREATEDELETEMESSAGECREATIONTOOL = "createDeleteMessageCreationTool"; //$NON-NLS-1$

	private final static String CREATELOSTMESSAGECREATIONTOOL = "createLostMessageCreationTool"; //$NON-NLS-1$

	private final static String CREATEFOUNDMESSAGECREATIONTOOL = "createFoundMessageCreationTool"; //$NON-NLS-1$

	private final static String CREATETIMEOBSERVATIONCREATIONTOOL = "createTimeObservationCreationTool"; //$NON-NLS-1$

	private final static String CREATETIMECONSTRAINTCREATIONTOOL = "createTimeConstraintCreationTool"; //$NON-NLS-1$

	private final static String CREATEDURATIONOBSERVATIONCREATIONTOOL = "createDurationObservationCreationTool"; //$NON-NLS-1$

	private final static String CREATEDURATIONCONSTRAINTCREATIONTOOL = "createDurationConstraintCreationTool"; //$NON-NLS-1$

	private final static String CREATEGENERALORDERINGCREATIONTOOL = "createGeneralOrderingCreationTool"; //$NON-NLS-1$

	public static final String ORIGINAL_TARGET = "ORIGINAL_TARGET"; //$NON-NLS-1$

	@Override
	public Tool createTool(final String toolId) {
		if (toolId.equals(CREATEOCCURRENCESPECIFICATIONCREATIONTOOL)) {
			return createOccurrenceSpecificationCreationTool();
		} else if (toolId.equals(CREATEDESTRUCTIONOCCURRENCESPECIFICATIONCREATIONTOOL)) {
			return createDestructionOccurrenceSpecificationCreationTool();
		} else if (toolId.equals(CREATESTATEDEFINITIONCREATIONTOOL)) {
			return createStateDefinitionCreationTool();
		} else if (toolId.equals(CREATEMESSAGESYNCCREATIONTOOL)) {
			return createSyncMessageCreationTool();
		} else if (toolId.equals(CREATEMESSAGEASYNCCREATIONTOOL)) {
			return createAsyncMessageCreationTool();
		} else if (toolId.equals(CREATEMESSAGEREPLYCREATIONTOOL)) {
			return createReplyMessageCreationTool();
		} else if (toolId.equals(CREATECREATEMESSAGECREATIONTOOL)) {
			return createCreateMessageCreationTool();
		} else if (toolId.equals(CREATEDELETEMESSAGECREATIONTOOL)) {
			return createDeleteMessageCreationTool();
		} else if (toolId.equals(CREATELOSTMESSAGECREATIONTOOL)) {
			return createLostMessageCreationTool();
		} else if (toolId.equals(CREATEFOUNDMESSAGECREATIONTOOL)) {
			return createFoundMessageCreationTool();
		} else if (toolId.equals(CREATETIMEOBSERVATIONCREATIONTOOL)) {
			return createTimeObservationCreationTool();
		} else if (toolId.equals(CREATETIMECONSTRAINTCREATIONTOOL)) {
			return createTimeConstraintCreationTool();
		} else if (toolId.equals(CREATEDURATIONOBSERVATIONCREATIONTOOL)) {
			return createDurationObservationCreationTool();
		} else if (toolId.equals(CREATEDURATIONCONSTRAINTCREATIONTOOL)) {
			return createDurationConstraintCreationTool();
		} else if (toolId.equals(CREATEGENERALORDERINGCREATIONTOOL)) {
			return createNewGeneralOrderingCreationTool();
		}
		return super.createTool(toolId);
	}

	private static Tool createTimeObservationCreationTool() {
		return createNewTimeTool(UMLElementTypes.TimeObservation_Shape);
	}

	private static Tool createTimeConstraintCreationTool() {
		return createNewTimeTool(UMLElementTypes.TimeConstraint_Shape);
	}

	private static Tool createDurationObservationCreationTool() {
		return createNewDurationTool(UMLElementTypes.DurationObservation_Shape);
	}

	private static Tool createDurationConstraintCreationTool() {
		return createNewDurationTool(UMLElementTypes.DurationConstraint_Shape);
	}

	private static Tool createNewTimeTool(final IElementType elementType) {
		return new AspectUnspecifiedTypeCreationTool(Collections.singletonList(elementType)) {

			/**
			 * Redirect the creation request to the parent (Lifeline compartment), but keep the original target in the
			 * extended data for the creation command.
			 */
			@Override
			protected Command getCommand() {
				EditPart target = getTargetEditPart();
				final Request request = getTargetRequest();
				if (target != null && EditPartUtils.isEditPartFor(target, UMLPackage.eINSTANCE.getOccurrenceSpecification(), UMLPackage.eINSTANCE.getStateInvariant())) {
					@SuppressWarnings("unchecked")
					final Map<Object, Object> extendedData = request.getExtendedData();
					extendedData.put(ORIGINAL_TARGET, target);
					target = target.getParent();
					return target.getCommand(request);
				}
				return UnexecutableCommand.INSTANCE;
			}
		};
	}

	private static Tool createNewDurationTool(final IElementType elementType) {
		return new DurationCreationTool(elementType);
	}

	private static Tool createOccurrenceSpecificationCreationTool() {
		return new OccurrenceSpecificationCreationTool();
	}

	private static Tool createDestructionOccurrenceSpecificationCreationTool() {
		return new DestructionOccurrenceSpecificationCreationTool();
	}

	private static Tool createNewGeneralOrderingCreationTool() {
		return new GeneralOrderingCreationTool();
	}

	/** Overloaded to only let StateDefinitions be created in the StateDefinition compartment. */
	private static Tool createStateDefinitionCreationTool() {
		final List<IElementType> types = new ArrayList<IElementType>(1);
		types.add(UMLElementTypes.Node_StateDefinitionShape);

		final Tool tool = new AspectUnspecifiedTypeCreationTool(types) {

			@Override
			protected Command getCommand() {
				if (!(getTargetEditPart() instanceof FullLifelineStateDefinitionCompartmentEditPartCN)) {
					return UnexecutableCommand.INSTANCE;
				}
				return super.getCommand();
			}
		};
		return tool;
	}

	private static Tool createSyncMessageCreationTool() {
		return new SpecificTypeCreationTool(UMLElementTypes.Message_SynchEdge, MessageUtils.getAllowedMessageTargets(), MessageUtils.getAllowedMessageTargets());
	}

	private static Tool createAsyncMessageCreationTool() {
		return new SpecificTypeCreationTool(UMLElementTypes.Message_AsynchEdge, MessageUtils.getAllowedMessageTargets(), MessageUtils.getAllowedMessageTargets());
	}

	private static Tool createReplyMessageCreationTool() {
		return new SpecificTypeCreationTool(UMLElementTypes.Message_ReplyEdge, MessageUtils.getAllowedMessageTargets(), MessageUtils.getAllowedMessageTargets());
	}

	private static Tool createCreateMessageCreationTool() {
		return new SpecificTypeCreationTool(UMLElementTypes.Message_CreateEdge, MessageUtils.getAllowedMessageTargets(), MessageUtils.getAllowedMessageTargets());
	}

	private static Tool createDeleteMessageCreationTool() {
		return new SpecificTypeCreationTool(UMLElementTypes.Message_DeleteEdge, MessageUtils.getAllowedMessageTargets(), MessageUtils.getAllowedMessageTargets());
	}

	private static Tool createLostMessageCreationTool() {
		return new AspectUnspecifiedTypeConnectionTool(Collections.singletonList(UMLElementTypes.Message_LostEdge)) {

			@Override
			protected Command getCommand() {
				final Object type = getTargetRequest().getType();
				if (RequestConstants.REQ_CONNECTION_END == type) {
					final CreateAspectUnspecifiedTypeConnectionRequest request = (CreateAspectUnspecifiedTypeConnectionRequest) getTargetRequest();
					final EditPart sourceEditPart = request.getSourceEditPart();

					// Note: the bounds must be computed before executing the command because the source may be an
					// OccurrenceSpecification that will get swapped to a MessageOccurrenceSpecification, thereby
					// changing the Figure and EditPart.
					final IFigure figure = ((GraphicalEditPart) sourceEditPart).getFigure();
					final Point figureLocation = new Point(figure.getBounds().getCenter());
					figure.getParent().translateToAbsolute(figureLocation);
					final Point location = request.getLocation();
					final double scale = FigureUtils.getScale(figure);
					final Point anchorLocation = new Point(location.x - figureLocation.x, location.y - figureLocation.y).scale(1.0 / scale);

					final Command superCommand = super.getCommand();
					final CompoundCommand compoundCommand = new CompoundCommand();
					compoundCommand.add(superCommand);
					final TransactionalEditingDomain editingDomain = TransactionUtil.getEditingDomain(sourceEditPart.getModel());

					// add a command that sets the initial anchor position using an EAnnotation
					compoundCommand.add(new ICommandProxy(new AbstractTransactionalCommand(editingDomain, Messages.CustomPaletteFactory_SetLostMessageOrigin, null) {

						@Override
						protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
							final Connector connector = findCreatedConnector(superCommand);
							MessageUtils.setMessageConnectorLocation(connector, anchorLocation);
							return CommandResult.newOKCommandResult();
						}
					}));
					return compoundCommand;
				}
				return super.getCommand();
			}
		};
	}

	private static Tool createFoundMessageCreationTool() {
		return new AspectUnspecifiedTypeConnectionTool(Collections.singletonList(UMLElementTypes.Message_FoundEdge)) {

			@Override
			protected Command getCommand() {
				final CreateAspectUnspecifiedTypeConnectionRequest request = (CreateAspectUnspecifiedTypeConnectionRequest) getTargetRequest();
				final EditPart targetEditPart = request.getTargetEditPart();

				final Object type = getTargetRequest().getType();
				if (RequestConstants.REQ_CONNECTION_START == type) {
					MessageUtils.saveRequestStartLocation(request);
				}

				if (RequestConstants.REQ_CONNECTION_END == type) {
					final Point startLocation = MessageUtils.retrieveRequestStartLocation(request);

					// Note: the bounds must be computed before executing the command because the source may be an
					// OccurrenceSpecification that will get swapped to a MessageOccurrenceSpecification, thereby
					// changing the Figure and EditPart.
					final IFigure figure = ((GraphicalEditPart) targetEditPart).getFigure();
					final Point figureLocation = new Point(figure.getBounds().getCenter());
					figure.getParent().translateToAbsolute(figureLocation);
					final double scale = FigureUtils.getScale(figure);
					final Point anchorLocation = new Point(startLocation.x - figureLocation.x, startLocation.y - figureLocation.y).scale(1.0 / scale);

					final Command superCommand = super.getCommand();
					final CompoundCommand compoundCommand = new CompoundCommand();
					compoundCommand.add(superCommand);
					final TransactionalEditingDomain editingDomain = TransactionUtil.getEditingDomain(targetEditPart.getModel());

					// add a command that sets the initial anchor position using an EAnnotation
					compoundCommand.add(new ICommandProxy(new AbstractTransactionalCommand(editingDomain, Messages.CustomPaletteFactory_SetFoundMessageTarget, null) {

						@Override
						protected CommandResult doExecuteWithResult(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
							final Connector connector = findCreatedConnector(superCommand);
							MessageUtils.setMessageConnectorLocation(connector, anchorLocation);
							return CommandResult.newOKCommandResult();
						}
					}));
					return compoundCommand;
				}
				return super.getCommand();
			}
		};
	}

	/** Find the Connector in the haystack (buried deep in a CommandResult within the command). */
	protected static Connector findCreatedConnector(final Command command) {
		if (command instanceof ICommandProxy) {
			final ICommandProxy commandProxy = (ICommandProxy) command;
			final ICommand iCommand = commandProxy.getICommand();
			final CommandResult commandResult = iCommand.getCommandResult();
			final Object returnValue = commandResult.getReturnValue();
			if (returnValue instanceof List<?>) {
				final List<?> resultList = (List<?>) returnValue;
				for (final Object resultElement : resultList) {
					if (resultElement instanceof ConnectionViewAndElementDescriptor) {
						final ConnectionViewAndElementDescriptor connectionViewAndElementDescriptor = (ConnectionViewAndElementDescriptor) resultElement;
						final View view = (View) connectionViewAndElementDescriptor.getAdapter(View.class);
						if (view instanceof Connector) {
							final Connector connector = (Connector) view;
							return connector;
						}
					}
				}
			}
		}
		throw new IllegalStateException("connector not found"); //$NON-NLS-1$
	}
}

Back to the top