Skip to main content
summaryrefslogtreecommitdiffstats
blob: 718f5cd32f2fcc95162f95d767dc3ea312f2f44b (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
/*****************************************************************************
 * Copyright (c) 2012, 2014 CEA LIST and others.
 *
 *    
 * 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:
 *  Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr - Initial API and implementation
 *  Christian W. Damus (CEA) - bug 323802
 *
 *****************************************************************************/
package org.eclipse.papyrus.uml.diagram.stereotype.edition.editpolicies;

import java.util.Iterator;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.gef.EditPart;
import org.eclipse.gmf.runtime.diagram.core.commands.DeleteCommand;
import org.eclipse.gmf.runtime.diagram.ui.editparts.BorderedBorderItemEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
import org.eclipse.gmf.runtime.notation.Bounds;
import org.eclipse.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.LayoutConstraint;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.papyrus.infra.gmfdiag.common.utils.GMFUnsafe;
import org.eclipse.papyrus.uml.appearance.helper.AppliedStereotypeHelper;
import org.eclipse.papyrus.uml.appearance.helper.UMLVisualInformationPapyrusConstant;
import org.eclipse.papyrus.uml.diagram.common.Activator;
import org.eclipse.papyrus.uml.diagram.common.editpolicies.AppliedStereotypeNodeLabelDisplayEditPolicy;
import org.eclipse.papyrus.uml.diagram.stereotype.edition.command.CreateAppliedStereotypeCommentViewCommand;
import org.eclipse.papyrus.uml.diagram.stereotype.edition.editpart.AppliedStereotypesCommentLinkEditPart;
import org.eclipse.papyrus.uml.tools.listeners.PapyrusStereotypeListener;
import org.eclipse.papyrus.uml.tools.utils.StereotypeUtil;
import org.eclipse.swt.widgets.Display;

/**
 * This editpolicy has in charge to :
 * - create or destroy the appliedStereotypesCommentEditpart
 * - adapt the information about stereotype display into appliedstereotypeCommentEditPart
 * by using eannotation existing mechanism
 * 
 */
public class AppliedStereotypeCommentCreationEditPolicy extends AppliedStereotypeNodeLabelDisplayEditPolicy {


	/** constant for this edit policy role */
	public final static String APPLIED_STEREOTYPE_COMMENT = "Applied_Stereotype_Comment";


	/**
	 * This method has in charge to refresh the presence of the view that represent the comment
	 */
	protected void updateAppliedStereotypeCommentShape() {
		String stereotypeLocalizationToDisplay = AppliedStereotypeHelper.getAppliedStereotypesPropertiesLocalization((View)getHost().getModel());
		String stereotypePropertiesToDisplay = AppliedStereotypeHelper.getAppliedStereotypesPropertiesToDisplay((View)getHost().getModel());
		//look for the AppliedStereotypesCommentEditPart
		if(getAppliedStereotypeCommentNode() == null && (!stereotypePropertiesToDisplay.trim().equals(""))) {
			//test if stereotype has to be display as a comment
			if(stereotypeLocalizationToDisplay.equals(UMLVisualInformationPapyrusConstant.STEREOTYPE_COMMENT_LOCATION)) {

				if(getHost() instanceof ConnectionEditPart) {
					executeAppliedStereotypeCommentCreation((ConnectionEditPart)getHost(), ((ConnectionEditPart)getHost()).getEditingDomain(), ((ConnectionEditPart)getHost()).resolveSemanticElement());
				}

				if(getHost() instanceof GraphicalEditPart) {
					executeAppliedStereotypeCommentCreation((GraphicalEditPart)getHost(), ((GraphicalEditPart)getHost()).getEditingDomain(), ((GraphicalEditPart)getHost()).resolveSemanticElement());
				}
			}
		}
		
		//test if the comment has to be removed
		if(getAppliedStereotypeCommentNode() != null) {
			View commentNode = getAppliedStereotypeCommentNode();
			
			//1. the  display is not comment
			if(!stereotypeLocalizationToDisplay.equals(UMLVisualInformationPapyrusConstant.STEREOTYPE_COMMENT_LOCATION) ) {
				final TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(commentNode);
				executeAppliedStereotypeCommentDeletion(domain, commentNode);
			}
			
			//the result of properties to display is null so no compartment will be created
			String todisplay = StereotypeUtil.getPropertiesValues(stereotypePropertiesToDisplay, getUMLElement()); 
			if("".equals(todisplay.trim())) {
				final TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(commentNode);
				executeAppliedStereotypeCommentDeletion(domain, commentNode);
			}
		}

	}

	/**
	 * return the number of visible compartment that represent a stereotype
	 * @param view the container view
	 * @param eobject the eobject that represent the container
	 * @return the number of visible stereotype compartment
	 */
	protected int getvisisbleAppliedStereotypeCompartment(View view, EObject eobject) {
		int nbVisibleCompartment = 0;
		@SuppressWarnings("unchecked")
		Iterator<View> iteratorView = view.getChildren().iterator();
		while(iteratorView.hasNext()) {
			View subview = (View)iteratorView.next();
			if(subview.getElement() != null && !subview.getElement().equals(eobject)) {
				nbVisibleCompartment++;
			}
		}
		return nbVisibleCompartment;
	}
/**
 * this method is use to copy all eAnnotation from the view to the comment in order to display properties of stereotype
 */
	protected void delegateEAnnotationInCommentShape() {
		final Node appliedStereotypeComment = getAppliedStereotypeCommentNode();

		if(appliedStereotypeComment != null) {
			View originView = getView();
			final EAnnotation stereotypeAnnotation = originView.getEAnnotation(UMLVisualInformationPapyrusConstant.STEREOTYPE_ANNOTATION);

			final TransactionalEditingDomain domain = TransactionUtil.getEditingDomain(originView);
			final RecordingCommand cmd = new RecordingCommand(domain, "EannotationDelegation") {

				@Override
				protected void doExecute() {
					EAnnotation stereotypeAnnotationCopy = EcoreUtil.copy(stereotypeAnnotation);
					appliedStereotypeComment.getEAnnotations().clear();
					appliedStereotypeComment.getEAnnotations().add(stereotypeAnnotationCopy);
					RecordingCommand cmd = AppliedStereotypeHelper.getSetAppliedStereotypePropertiesLocalizationCommand(domain, appliedStereotypeComment, UMLVisualInformationPapyrusConstant.STEREOTYPE_COMPARTMENT_LOCATION);
					cmd.execute();
					String presentationKind = AppliedStereotypeHelper.getAppliedStereotypePresentationKind(getView());
					cmd = AppliedStereotypeHelper.getRemoveAppliedStereotypeCommand(domain, appliedStereotypeComment, AppliedStereotypeHelper.getStereotypesToDisplay(appliedStereotypeComment), presentationKind);
					cmd.execute();
				}
			};
			
			Display.getCurrent().syncExec(new Runnable() {

				public void run() {
					//use to avoid to put it in the command stack
					try {
						GMFUnsafe.write(domain, cmd);
					} catch (Exception e) {
						Activator.log.error(e);
					}
				}
			});
		}
	}

	/**
	 * return the comment nodes that represent stereotype properties
	 * 
	 * @return may be null if nothing is founded
	 */
	protected Node getAppliedStereotypeCommentNode() {
		View SemanticView = (View)getHost().getModel();

		Edge appliedStereotypeLink = null;
		//look for all links with the id AppliedStereotypesCommentLinkEditPart.ID
		@SuppressWarnings("unchecked")
		Iterator<Edge> edgeIterator = SemanticView.getSourceEdges().iterator();
		while(edgeIterator.hasNext()) {
			Edge edge = (Edge)edgeIterator.next();
			if(edge.getType().equals(AppliedStereotypesCommentLinkEditPart.ID)) {
				appliedStereotypeLink = edge;
			}

		}
		if(appliedStereotypeLink == null) {
			return null;
		}
		return (Node)appliedStereotypeLink.getTarget();

	}

	/**
	 * the goal of this method is to execute the a command to create a notation node for applied stereotype
	 * as "Comment" shape
	 * 
	 * @param editPart
	 *        the semantic Editpart
	 * @param appliedstereotype
	 *        the stereotype application
	 */
	protected void executeAppliedStereotypeCommentCreation(final EditPart editPart, final TransactionalEditingDomain domain, final EObject semanticElement) {
		Display.getCurrent().syncExec(new Runnable() {

			public void run() {
				int x = 200;
				int y = 100;
				if(editPart.getModel() instanceof Node) {
					LayoutConstraint constraint = ((Node)editPart.getModel()).getLayoutConstraint();
					if(constraint instanceof Bounds) {
						x = x + ((Bounds)constraint).getX();
						y = ((Bounds)constraint).getY();
					}

				}
				if(editPart.getModel() instanceof Edge && ((((Edge)editPart.getModel()).getSource()) instanceof Node)) {

					LayoutConstraint constraint = ((Node)((Edge)editPart.getModel()).getSource()).getLayoutConstraint();
					if(constraint instanceof Bounds) {
						x = x + ((Bounds)constraint).getX();
						y = ((Bounds)constraint).getY() - 100;
					}

				}
				boolean isBorderElement = false;
				if(editPart instanceof BorderedBorderItemEditPart) {
					isBorderElement = true;
				}
				if(getAppliedStereotypeCommentNode() == null) {
					CreateAppliedStereotypeCommentViewCommand command = new CreateAppliedStereotypeCommentViewCommand(domain, (View)editPart.getModel(), x, y, semanticElement, isBorderElement);
					//use to avoid to put it in the command stack
					try {
						GMFUnsafe.write(domain, command);
					} catch (Exception e) {
						Activator.log.error(e);
					}
				}
			}

		});
	}
	/**
	 * method in oder to delete the comment
	 * @param domain the transactional editing domain
	 * @param commentNode the view that represent the comment of stereotype
	 */

	protected void executeAppliedStereotypeCommentDeletion(final TransactionalEditingDomain domain, final View commentNode) {
		Display.getCurrent().syncExec(new Runnable() {

			public void run() {
				//because it is asynchrone the comment node maybe become s null
				if(commentNode != null && TransactionUtil.getEditingDomain(commentNode) != null) {
					DeleteCommand command = new DeleteCommand(commentNode);
					//use to avoid to put it in the command stack
					try {
						GMFUnsafe.write(domain, command);
					} catch (Exception e) {
						Activator.log.error(e);
					}
				}
			}
		});
	}

	/**
	 * 
	 * {@inheritedDoc}
	 */
	@Override
	public void notifyChanged(Notification notification) {
		// change the label of the figure managed by the host edit part (managed
		// by the parent edit
		// part in general...)
		// it must be changed only if:
		// - the annotation corresponding to the display of the stereotype
		// changes
		// - the stereotype application list has changed
		final int eventType = notification.getEventType();
		if(eventType == PapyrusStereotypeListener.APPLIED_STEREOTYPE) {
			// a stereotype was applied to the notifier
			// then a new listener should be added to the stereotype application
			getDiagramEventBroker().addNotificationListener((EObject)notification.getNewValue(), this);
			//createAppliedStereotypeCompartment((EObject)notification.getNewValue());
		} else if(eventType == PapyrusStereotypeListener.UNAPPLIED_STEREOTYPE) {
			getDiagramEventBroker().removeNotificationListener((EObject)notification.getOldValue(), this);
			cleanStereotypeDisplayInEAnnotation();
			updateAppliedStereotypeCommentShape();

		}
		// if element that has changed is a stereotype => refresh the label.
		if(notification.getNotifier() instanceof View && (notification.getEventType() == Notification.ADD) && (notification.getNewValue() instanceof EAnnotation)) {
			if(UMLVisualInformationPapyrusConstant.STEREOTYPE_ANNOTATION == ((EAnnotation)notification.getNewValue()).getSource()) {
				// stereotype annotation has changed => refresh label display
				updateAppliedStereotypeCommentShape();
				delegateEAnnotationInCommentShape();
				//refreshDisplay();
			}
		}
		// if element that has changed is a stereotype => refresh the label.
		if(notification.getNotifier() instanceof EAnnotation && (notification.getEventType() == Notification.ADD)) {
			if(UMLVisualInformationPapyrusConstant.STEREOTYPE_ANNOTATION == ((EAnnotation)notification.getNotifier()).getSource()) {
				// stereotype annotation has changed => refresh label display
				updateAppliedStereotypeCommentShape();
				delegateEAnnotationInCommentShape();
			}
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void refreshDisplay() {
		//do nothing
		//refreshStereotypeDisplay();
	}

}

Back to the top