Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: e78efeb1eded04923e095ee80649ceaffa827268 (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
/*****************************************************************************
 * Copyright (c) 2014 CEA LIST.
 *
 * 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:
 *  Benoit Maggi (CEA LIST) benoit.maggi@cea.fr - Initial API and implementation
 *****************************************************************************/
package org.eclipse.papyrus.infra.gmfdiag.common.strategy.paste;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.papyrus.infra.core.clipboard.IClipboardAdditionalData;
import org.eclipse.papyrus.infra.core.clipboard.PapyrusClipboard;
import org.eclipse.papyrus.infra.gmfdiag.common.Activator;
import org.eclipse.papyrus.infra.gmfdiag.common.commands.InsertDiagramCommand;
import org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramUtils;


/**
 * Offer a copy/paste strategy for diagram in model explorer.
 */
public class DiagramPasteStrategy extends AbstractPasteStrategy implements IPasteStrategy {

	/** key to store diagrams with no owner */
	protected static final String DIAGRAM_WITH_NO_OWNER = "DIAGRAM_WITH_NO_OWNER"; //$NON-NLS-1$

	/** The instance. */
	private static IPasteStrategy instance = new DiagramPasteStrategy();

	/**
	 * Gets the single instance of DiagramPasteStrategy.
	 *
	 * @return single instance of DiagramPasteStrategy
	 */
	public static IPasteStrategy getInstance() {
		return instance;
	}


	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.papyrus.infra.gmfdiag.common.strategy.paste.IPasteStrategy#getLabel()
	 */
	@Override
	public String getLabel() {
		return "Diagram Strategy"; //$NON-NLS-1$
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.papyrus.infra.gmfdiag.common.strategy.paste.IPasteStrategy#getID()
	 */
	@Override
	public String getID() {
		return Activator.ID + ".DiagramStrategy"; //$NON-NLS-1$
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.papyrus.infra.gmfdiag.common.strategy.paste.IPasteStrategy#getDescription()
	 */
	@Override
	public String getDescription() {
		return "Copy Diagrams in model explorer"; //$NON-NLS-1$
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.papyrus.infra.gmfdiag.common.strategy.paste.IPasteStrategy#getSemanticCommand(org.eclipse.emf.edit.domain.EditingDomain,
	 * org.eclipse.emf.ecore.EObject, org.eclipse.papyrus.infra.core.clipboard.PapyrusClipboard)
	 */
	@Override
	public org.eclipse.emf.common.command.Command getSemanticCommand(final EditingDomain domain, final EObject targetOwner, PapyrusClipboard<Object> papyrusClipboard) {
		CompoundCommand compoundCommand = new CompoundCommand("Copy all Diagrams"); //$NON-NLS-1$

		Map internalClipboardToTargetCopy = papyrusClipboard.getInternalClipboardToTargetCopy();
		Map<Object, ?> additionalDataMap = papyrusClipboard.getAdditionalDataForStrategy(getID());
		if (additionalDataMap != null) {
			Object additionalData = additionalDataMap.get(DIAGRAM_WITH_NO_OWNER);
			if (additionalData instanceof DiagramClipboardAdditionalData) {
				DiagramClipboardAdditionalData diagramClipboardAdditionnalData = (DiagramClipboardAdditionalData) additionalData;
				Collection<Diagram> duplicateDiagrams = diagramClipboardAdditionnalData.getDuplicatedDiagrams(internalClipboardToTargetCopy);
				for (final Diagram diagram : duplicateDiagrams) {
					org.eclipse.emf.common.command.Command command = new InsertDiagramCommand((TransactionalEditingDomain) domain, "Insert a diagram with no source owner", diagram, targetOwner); //$NON-NLS-1$
					compoundCommand.append(command);
				}
			}

			for (Iterator<Object> iterator = papyrusClipboard.iterator(); iterator.hasNext();) {
				Object object = iterator.next();
				// get target Element
				EObject target = papyrusClipboard.getTragetCopyFromInternalClipboardCopy(object);
				if (target != null && target instanceof EObject) {
					// get affiliate additional data
					additionalData = additionalDataMap.get(object);
					if (additionalData instanceof DiagramClipboardAdditionalData) {
						DiagramClipboardAdditionalData diagramClipboardAdditionalData = (DiagramClipboardAdditionalData) additionalData;
						Collection<Diagram> diagrams = diagramClipboardAdditionalData.getDuplicatedDiagrams(internalClipboardToTargetCopy);
						// duplicate diagrams
						for (final Diagram diagram : diagrams) {
							org.eclipse.emf.common.command.Command command = new InsertDiagramCommand((TransactionalEditingDomain) domain, "InsertDiagramCommand", diagram, target); //$NON-NLS-1$
							compoundCommand.append(command);
						}
					}
				}
			}
		}

		// An empty compound Command can't be executed
		if (compoundCommand.getCommandList().isEmpty()) {
			return null;
		}
		return compoundCommand;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.papyrus.infra.gmfdiag.common.strategy.paste.IPasteStrategy#dependsOn()
	 */
	@Override
	public IPasteStrategy dependsOn() {
		return DefaultPasteStrategy.getInstance();
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.papyrus.infra.gmfdiag.common.strategy.paste.IPasteStrategy#prepare(org.eclipse.papyrus.infra.core.clipboard.PapyrusClipboard)
	 */
	@Override
	public void prepare(PapyrusClipboard<Object> papyrusClipboard, Collection<EObject> selection) {
		Map<Object, IClipboardAdditionalData> mapCopyToClipboardAdditionalData = new HashMap<Object, IClipboardAdditionalData>();
		Map sourceToInternalClipboard = papyrusClipboard.getSourceToInternalClipboard();
		List<Diagram> extractSelectedWithoutOwner = extractDiagramWithoutOwner(selection);
		if (extractSelectedWithoutOwner != null && !extractSelectedWithoutOwner.isEmpty()) {
			DiagramClipboardAdditionalData diagramAdditionnalData = new DiagramClipboardAdditionalData(extractSelectedWithoutOwner, sourceToInternalClipboard);
			mapCopyToClipboardAdditionalData.put(DIAGRAM_WITH_NO_OWNER, diagramAdditionnalData);
		}

		for (Iterator<EObject> iterator = papyrusClipboard.iterateOnSource(); iterator.hasNext();) {
			EObject eObjectSource = iterator.next();
			ResourceSet resourceSet = eObjectSource.eResource().getResourceSet();
			List<Diagram> associatedDiagrams = DiagramUtils.getAssociatedDiagrams(eObjectSource, resourceSet);
			if (associatedDiagrams != null) {
				DiagramClipboardAdditionalData diagramAdditionnalData = new DiagramClipboardAdditionalData(associatedDiagrams, sourceToInternalClipboard);
				Object copy = papyrusClipboard.getCopyFromSource(eObjectSource);
				mapCopyToClipboardAdditionalData.put(copy, diagramAdditionnalData);
			}

		}
		papyrusClipboard.pushAdditionalData(getID(), mapCopyToClipboardAdditionalData);
	}


	/**
	 * Extract Diagram which owner is not in the selection
	 *
	 * @param selection
	 * @return
	 */
	protected List<Diagram> extractDiagramWithoutOwner(Collection<EObject> selection) {
		List<Diagram> diagramWithoutOwnerInSelection = new ArrayList<Diagram>();
		if (selection != null) {
			for (EObject eObject : selection) {
				if (eObject instanceof Diagram) {
					Diagram diagram = (Diagram) eObject;
					EObject element = diagram.getElement();
					if (!selection.contains(element)) {
						diagramWithoutOwnerInSelection.add(diagram);
					}
				}
			}
		}
		return diagramWithoutOwnerInSelection;
	}


	protected class DiagramClipboardAdditionalData implements IClipboardAdditionalData {

		/** The diagrams. */
		protected Collection<Diagram> diagrams;

		/**
		 * @param diagramCopier
		 * @param diagrams
		 */
		public DiagramClipboardAdditionalData(Collection<Diagram> diagrams, Map<? extends EObject, ? extends EObject> alreadyCopied) {
			this.diagrams = duplicateDiagrams(diagrams, alreadyCopied);
		}

		/**
		 * @return
		 */
		public Collection<Diagram> getDuplicatedDiagrams(Map<? extends EObject, ? extends EObject> alreadyCopied) {
			return duplicateDiagrams(this.diagrams, alreadyCopied);
		}

		/**
		 * @param diagrams
		 *            to duplicate
		 * @param alreadyCopied
		 * @return duplicated diagrams
		 */
		protected Collection<Diagram> duplicateDiagrams(Collection<Diagram> diagrams, Map<? extends EObject, ? extends EObject> alreadyCopied) {
			Collection<Diagram> duplicatedDiagrams = new ArrayList<Diagram>();
			EcoreUtil.Copier copier = new EcoreUtil.Copier();
			copier.putAll(alreadyCopied);
			for (Diagram diagram : diagrams) {
				copier.copy(diagram);
				copier.copyReferences();
				EObject copy = copier.get(diagram);
				if (copy instanceof Diagram) {
					duplicatedDiagrams.add((Diagram) copy);
				}
			}
			return duplicatedDiagrams;
		}
	}

}

Back to the top