Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 3099c9ced89aedaec36597350ed210c1d29e9081 (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
/*****************************************************************************
 * Copyright (c) 2010 CEA
 *
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *   Atos Origin - Initial API and implementation
 *
 *****************************************************************************/
package org.eclipse.papyrus.uml.diagram.sequence.edit.policies;

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

import org.eclipse.draw2d.geometry.Point;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.commands.Command;
import org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionNodeEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.CreationEditPolicy;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest;
import org.eclipse.gmf.runtime.emf.type.core.IHintedType;
import org.eclipse.papyrus.uml.diagram.sequence.edit.parts.LifelineEditPart;
import org.eclipse.papyrus.uml.diagram.sequence.providers.UMLElementTypes;
import org.eclipse.papyrus.uml.diagram.sequence.util.SequenceRequestConstant;
import org.eclipse.papyrus.uml.diagram.sequence.util.SequenceUtil;
import org.eclipse.uml2.uml.OccurrenceSpecification;

public class CreationOnMessageEditPolicy extends CreationEditPolicy {

	/**
	 * TODO_MIA: CHeck if necessary
	 * Get the command after updating the request with appropriate occurrences
	 *
	 * @see org.eclipse.gmf.runtime.diagram.ui.editpolicies.CreationEditPolicy#getCreateElementAndViewCommand(org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewAndElementRequest)
	 *
	 * @param request
	 *            the request
	 * @return command or null
	 */
	@Override
	protected Command getCreateElementAndViewCommand(CreateViewAndElementRequest request) {
		Map<String, Object> extendedData = request.getExtendedData();
		// record the nearest event if necessary
		String requestHint = request.getViewAndElementDescriptor().getSemanticHint();
		if (isCreatedOnOccurrenceSpecification(requestHint)) {
			EditPart hostPart = getHost();
			if (hostPart instanceof ConnectionNodeEditPart) {
				LifelineEditPart sourceLifeline = SequenceUtil.getParentLifelinePart(((ConnectionNodeEditPart) hostPart).getSource());
				LifelineEditPart targetLifeline = SequenceUtil.getParentLifelinePart(((ConnectionNodeEditPart) hostPart).getTarget());
				Entry<Point, List<OccurrenceSpecification>> eventAndLocation = null;
				if (sourceLifeline != null) {
					eventAndLocation = SequenceUtil.findNearestEvent(request.getLocation(), sourceLifeline);
				}
				if (targetLifeline != null && eventAndLocation == null) {
					eventAndLocation = SequenceUtil.findNearestEvent(request.getLocation(), targetLifeline);
				}
				// find an event near enough to create the constraint or observation
				List<OccurrenceSpecification> events = Collections.emptyList();
				Point location = null;
				if (eventAndLocation != null) {
					location = eventAndLocation.getKey();
					events = eventAndLocation.getValue();
				}
				if (extendedData.containsKey(SequenceRequestConstant.NEAREST_OCCURRENCE_SPECIFICATION_2)) {
					extendedData.put(SequenceRequestConstant.NEAREST_OCCURRENCE_SPECIFICATION_2, events);
				} else {
					extendedData.put(org.eclipse.papyrus.uml.service.types.utils.SequenceRequestConstant.NEAREST_OCCURRENCE_SPECIFICATION, events);
				}
				if (extendedData.containsKey(SequenceRequestConstant.OCCURRENCE_SPECIFICATION_LOCATION_2)) {
					extendedData.put(SequenceRequestConstant.OCCURRENCE_SPECIFICATION_LOCATION_2, location);
				} else {
					extendedData.put(SequenceRequestConstant.OCCURRENCE_SPECIFICATION_LOCATION, location);
				}
				if (location != null) {
					// Let the hosted lifeline to do it.
					EditPart object = getHost().getViewer().findObjectAtExcluding(location, Collections.emptyList(), new EditPartViewer.Conditional() {

						@Override
						public boolean evaluate(EditPart editpart) {
							return editpart instanceof LifelineEditPart;
						}
					});
					LifelineEditPart targetEditPart = null;
					if (object instanceof LifelineEditPart) {
						targetEditPart = (LifelineEditPart) object;
					} else {
						while (object != null) {
							if (object.getParent() instanceof LifelineEditPart) {
								targetEditPart = (LifelineEditPart) object.getParent();
								break;
							}
							object = object.getParent();
						}
					}
					if (targetEditPart != null) {
						return targetEditPart.getCommand(request);
					}
				}
			}
		}
		return super.getCreateElementAndViewCommand(request);
	}

	/**
	 * Return true if creation must be performed on an occurrence specification
	 *
	 * @param requestHint
	 *            the hint of object to create
	 * @return true if creation on an occurrence specification
	 */
	private boolean isCreatedOnOccurrenceSpecification(String requestHint) {
		return isTimeHint(requestHint);
	}

	/**
	 * Return true if hint is for creating a time observation/constraint
	 *
	 * @param requestHint
	 *            the hint of object to create
	 * @return true if correct hint
	 */
	private boolean isTimeHint(String requestHint) {
		String timeConstraintHint = ((IHintedType) UMLElementTypes.TimeConstraint_Shape).getSemanticHint();
		String timeObservationHint = ((IHintedType) UMLElementTypes.TimeObservation_Shape).getSemanticHint();
		return timeConstraintHint.equals(requestHint) || timeObservationHint.equals(requestHint);
	}
}

Back to the top