Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/commands/DuplicateDiagramCommand.java')
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/commands/DuplicateDiagramCommand.java238
1 files changed, 238 insertions, 0 deletions
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/commands/DuplicateDiagramCommand.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/commands/DuplicateDiagramCommand.java
new file mode 100644
index 00000000000..cd05de0e530
--- /dev/null
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/commands/DuplicateDiagramCommand.java
@@ -0,0 +1,238 @@
+/*****************************************************************************
+ * Copyright (c) 2011 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
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.gmfdiag.common.commands;
+
+import java.util.Collections;
+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.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.emf.commands.core.commands.DuplicateEObjectsCommand;
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.DiModel;
+import org.eclipse.papyrus.infra.emf.utils.BusinessModelResolver;
+import org.eclipse.papyrus.infra.gmfdiag.common.Activator;
+import org.eclipse.papyrus.infra.gmfdiag.common.model.NotationModel;
+
+
+/**
+ * Command to duplicate diagrams in model explorer. This adds the diagram to the resource containing the source diagram.
+ */
+public class DuplicateDiagramCommand extends DuplicateEObjectsCommand {
+
+ /** diagram to be duplicated */
+ private final Diagram diagramToDuplicate;
+
+ /**
+ * Constructs a new duplicate EObjects command with the specified label and
+ * list of EObjects.
+ *
+ * @param editingDomain
+ * the editing domain through which model changes are made
+ * @param label
+ * The label for the new command.
+ * @param diagram
+ * <code>Diagram</code> to be duplicated.
+ */
+ public DuplicateDiagramCommand(TransactionalEditingDomain editingDomain, String label, Diagram diagram) {
+ super(editingDomain, label, Collections.singletonList(diagram));
+ this.diagramToDuplicate = diagram;
+ }
+
+ /**
+ * Constructs a new duplicate EObjects command with the specified label and
+ * list of EObjects.
+ *
+ * @param editingDomain
+ * the editing domain through which model changes are made
+ * @param label
+ * The label for the new command.
+ * @param diagram
+ * <code>Diagram</code> to be duplicated.
+ * @param allDuplicatedObjectsMap
+ * An empty map to be populated with the duplicated objects.
+ */
+ public DuplicateDiagramCommand(TransactionalEditingDomain editingDomain, String label, Diagram diagram, Map allDuplicatedObjectsMap) {
+ super(editingDomain, label, Collections.singletonList(diagram), allDuplicatedObjectsMap);
+ this.diagramToDuplicate = diagram;
+ }
+
+ /**
+ * Constructs a new duplicate EObjects command with the specified label and
+ * list of EObjects. Also sets the list of affected files to be the files,
+ * where the targetContainer is stored. Target container specifies the
+ * eObject into which the duplicated eObjects will be added.
+ *
+ * @param editingDomain
+ * the editing domain through which model changes are made
+ * @param label
+ * The label for the new command.
+ * @param diagram
+ * <code>Diagram</code> to be duplicated.
+ * @param allDuplicatedObjectsMap
+ * An empty map to be populated with the duplicated objects.
+ */
+ public DuplicateDiagramCommand(TransactionalEditingDomain editingDomain, String label, Diagram diagram, Map allDuplicatedObjectsMap, EObject targetContainer) {
+ super(editingDomain, label, Collections.singletonList(diagram), allDuplicatedObjectsMap, targetContainer);
+ this.diagramToDuplicate = diagram;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected CommandResult doExecuteWithResult(IProgressMonitor progressMonitor, IAdaptable info) throws ExecutionException {
+ // Remove elements whose container is getting copied.
+ // ClipboardSupportUtil.getCopyElements(getObjectsToBeDuplicated());
+
+ // Perform the copy and update the references.
+ EcoreUtil.Copier copier = new DiagramCopier(getAllDuplicatedObjectsMap());
+ copier.copy(diagramToDuplicate);
+ copier.copyReferences();
+
+ EObject duplicateDiagram = copier.get(diagramToDuplicate);
+ Resource targetResource = getNotationResourceForDiagram(((Diagram)duplicateDiagram).getElement(), getEditingDomain());
+
+ if(targetResource != null) {
+ targetResource.getContents().add(duplicateDiagram);
+ } else {
+ Activator.log.warn("It was not possible to find the Resource with the target EObject"); //$NON-NLS-1$
+ targetResource = diagramToDuplicate.eResource();
+ if(targetResource != null) {
+ Activator.log.error("It was not possible to find the Resource with the source diagram", null); //$NON-NLS-1$
+ targetResource.getContents().add(duplicateDiagram);
+ }
+ }
+ return CommandResult.newOKCommandResult(getAllDuplicatedObjectsMap());
+ }
+
+ @Override
+ public boolean canExecute() {
+ // should add some tests here? no need to test containment feature like previous, Diagram has no owner...
+ return true;
+ }
+
+ /**
+ * Returns the notation resource where to add the new diagram
+ *
+ * @param eObject
+ * the semantic object linked to the diagram or the diagram itself.
+ * @param domain
+ * the editing domain
+ * @return the resource where the diagram should be added or <code>null</code> if no resource was found
+ * TODO this method should be handled by the resource plugin.
+ */
+ public Resource getNotationResourceForDiagram(EObject eObject, TransactionalEditingDomain domain) {
+ Object object = BusinessModelResolver.getInstance().getBusinessModel(eObject);
+ EObject semanticObject;
+ if(!(object instanceof EObject)) {
+ semanticObject = eObject;
+ } else {
+ semanticObject = (EObject)object;
+ }
+
+ Resource containerResource = semanticObject.eResource();
+ if(containerResource == null) {
+ return null;
+ }
+ // retrieve the model set from the container resource
+ ResourceSet resourceSet = containerResource.getResourceSet();
+
+ if(resourceSet instanceof ModelSet) {
+ ModelSet modelSet = (ModelSet)resourceSet;
+ Resource destinationResource = modelSet.getAssociatedResource(semanticObject, NotationModel.NOTATION_FILE_EXTENSION, true);
+ return destinationResource;
+ } else {
+ throw new RuntimeException("Resource Set is not a ModelSet or is null"); //$NON-NLS-1$
+ }
+ }
+
+
+ /**
+ * Returns the di resource where to add the new diagram
+ *
+ * @param eObject
+ * the semantic object linked to the diagram or the diagram itself.
+ * @param domain
+ * the editing domain
+ * @return the resource where the diagram should be added or <code>null</code> if no resource was found
+ */
+ public Resource getDiResourceForDiagram(EObject eObject, TransactionalEditingDomain domain) {
+ Object object = BusinessModelResolver.getInstance().getBusinessModel(eObject);
+ EObject semanticObject;
+ if(!(object instanceof EObject)) {
+ semanticObject = eObject;
+ } else {
+ semanticObject = (EObject)object;
+ }
+
+ Resource containerResource = semanticObject.eResource();
+ if(containerResource == null) {
+ return null;
+ }
+ // retrieve the model set from the container resource
+ ResourceSet resourceSet = containerResource.getResourceSet();
+
+ if(resourceSet instanceof ModelSet) {
+ ModelSet modelSet = (ModelSet)resourceSet;
+ Resource destinationResource = modelSet.getAssociatedResource(semanticObject, DiModel.MODEL_FILE_EXTENSION, true);
+ return destinationResource;
+ } else {
+ throw new RuntimeException("Resource Set is not a ModelSet or is null"); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Copier for diagrams, where only views and internal references are duplicated, not the semantic elements themselves.
+ */
+ protected class DiagramCopier extends EcoreUtil.Copier {
+
+ /** Serial UUID */
+ private static final long serialVersionUID = 8544123249170461708L;
+
+ /** semantic objects referenced by the views in the diagram */
+ private Map<EObject, EObject> semanticObjects;
+
+ /**
+ * Creates a new {@link DiagramCopier}
+ *
+ * @param semanticObjects
+ * list of semantic objects already copied, to which new views should be related.
+ */
+ public DiagramCopier(Map<EObject, EObject> semanticObjects) {
+ this.semanticObjects = semanticObjects;
+ }
+
+ /**
+ * Overrides the get to look in the map of duplicated semantic objects in case the element was not found in this map
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ public EObject get(Object arg0) {
+ EObject object = super.get(arg0);
+ if(object == null) {
+ object = semanticObjects.get(arg0);
+ }
+ return object;
+ }
+ }
+}

Back to the top