summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenoit Maggi2014-04-30 09:47:18 (EDT)
committerCamille Letavernier2014-05-13 11:48:13 (EDT)
commitdeaec2a96cd6f01c51c876a6160fc782cd1293b5 (patch)
tree266a23742f075c2dd23704b9cf77d15501724aae
parent36c7009a5ca5bc1aa0f408bf19b7e802640a714d (diff)
downloadorg.eclipse.papyrus-deaec2a96cd6f01c51c876a6160fc782cd1293b5.zip
org.eclipse.papyrus-deaec2a96cd6f01c51c876a6160fc782cd1293b5.tar.gz
org.eclipse.papyrus-deaec2a96cd6f01c51c876a6160fc782cd1293b5.tar.bz2
Bug 413802 – Cannot copy & paste model using Project Explorerrefs/changes/41/24641/9
Add copy/paste action for papyrus model in projectExplorer (Handler/Command don't seem to be able to override paste action) Change-Id: I5d2f5630d75c65e08fe8fb67cb3e383150591feb Signed-off-by: Benoit Maggi <benoit.maggi@cea.fr>
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/DependencyManagementHelper.java95
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/IURIReplacementStrategy.java28
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/MoveFileURIReplacementStrategy.java144
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/ReplacementImpl.java72
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/RestoreDependencyHelper.java132
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ResourceUtils.java188
-rw-r--r--plugins/infra/org.eclipse.papyrus.infra.onefile/META-INF/MANIFEST.MF51
-rw-r--r--plugins/infra/org.eclipse.papyrus.infra.onefile/plugin.xml596
-rw-r--r--plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/action/CopyFilesAndFoldersOperation.java1959
-rw-r--r--plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/action/PapyrusCopyFilesAndFoldersOperation.java190
-rw-r--r--plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/action/PapyrusModelPasteAction.java50
-rw-r--r--plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/action/PasteAction.java266
-rw-r--r--plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/providers/CopyToClipboardAction.java70
-rw-r--r--plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/providers/PapyrusEditActionProvider.java147
-rw-r--r--plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/providers/PapyrusModelActionProvider.java964
-rw-r--r--plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/testers/PapyrusClipboardTester.java77
16 files changed, 4083 insertions, 946 deletions
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/DependencyManagementHelper.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/DependencyManagementHelper.java
index e97eb3d..65d9a2f 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/DependencyManagementHelper.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/DependencyManagementHelper.java
@@ -1,6 +1,6 @@
/*****************************************************************************
* Copyright (c) 2013 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
@@ -35,21 +35,21 @@ import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
/**
* A Helper to edit dependencies (URIs) between EMF Resources
- *
+ *
* It replaces all references from a Resource A to a Resource B with references from A to B'
- *
+ *
* B and B' must be "equivalent" (e.g. B is a copy of B' with or without modifications).
- *
+ *
* @author Camille Letavernier
- *
+ *
*/
public class DependencyManagementHelper {
/**
* Replaces all references (dependencies) in the "fromResources" to the "uriToReplace" URI, with the "targetURI"
- *
+ *
* Simplified pseudo code algorithm: fromResources.replaceAll(uriToReplace, targetURI)
- *
+ *
* @param uriToReplace
* The URI of the resource which initially contains the referenced elements. May or may not exist.
* Must not be null
@@ -62,7 +62,7 @@ public class DependencyManagementHelper {
* Must not be empty
* @param editingDomain
* The editing domain. May be null.
- *
+ *
* @return
* The collection of replacements
*/
@@ -90,9 +90,9 @@ public class DependencyManagementHelper {
/**
* Replaces all references (dependencies) in the "fromResources" to the "uriToReplace" URI, with the "targetURI"
- *
+ *
* Simplified pseudo code algorithm: fromResources.replaceAll(uriToReplace, targetURI)
- *
+ *
* @param uriToReplace
* The URI of the resource which initially contains the referenced elements. May or may not exist.
* Must not be null
@@ -197,7 +197,7 @@ public class DependencyManagementHelper {
/**
* Replaces the EObject (Which may be a proxy) by its equivalent in the given Resource's URI.
* Returns null if the "currentValueToReplace" doesn't belong to the resource represented by "uriToReplace".
- *
+ *
* @param currentValueToReplace
* The current value, to be replaced. May be a proxy
* @param uriToReplace
@@ -221,7 +221,7 @@ public class DependencyManagementHelper {
/**
* Replaces the EObject (Which may be a proxy) by its equivalent in the given Resource's URI.
- *
+ *
* @param currentValueToReplace
* The current value, to be replaced. May be a proxy
* @param targetURI
@@ -255,9 +255,9 @@ public class DependencyManagementHelper {
/**
* Replaces all references (dependencies) in the "resourceSet" to the "uriToReplace" URI, with the "targetURI"
- *
+ *
* Simplified pseudo code algorithm: resourceSet.getResources().replaceAll(uriToReplace, targetURI)
- *
+ *
* @param uriToReplace
* The URI of the resource which initially contains the referenced elements. May or may not exist.
* Must not be null
@@ -283,9 +283,9 @@ public class DependencyManagementHelper {
/**
* Replaces all references (dependencies) in the "fromResources" to the "uriToReplace" URI, with the "targetURI"
- *
+ *
* Simplified pseudo code algorithm: fromResources.replaceAll(uriToReplace, targetURI)
- *
+ *
* @param uriToReplace
* The URI of the resource which initially contains the referenced elements. May or may not exist.
* Must not be null
@@ -305,9 +305,9 @@ public class DependencyManagementHelper {
/**
* Replaces all references (dependencies) in the "fromResource" to the "uriToReplace" URI, with the "targetURI"
- *
+ *
* Simplified pseudo code algorithm: fromResource.replaceAll(uriToReplace, targetURI)
- *
+ *
* @param uriToReplace
* The URI of the resource which initially contains the referenced elements. May or may not exist.
* Must not be null
@@ -327,9 +327,9 @@ public class DependencyManagementHelper {
/**
* Replaces all references (dependencies) in the "resourceSet" to the "uriToReplace" URI, with the "targetURI"
- *
+ *
* Simplified pseudo code algorithm: resourceSet.getResources().replaceAll(uriToReplace, targetURI)
- *
+ *
* @param uriToReplace
* The URI of the resource which initially contains the referenced elements. May or may not exist.
* Must not be null
@@ -347,59 +347,4 @@ public class DependencyManagementHelper {
return updateDependencies(uriToReplace, targetURI, resourcesToEdit, null);
}
- private static class ReplacementImpl implements Replacement {
-
- private EObject parent;
-
- private EStructuralFeature property;
-
- private EObject oldValue;
-
- private EObject newValue;
-
- public ReplacementImpl(EObject parent, EStructuralFeature property, EObject oldValue, EObject newValue) {
- this.parent = parent;
- this.property = property;
- this.oldValue = oldValue;
- this.newValue = newValue;
- }
-
- public EObject getEObject() {
- return parent;
- }
-
- public EStructuralFeature getEStructuralFeature() {
- return property;
- }
-
- public EObject get(boolean resolve) {
- if(resolve && newValue != null && newValue.eIsProxy()) {
- newValue = EcoreUtil.resolve(newValue, parent);
- }
-
- return newValue;
- }
-
- public void set(Object newValue) {
- throw new UnsupportedOperationException();
- }
-
- public boolean isSet() {
- return newValue != null;
- }
-
- public void unset() {
- throw new UnsupportedOperationException();
- }
-
- public EObject getOldValue() {
- return oldValue;
- }
-
- @Override
- public String toString() {
- return String.format("%s replaced with %s", EcoreUtil.getURI(oldValue), EcoreUtil.getURI(newValue));
- }
- }
-
}
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/IURIReplacementStrategy.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/IURIReplacementStrategy.java
new file mode 100644
index 0000000..65e3d46
--- /dev/null
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/IURIReplacementStrategy.java
@@ -0,0 +1,28 @@
+/*****************************************************************************
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Benoit Maggi benoit.maggi@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.emf.resource;
+
+import org.eclipse.emf.common.util.URI;
+
+
+/**
+ * Interface for different strategies to change URI of a Resource
+ *
+ */
+public interface IURIReplacementStrategy {
+
+ URI getReplacementCandidate(URI resourceURI);
+
+}
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/MoveFileURIReplacementStrategy.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/MoveFileURIReplacementStrategy.java
new file mode 100644
index 0000000..81f59eb
--- /dev/null
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/MoveFileURIReplacementStrategy.java
@@ -0,0 +1,144 @@
+/*****************************************************************************
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Benoit Maggi benoit.maggi@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+
+package org.eclipse.papyrus.infra.emf.resource;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.URIConverter;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+
+
+/**
+ * The Class MoveFileURIReplacementStrategy.
+ */
+public class MoveFileURIReplacementStrategy implements IURIReplacementStrategy {
+
+
+ /** The replacement uri mapping. */
+ protected Map<URI, URI> replacementURIMapping;
+
+ /** The source path. */
+ protected IPath sourcePath;
+
+ /** The target path. */
+ protected IPath targetPath;
+
+ /**
+ * Instantiates a new move file uri replacement strategy.
+ *
+ * @param replacementURIMapping
+ * the replacement uri mapping
+ * @param sourcePath
+ * the source path
+ * @param targetPath
+ * the target path
+ */
+ public MoveFileURIReplacementStrategy(Map<URI, URI> replacementURIMapping, IPath sourcePath, IPath targetPath) {
+ this.replacementURIMapping = replacementURIMapping;
+ this.sourcePath = sourcePath;
+ this.targetPath = targetPath;
+ }
+
+ /**
+ * Instantiates a new move file uri replacement strategy.
+ *
+ * @param sourcePath
+ * the source path
+ * @param targetPath
+ * the target path
+ */
+ public MoveFileURIReplacementStrategy(IPath sourcePath, IPath targetPath) {
+ this(new HashMap<URI, URI>(), sourcePath, targetPath);
+ }
+
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.infra.emf.resource.IURIReplacementStrategy#getReplacementCandidate(org.eclipse.emf.common.util.URI)
+ */
+ public URI getReplacementCandidate(URI resourceURI) {
+ if(replacementURIMapping.containsKey(resourceURI)) {
+ return replacementURIMapping.get(resourceURI);
+ }
+ URI calculateUri = calculateNewUri(resourceURI);
+ replacementURIMapping.put(resourceURI, calculateUri);
+ return calculateUri;
+ }
+
+
+ /**
+ * Calculate uri.
+ *
+ * @param resourceURI
+ * the resource uri
+ * @return the uri
+ */
+ protected URI calculateNewUri(URI resourceURI) {
+ ModelSet modelSet = new ModelSet();
+ URIConverter uriConverter = modelSet.getURIConverter();
+ boolean exists = uriConverter.exists(resourceURI, Collections.EMPTY_MAP);
+ if(!exists) {
+ URI choseCorrectPath = trySourcePath(sourcePath, targetPath, resourceURI);
+ if(choseCorrectPath != null) {
+ return choseCorrectPath;
+ }
+ }
+ return resourceURI;
+ }
+
+
+
+
+ /**
+ * If the resource is not found in the target location then look in the source location
+ *
+ * @param sourcePath
+ * the source path
+ * @param targetPath
+ * the target path
+ * @param resourceURI
+ * the resource uri
+ * @return the uri
+ */
+ protected URI trySourcePath(IPath sourcePath, IPath targetPath, URI resourceURI) {
+ String uriPlatformString = resourceURI.toPlatformString(true);
+ if(uriPlatformString != null) {
+ Path path = new Path(uriPlatformString);
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ IFile file = root.getFile(path);
+ if(!file.exists()) {// test file non existence from the target
+ // calculate a new path from source path
+ URI sourceURI = URI.createPlatformResourceURI(sourcePath.toString()+Path.SEPARATOR, true);
+ URI targetURI = URI.createPlatformResourceURI(targetPath.toString()+Path.SEPARATOR, true);
+ URI resourceDeresolved = resourceURI.deresolve(targetURI);
+ URI resourceResolved = resourceDeresolved.resolve(sourceURI);
+ return resourceResolved;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/ReplacementImpl.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/ReplacementImpl.java
new file mode 100644
index 0000000..6eafbfb
--- /dev/null
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/ReplacementImpl.java
@@ -0,0 +1,72 @@
+/*****************************************************************************
+ * Copyright (c) 2013 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.resource;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+
+
+public class ReplacementImpl implements Replacement {
+
+ private EObject parent;
+
+ private EStructuralFeature property;
+
+ private EObject oldValue;
+
+ private EObject newValue;
+
+ public ReplacementImpl(EObject parent, EStructuralFeature property, EObject oldValue, EObject newValue) {
+ this.parent = parent;
+ this.property = property;
+ this.oldValue = oldValue;
+ this.newValue = newValue;
+ }
+
+ public EObject getEObject() {
+ return parent;
+ }
+
+ public EStructuralFeature getEStructuralFeature() {
+ return property;
+ }
+
+ public EObject get(boolean resolve) {
+ if(resolve && newValue != null && newValue.eIsProxy()) {
+ newValue = EcoreUtil.resolve(newValue, parent);
+ }
+
+ return newValue;
+ }
+
+ public void set(Object newValue) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isSet() {
+ return newValue != null;
+ }
+
+ public void unset() {
+ throw new UnsupportedOperationException();
+ }
+
+ public EObject getOldValue() {
+ return oldValue;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s replaced with %s", EcoreUtil.getURI(oldValue), EcoreUtil.getURI(newValue)); //$NON-NLS-1$
+ }
+} \ No newline at end of file
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/RestoreDependencyHelper.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/RestoreDependencyHelper.java
new file mode 100644
index 0000000..f018ddb
--- /dev/null
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/resource/RestoreDependencyHelper.java
@@ -0,0 +1,132 @@
+/*****************************************************************************
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Benoit Maggi benoit.maggi@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.emf.resource;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.papyrus.infra.emf.Activator;
+
+/**
+ * The Class RestoreDependencyHelper is used to restore broken URI according to a replacement Strategy.
+ */
+public class RestoreDependencyHelper {
+
+
+ /** The uri replacement strategy. */
+ protected IURIReplacementStrategy iURIReplacementStrategy;
+
+ /**
+ * Instantiates a new restore dependency helper.
+ *
+ * @param iURIReplacementStrategy the chosen uriReplacementStrategy
+ */
+ public RestoreDependencyHelper(IURIReplacementStrategy iURIReplacementStrategy) {
+ this.iURIReplacementStrategy = iURIReplacementStrategy;
+ }
+
+ /**
+ * Restore dependencies, iterate on all contents to check and replace URIs.
+ *
+ * @param resource the resource
+ * @return the collection
+ */
+ public Collection<Replacement> restoreDependencies(Resource resource) {
+ Iterator<EObject> allContentsIterator = resource.getAllContents();
+ Collection<Replacement> replacements = new LinkedList<Replacement>();
+ while(allContentsIterator.hasNext()) {
+ EObject eObject = allContentsIterator.next();
+
+ for(EReference reference : eObject.eClass().getEAllReferences()) {
+ if(reference.isContainment()) {
+ continue;
+ }
+
+ if(!reference.isChangeable()) {
+ continue;
+ }
+
+ Object value = eObject.eGet(reference);
+ if(value instanceof EObject) {
+ EObject eObjectToReplace = (EObject)value;
+ EObject newEObject = checkAndReplace(eObjectToReplace);
+ if(newEObject == null) {
+ continue;
+ }
+
+ try {
+ eObject.eSet(reference, newEObject);
+ replacements.add(new ReplacementImpl(eObject, reference, eObjectToReplace, newEObject));
+ } catch (Exception ex) {
+ Activator.log.error(ex);
+ }
+
+ } else if(value instanceof Collection<?>) {
+ Map<EObject, EObject> previousToNewValue = new HashMap<EObject, EObject>();
+ Collection<?> collection = (Collection<?>)value;
+ for(Object collectionElement : (Collection<?>)value) {
+ if(collectionElement instanceof EObject) {
+ EObject eObjectToReplace = (EObject)collectionElement;
+ EObject newEObject = checkAndReplace(eObjectToReplace);
+ if(newEObject == null) {
+ continue;
+ }
+ previousToNewValue.put(eObjectToReplace, newEObject);
+ }
+ }
+ if(previousToNewValue.isEmpty()) {
+ continue;
+ }
+ if(collection instanceof EStructuralFeature.Setting) {
+ EStructuralFeature.Setting setting = (EStructuralFeature.Setting)collection;
+ for(Map.Entry<EObject, EObject> entry : previousToNewValue.entrySet()) {
+ EcoreUtil.replace(setting, entry.getKey(), entry.getValue());
+ replacements.add(new ReplacementImpl(eObject, reference, entry.getKey(), entry.getValue()));
+ }
+ }
+ }
+ }
+ }
+ return replacements;
+ }
+
+ /**
+ * Check and replace.
+ *
+ * @param eObject the e object to replace
+ * @return the e object
+ */
+ protected EObject checkAndReplace(EObject eObject) {
+ URI eObjectURIToReplace = EcoreUtil.getURI(eObject);
+ URI resourceURI = eObjectURIToReplace.trimFragment();
+ if(!resourceURI.isEmpty()) {
+ URI targetURI = iURIReplacementStrategy.getReplacementCandidate(resourceURI);
+ if(targetURI != null && !targetURI.equals(resourceURI)) {
+ return DependencyManagementHelper.replace(eObject, targetURI);
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ResourceUtils.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ResourceUtils.java
index 225e5b5..26e1818 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ResourceUtils.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/ResourceUtils.java
@@ -1,81 +1,107 @@
-/*****************************************************************************
- * 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
- *
- * Contributors:
- * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
- *
- *****************************************************************************/
-package org.eclipse.papyrus.infra.emf.utils;
-
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.Assert;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.xmi.XMIResource;
-
-/**
- *
- * This class provides methods for EMF Resource
- *
- */
-public class ResourceUtils {
-
- private ResourceUtils() {
- //to prevent instanciation
- }
-
- /**
- *
- * @param resource
- * an EMF resource
- * @return
- * the IFile corresponding to this resource, or <code>null</code> if not found
- */
- public static IFile getFile(final Resource resource) {
- if(resource != null) {
- URI uri = resource.getURI();
- uri = resource.getResourceSet().getURIConverter().normalize(uri);
- if(uri.isPlatformResource()) {
- String uriPlatformString = uri.toPlatformString(true) ;
- return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(uriPlatformString));
- }
- }
- return null;
- }
-
- /**
- *
- *
- * @param resource
- * a resource
- * @return
- * a collection with all existing id in the resource
- *
- */
- public static Collection<String> getAllResourceIds(final XMIResource resource) {
- final Set<String> ids = new HashSet<String>();
- final Iterator<EObject> iterator = resource.getAllContents();
- while(iterator.hasNext()) {
- final EObject current = iterator.next();
- final String id = resource.getID(current);
- Assert.isNotNull(id);
- Assert.isTrue(!ids.contains(id));
- ids.add(id);
- }
- return ids;
- }
-}
+/*****************************************************************************
+ * 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
+ *
+ * Contributors:
+ * Vincent Lorenzo (CEA LIST) Vincent.Lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.emf.utils;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.xmi.XMIResource;
+
+/**
+ *
+ * This class provides methods for EMF Resource
+ *
+ */
+public class ResourceUtils {
+
+ private ResourceUtils() {
+ //to prevent instanciation
+ }
+
+ /**
+ *
+ * @param resource
+ * an EMF resource
+ * @return
+ * the IFile corresponding to this resource, or <code>null</code> if not found
+ */
+ public static IFile getFile(final Resource resource) {
+ if(resource != null) {
+ URI uri = resource.getURI();
+ uri = resource.getResourceSet().getURIConverter().normalize(uri);
+ if(uri.isPlatformResource()) {
+ String uriPlatformString = uri.toPlatformString(true) ;
+ return ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(uriPlatformString));
+ }
+ }
+ return null;
+ }
+
+ /**
+ *
+ *
+ * @param resource
+ * a resource
+ * @return
+ * a collection with all existing id in the resource
+ *
+ */
+ public static Collection<String> getAllResourceIds(final XMIResource resource) {
+ final Set<String> ids = new HashSet<String>();
+ final Iterator<EObject> iterator = resource.getAllContents();
+ while(iterator.hasNext()) {
+ final EObject current = iterator.next();
+ final String id = resource.getID(current);
+ Assert.isNotNull(id);
+ Assert.isTrue(!ids.contains(id));
+ ids.add(id);
+ }
+ return ids;
+ }
+
+
+ /**
+ * Default options to save emf files used in Papyrus
+ * @return
+ */
+ public static Map<String, Object> getSaveOptions() {
+ Map<String, Object> saveOptions = new HashMap<String, Object>();
+
+ // default save options.
+ saveOptions.put(XMIResource.OPTION_DECLARE_XML, Boolean.TRUE);
+ saveOptions.put(XMIResource.OPTION_PROCESS_DANGLING_HREF, XMIResource.OPTION_PROCESS_DANGLING_HREF_DISCARD);
+ saveOptions.put(XMIResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
+ saveOptions.put(XMIResource.OPTION_USE_XMI_TYPE, Boolean.TRUE);
+ saveOptions.put(XMIResource.OPTION_SAVE_TYPE_INFORMATION, Boolean.TRUE);
+ saveOptions.put(XMIResource.OPTION_SKIP_ESCAPE_URI, Boolean.FALSE);
+ saveOptions.put(XMIResource.OPTION_ENCODING, "UTF-8");
+
+ //see bug 397987: [Core][Save] The referenced plugin models are saved using relative path
+ saveOptions.put(XMIResource.OPTION_URI_HANDLER, new org.eclipse.emf.ecore.xmi.impl.URIHandlerImpl.PlatformSchemeAware());
+
+ return saveOptions;
+ }
+
+}
diff --git a/plugins/infra/org.eclipse.papyrus.infra.onefile/META-INF/MANIFEST.MF b/plugins/infra/org.eclipse.papyrus.infra.onefile/META-INF/MANIFEST.MF
index 752e7a5..e8af4ff 100644
--- a/plugins/infra/org.eclipse.papyrus.infra.onefile/META-INF/MANIFEST.MF
+++ b/plugins/infra/org.eclipse.papyrus.infra.onefile/META-INF/MANIFEST.MF
@@ -1,24 +1,27 @@
-Manifest-Version: 1.0
-Export-Package: org.eclipse.papyrus.infra.onefile.model,
- org.eclipse.papyrus.infra.onefile.utils
-Require-Bundle: org.eclipse.papyrus.infra.core;bundle-version="1.0.0",
- org.eclipse.ui.navigator,
- org.eclipse.team.ui,
- org.eclipse.ui.navigator.resources,
- org.eclipse.core.resources;bundle-version="3.7.0",
- org.eclipse.core.runtime;bundle-version="3.7.0",
- org.eclipse.ui,
- org.eclipse.ui.ide;bundle-version="3.8.0",
- org.eclipse.papyrus.infra.core.log;bundle-version="1.0.0",
- org.eclipse.ltk.core.refactoring;bundle-version="3.6.0",
- org.eclipse.ltk.ui.refactoring;bundle-version="3.7.0"
-Bundle-Vendor: %providerName
-Bundle-ActivationPolicy: lazy
-Bundle-Version: 1.0.0.qualifier
-Bundle-Localization: plugin
-Bundle-Name: %pluginName
-Bundle-Activator: org.eclipse.papyrus.infra.onefile.Activator
-Bundle-ManifestVersion: 2
-Bundle-SymbolicName: org.eclipse.papyrus.infra.onefile;singleton:=true
-Bundle-RequiredExecutionEnvironment: J2SE-1.5
-
+Manifest-Version: 1.0
+Export-Package: org.eclipse.papyrus.infra.onefile.model,
+ org.eclipse.papyrus.infra.onefile.utils
+Require-Bundle: org.eclipse.papyrus.infra.core;bundle-version="1.0.0",
+ org.eclipse.ui.navigator,
+ org.eclipse.ui.navigator.resources,
+ org.eclipse.core.resources;bundle-version="3.7.0",
+ org.eclipse.core.runtime;bundle-version="3.7.0",
+ org.eclipse.ui,
+ org.eclipse.ui.ide;bundle-version="3.8.0",
+ org.eclipse.papyrus.infra.core.log;bundle-version="1.0.0",
+ org.eclipse.ltk.core.refactoring;bundle-version="3.6.0",
+ org.eclipse.ltk.ui.refactoring;bundle-version="3.7.0",
+ org.eclipse.core.filesystem;bundle-version="1.4.0",
+ org.eclipse.papyrus.infra.emf;bundle-version="1.0.0",
+ org.eclipse.core.expressions,
+ org.eclipse.emf.ecore
+Bundle-Vendor: %providerName
+Bundle-ActivationPolicy: lazy
+Bundle-Version: 1.0.0.qualifier
+Bundle-Localization: plugin
+Bundle-Name: %pluginName
+Bundle-Activator: org.eclipse.papyrus.infra.onefile.Activator
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.eclipse.papyrus.infra.onefile;singleton:=true
+Bundle-RequiredExecutionEnvironment: J2SE-1.5
+
diff --git a/plugins/infra/org.eclipse.papyrus.infra.onefile/plugin.xml b/plugins/infra/org.eclipse.papyrus.infra.onefile/plugin.xml
index 85297ae..4b89ad1 100644
--- a/plugins/infra/org.eclipse.papyrus.infra.onefile/plugin.xml
+++ b/plugins/infra/org.eclipse.papyrus.infra.onefile/plugin.xml
@@ -1,282 +1,316 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<?eclipse version="3.4"?>
-<plugin>
- <extension-point id="modelFactory" name="Model Factory" schema="schema/modelFactory.exsd"/>
- <extension
- point="org.eclipse.core.runtime.adapters">
- <factory
- adaptableType="org.eclipse.papyrus.infra.onefile.model.IPapyrusFile"
- class="org.eclipse.papyrus.infra.onefile.model.adapters.ModelAdapterFactory">
- <adapter type="org.eclipse.core.resources.mapping.ResourceMapping" />
- <adapter type="java.util.Collection" />
- <adapter
- type="org.eclipse.ui.ide.IContributorResourceAdapter2">
- </adapter>
- <adapter
- type="org.eclipse.core.resources.IFile">
- </adapter>
- <adapter
- type="org.eclipse.core.resources.IResource">
- </adapter>
- </factory>
- <factory
- adaptableType="org.eclipse.papyrus.infra.onefile.model.ISubResourceFile"
- class="org.eclipse.papyrus.infra.onefile.model.adapters.SubResourceAdapterFactory">
- <adapter
- type="org.eclipse.core.resources.mapping.ResourceMapping">
- </adapter>
- <adapter
- type="org.eclipse.core.resources.IFile">
- </adapter>
- <adapter
- type="org.eclipse.core.resources.IResource">
- </adapter>
- <adapter
- type="org.eclipse.ui.IContributorResourceAdapter">
- </adapter>
- <adapter
- type="org.eclipse.ui.ide.IContributorResourceAdapter2">
- </adapter>
- </factory>
- </extension>
- <extension
- id="modelProvider"
- name="One File Model Provider"
- point="org.eclipse.core.resources.modelProviders">
- <modelProvider
- class="org.eclipse.papyrus.infra.onefile.providers.OneFileModelProvider"/>
- <extends-model id="org.eclipse.core.resources.modelProvider"/>
- </extension>
- <extension
- point="org.eclipse.ui.navigator.navigatorContent">
- <commonFilter
- activeByDefault="true"
- class="org.eclipse.papyrus.infra.onefile.matcher.OnlyDiFilter"
- description="All the files related to di files are agregated bellow a common parent"
- id="org.eclipse.papyrus.infra.onefile.onlyDiFilter"
- name="Di view"
- visibleInUI="true">
- </commonFilter>
- <navigatorContent
- activeByDefault="true"
- contentProvider="org.eclipse.papyrus.infra.onefile.providers.PapyrusContentProvider"
- id="org.eclipse.papyrus.infra.onefile.DiContent"
- labelProvider="org.eclipse.papyrus.infra.onefile.providers.PapyrusLabelProvider"
- name="Papyrus Content"
- priority="high">
- <enablement>
- <or>
- <instanceof
- value="org.eclipse.papyrus.infra.onefile.model.IPapyrusFile">
- </instanceof>
- <instanceof
- value="org.eclipse.papyrus.infra.onefile.providers.OneFileModelProvider">
- </instanceof>
- <instanceof
- value="org.eclipse.core.resources.IResource">
- </instanceof>
- <instanceof
- value="org.eclipse.core.internal.resources.mapping.ResourceModelProvider">
- </instanceof>
- <instanceof
- value="org.eclipse.core.resources.IFile">
- </instanceof>
- <adapt
- type="org.eclipse.core.resources.IResource">
- </adapt>
- </or>
- </enablement>
- <actionProvider
- class="org.eclipse.papyrus.infra.onefile.providers.PapyrusModelActionProvider"
- id="org.eclipse.papyrus.infra.onefile.DiContent.OpenActions"
- overrides="org.eclipse.ui.navigator.resources.OpenActions">
- <enablement>
- <instanceof
- value="org.eclipse.papyrus.infra.onefile.model.IPapyrusFile">
- </instanceof>
- </enablement>
- </actionProvider>
- <dropAssistant
- class="org.eclipse.papyrus.infra.onefile.model.adapters.PapyrusCommonDropAdapterAssistant"
- id="org.eclipse.papyrus.infra.onefile.PapyrusDropAssistant">
- <possibleDropTargets>
- <instanceof
- value="org.eclipse.core.resources.IContainer">
- </instanceof></possibleDropTargets>
- </dropAssistant>
- <commonSorter
- class="org.eclipse.papyrus.infra.onefile.providers.PapyrusViewerSorter"
- id="org.eclipse.papyrus.infra.onefile.sorter">
- </commonSorter>
- <triggerPoints>
- <or>
- <instanceof
- value="org.eclipse.core.resources.IContainer">
- </instanceof>
- <instanceof
- value="org.eclipse.papyrus.infra.onefile.model.IPapyrusFile">
- </instanceof>
- <instanceof
- value="org.eclipse.papyrus.infra.onefile.model.ISubResourceFile">
- </instanceof>
- </or>
- </triggerPoints>
- <actionProvider
- class="org.eclipse.papyrus.infra.onefile.providers.SubresourceFileActionProvider"
- id="org.eclipse.papyrus.infra.onefile.DiContent.EditActions">
- <enablement>
- <instanceof
- value="org.eclipse.papyrus.infra.onefile.model.ISubResourceFile">
- </instanceof>
- </enablement>
- </actionProvider>
- </navigatorContent>
- </extension>
- <extension point="org.eclipse.ui.navigator.viewer">
- <viewerContentBinding viewerId="org.eclipse.team.ui.navigatorViewer">
- <includes>
- <contentExtension
- pattern="org.eclipse.papyrus.infra.onefile.DiContent"/>
- </includes>
- </viewerContentBinding>
- <viewerContentBinding
- viewerId="org.eclipse.jdt.ui.PackageExplorer">
- <includes>
- <contentExtension
- pattern="org.eclipse.papyrus.infra.onefile.onlyDiFilter">
- </contentExtension>
- <contentExtension
- pattern="org.eclipse.papyrus.infra.onefile.DiContent">
- </contentExtension>
- <contentExtension
- pattern="org.eclipse.papyrus.infra.onefile.oneFileLinkHelper">
- </contentExtension>
- <contentExtension
- pattern="org.eclipse.ui.navigator.resourceContent" />
- <contentExtension
- pattern="org.eclipse.ui.navigator.resources.filters.*"/>
- </includes>
- </viewerContentBinding>
- <viewerContentBinding
- viewerId="org.eclipse.ui.navigator.ProjectExplorer">
- <includes>
- <contentExtension
- pattern="org.eclipse.papyrus.infra.onefile.onlyDiFilter">
- </contentExtension>
- <contentExtension
- pattern="org.eclipse.papyrus.infra.onefile.DiContent">
- </contentExtension>
- <contentExtension
- pattern="org.eclipse.papyrus.infra.onefile.oneFileLinkHelper">
- </contentExtension>
- <contentExtension
- pattern="org.eclipse.ui.navigator.resourceContent" />
- <contentExtension
- pattern="org.eclipse.ui.navigator.resources.filters.*"/>
- </includes>
- </viewerContentBinding>
- <viewerContentBinding
- viewerId="org.eclipse.team.ui.navigatorViewer">
- <includes>
- <contentExtension
- pattern="org.eclipse.papyrus.infra.onefile.onlyDiFilter">
- </contentExtension>
- <contentExtension
- pattern="org.eclipse.papyrus.infra.onefile.DiContent">
- </contentExtension>
- </includes>
- </viewerContentBinding>
- <viewerContentBinding
- viewerId="org.eclipse.team.svn.ui.workspaceSynchronization">
- <includes>
- <contentExtension
- pattern="org.eclipse.papyrus.infra.onefile.onlyDiFilter">
- </contentExtension>
- <contentExtension
- pattern="org.eclipse.papyrus.infra.onefile.DiContent">
- </contentExtension>
- </includes>
- </viewerContentBinding>
- <viewerContentBinding
- viewerId="org.eclipse.team.cvs.ui.workspaceSynchronization">
- <includes>
- <contentExtension
- pattern="org.eclipse.papyrus.infra.onefile.onlyDiFilter">
- </contentExtension>
- <contentExtension
- pattern="org.eclipse.papyrus.infra.onefile.DiContent">
- </contentExtension>
- </includes>
- </viewerContentBinding>
- <viewerContentBinding
- viewerId="org.eclipse.papyrus.infra.onefile.DiContent">
- <includes>
- <contentExtension
- pattern="org.eclipse.jdt.java.ui.javaContent">
- </contentExtension>
- </includes>
- </viewerContentBinding>
- </extension>
-
- <extension
- point="org.eclipse.ui.navigator.linkHelper">
- <linkHelper
- class="org.eclipse.papyrus.infra.onefile.model.adapters.PapyrusLinkHelper"
- id="org.eclipse.papyrus.infra.onefile.oneFileLinkHelper">
- <editorInputEnablement>
- <and>
- <instanceof
- value="org.eclipse.ui.IFileEditorInput">
- </instanceof>
- <adapt
- type="org.eclipse.core.resources.IFile">
- <test
- property="org.eclipse.core.resources.extension"
- value="di">
- </test>
- </adapt>
- </and>
- </editorInputEnablement>
- <selectionEnablement>
- <or>
- <instanceof
- value="org.eclipse.papyrus.infra.onefile.model.IPapyrusFile">
- </instanceof>
- <and>
- <instanceof
- value="org.eclipse.core.resources.IFile">
- </instanceof>
- <test
- forcePluginActivation="true"
- property="org.eclipse.core.resources.extension"
- value="di">
- </test>
- </and>
- </or>
- </selectionEnablement>
- </linkHelper>
- </extension>
- <extension
- point="org.eclipse.papyrus.infra.onefile.modelFactory">
- <factory
- instance="org.eclipse.papyrus.infra.onefile.model.impl.PapyrusModelFactory"
- priority="1">
- </factory>
- </extension>
- <extension
- point="org.eclipse.ui.decorators">
- <decorator
- adaptable="true"
- class="org.eclipse.papyrus.infra.onefile.providers.OneFileDecorator"
- id="org.eclipse.papyrus.infra.onefile.onefiledecorator"
- label="One File Decorator"
- lightweight="true"
- state="true">
- <enablement>
- <objectClass
- name="org.eclipse.papyrus.infra.onefile.model.IPapyrusFile">
- </objectClass>
- </enablement>
- </decorator>
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+ <extension-point id="modelFactory" name="Model Factory" schema="schema/modelFactory.exsd"/>
+ <extension
+ point="org.eclipse.core.runtime.adapters">
+ <factory
+ adaptableType="org.eclipse.papyrus.infra.onefile.model.IPapyrusFile"
+ class="org.eclipse.papyrus.infra.onefile.model.adapters.ModelAdapterFactory">
+ <adapter type="org.eclipse.core.resources.mapping.ResourceMapping" />
+ <adapter type="java.util.Collection" />
+ <adapter
+ type="org.eclipse.ui.ide.IContributorResourceAdapter2">
+ </adapter>
+ <adapter
+ type="org.eclipse.core.resources.IFile">
+ </adapter>
+ <adapter
+ type="org.eclipse.core.resources.IResource">
+ </adapter>
+ </factory>
+ <factory
+ adaptableType="org.eclipse.papyrus.infra.onefile.model.ISubResourceFile"
+ class="org.eclipse.papyrus.infra.onefile.model.adapters.SubResourceAdapterFactory">
+ <adapter
+ type="org.eclipse.core.resources.mapping.ResourceMapping">
+ </adapter>
+ <adapter
+ type="org.eclipse.core.resources.IFile">
+ </adapter>
+ <adapter
+ type="org.eclipse.core.resources.IResource">
+ </adapter>
+ <adapter
+ type="org.eclipse.ui.IContributorResourceAdapter">
+ </adapter>
+ <adapter
+ type="org.eclipse.ui.ide.IContributorResourceAdapter2">
+ </adapter>
+ </factory>
</extension>
-</plugin>
+ <extension
+ id="modelProvider"
+ name="One File Model Provider"
+ point="org.eclipse.core.resources.modelProviders">
+ <modelProvider
+ class="org.eclipse.papyrus.infra.onefile.providers.OneFileModelProvider"/>
+ <extends-model id="org.eclipse.core.resources.modelProvider"/>
+ </extension>
+ <extension
+ point="org.eclipse.ui.navigator.navigatorContent">
+ <commonFilter
+ activeByDefault="true"
+ class="org.eclipse.papyrus.infra.onefile.matcher.OnlyDiFilter"
+ description="All the files related to di files are agregated bellow a common parent"
+ id="org.eclipse.papyrus.infra.onefile.onlyDiFilter"
+ name="Di view"
+ visibleInUI="true">
+ </commonFilter>
+ <navigatorContent
+ activeByDefault="true"
+ contentProvider="org.eclipse.papyrus.infra.onefile.providers.PapyrusContentProvider"
+ id="org.eclipse.papyrus.infra.onefile.DiContent"
+ labelProvider="org.eclipse.papyrus.infra.onefile.providers.PapyrusLabelProvider"
+ name="Papyrus Content"
+ priority="high">
+ <enablement>
+ <or>
+ <instanceof
+ value="org.eclipse.papyrus.infra.onefile.model.IPapyrusFile">
+ </instanceof>
+ <instanceof
+ value="org.eclipse.papyrus.infra.onefile.providers.OneFileModelProvider">
+ </instanceof>
+ <instanceof
+ value="org.eclipse.core.resources.IResource">
+ </instanceof>
+ <instanceof
+ value="org.eclipse.core.internal.resources.mapping.ResourceModelProvider">
+ </instanceof>
+ <instanceof
+ value="org.eclipse.core.resources.IFile">
+ </instanceof>
+ <adapt
+ type="org.eclipse.core.resources.IResource">
+ </adapt>
+ </or>
+ </enablement>
+ <actionProvider
+ class="org.eclipse.papyrus.infra.onefile.providers.PapyrusModelActionProvider"
+ id="org.eclipse.papyrus.infra.onefile.DiContent.OpenActions"
+ overrides="org.eclipse.ui.navigator.resources.OpenActions">
+ <enablement>
+ <instanceof
+ value="org.eclipse.papyrus.infra.onefile.model.IPapyrusFile">
+ </instanceof>
+ </enablement>
+ </actionProvider>
+ <actionProvider
+ class="org.eclipse.papyrus.infra.onefile.providers.PapyrusEditActionProvider"
+ dependsOn="org.eclipse.ui.navigator.resources.actions.EditActions"
+ id="org.eclipse.papyrus.infra.onefile.DiContent.EditActions">
+ <enablement>
+ <and>
+ <with
+ variable="activeShell">
+ <test
+ property="org.eclipse.papyrus.infra.onefile.handlers.tester.containsPapyrusModel"
+ value="true">
+ </test>
+ </with>
+ </and>
+ </enablement>
+ </actionProvider>
+ <dropAssistant
+ class="org.eclipse.papyrus.infra.onefile.model.adapters.PapyrusCommonDropAdapterAssistant"
+ id="org.eclipse.papyrus.infra.onefile.PapyrusDropAssistant">
+ <possibleDropTargets>
+ <instanceof
+ value="org.eclipse.core.resources.IContainer">
+ </instanceof>
+ </possibleDropTargets>
+ </dropAssistant>
+ <commonSorter
+ class="org.eclipse.papyrus.infra.onefile.providers.PapyrusViewerSorter"
+ id="org.eclipse.papyrus.infra.onefile.sorter">
+ </commonSorter>
+ <triggerPoints>
+ <or>
+ <instanceof
+ value="org.eclipse.core.resources.IContainer">
+ </instanceof>
+ <instanceof
+ value="org.eclipse.papyrus.infra.onefile.model.IPapyrusFile">
+ </instanceof>
+ <instanceof
+ value="org.eclipse.papyrus.infra.onefile.model.ISubResourceFile">
+ </instanceof>
+ </or>
+ </triggerPoints>
+ <actionProvider
+ class="org.eclipse.papyrus.infra.onefile.providers.SubresourceFileActionProvider"
+ id="org.eclipse.papyrus.infra.onefile.DiContent.EditActions">
+ <enablement>
+ <instanceof
+ value="org.eclipse.papyrus.infra.onefile.model.ISubResourceFile">
+ </instanceof>
+ </enablement>
+ </actionProvider>
+ </navigatorContent>
+ </extension>
+ <extension point="org.eclipse.ui.navigator.viewer">
+ <viewerContentBinding viewerId="org.eclipse.team.ui.navigatorViewer">
+ <includes>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.DiContent"/>
+ </includes>
+ </viewerContentBinding>
+ <viewerContentBinding
+ viewerId="org.eclipse.jdt.ui.PackageExplorer">
+ <includes>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.onlyDiFilter">
+ </contentExtension>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.DiContent">
+ </contentExtension>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.oneFileLinkHelper">
+ </contentExtension>
+ <contentExtension
+ pattern="org.eclipse.ui.navigator.resourceContent" />
+ <contentExtension
+ pattern="org.eclipse.ui.navigator.resources.filters.*"/>
+ </includes>
+ </viewerContentBinding>
+ <viewerContentBinding
+ viewerId="org.eclipse.ui.navigator.ProjectExplorer">
+ <includes>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.onlyDiFilter">
+ </contentExtension>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.DiContent">
+ </contentExtension>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.oneFileLinkHelper">
+ </contentExtension>
+ <contentExtension
+ pattern="org.eclipse.ui.navigator.resourceContent" />
+ <contentExtension
+ pattern="org.eclipse.ui.navigator.resources.filters.*"/>
+ </includes>
+ </viewerContentBinding>
+ <viewerContentBinding
+ viewerId="org.eclipse.team.ui.navigatorViewer">
+ <includes>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.onlyDiFilter">
+ </contentExtension>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.DiContent">
+ </contentExtension>
+ </includes>
+ </viewerContentBinding>
+ <viewerContentBinding
+ viewerId="org.eclipse.team.svn.ui.workspaceSynchronization">
+ <includes>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.onlyDiFilter">
+ </contentExtension>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.DiContent">
+ </contentExtension>
+ </includes>
+ </viewerContentBinding>
+ <viewerContentBinding
+ viewerId="org.eclipse.team.cvs.ui.workspaceSynchronization">
+ <includes>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.onlyDiFilter">
+ </contentExtension>
+ <contentExtension
+ pattern="org.eclipse.papyrus.infra.onefile.DiContent">
+ </contentExtension>
+ </includes>
+ </viewerContentBinding>
+ <viewerContentBinding
+ viewerId="org.eclipse.papyrus.infra.onefile.DiContent">
+ <includes>
+ <contentExtension
+ pattern="org.eclipse.jdt.java.ui.javaContent">
+ </contentExtension>
+ </includes>
+ </viewerContentBinding>
+ </extension>
+
+ <extension
+ point="org.eclipse.ui.navigator.linkHelper">
+ <linkHelper
+ class="org.eclipse.papyrus.infra.onefile.model.adapters.PapyrusLinkHelper"
+ id="org.eclipse.papyrus.infra.onefile.oneFileLinkHelper">
+ <editorInputEnablement>
+ <and>
+ <instanceof
+ value="org.eclipse.ui.IFileEditorInput">
+ </instanceof>
+ <adapt
+ type="org.eclipse.core.resources.IFile">
+ <test
+ property="org.eclipse.core.resources.extension"
+ value="di">
+ </test>
+ </adapt>
+ </and>
+ </editorInputEnablement>
+ <selectionEnablement>
+ <or>
+ <instanceof
+ value="org.eclipse.papyrus.infra.onefile.model.IPapyrusFile">
+ </instanceof>
+ <and>
+ <instanceof
+ value="org.eclipse.core.resources.IFile">
+ </instanceof>
+ <test
+ forcePluginActivation="true"
+ property="org.eclipse.core.resources.extension"
+ value="di">
+ </test>
+ </and>
+ </or>
+ </selectionEnablement>
+ </linkHelper>
+ </extension>
+ <extension
+ point="org.eclipse.papyrus.infra.onefile.modelFactory">
+ <factory
+ instance="org.eclipse.papyrus.infra.onefile.model.impl.PapyrusModelFactory"
+ priority="1">
+ </factory>
+ </extension>
+ <extension
+ point="org.eclipse.ui.decorators">
+ <decorator
+ adaptable="true"
+ class="org.eclipse.papyrus.infra.onefile.providers.OneFileDecorator"
+ id="org.eclipse.papyrus.infra.onefile.onefiledecorator"
+ label="One File Decorator"
+ lightweight="true"
+ state="true">
+ <enablement>
+ <objectClass
+ name="org.eclipse.papyrus.infra.onefile.model.IPapyrusFile">
+ </objectClass>
+ </enablement>
+ </decorator>
+ </extension>
+<extension
+ point="org.eclipse.core.expressions.propertyTesters">
+ <propertyTester
+ class="org.eclipse.papyrus.infra.onefile.testers.PapyrusClipboardTester"
+ id="org.eclipse.papyrus.infra.onefile.handlers.tester"
+ namespace="org.eclipse.papyrus.infra.onefile.handlers.tester"
+ properties="containsPapyrusModel"
+ type="org.eclipse.swt.widgets.Shell">
+ </propertyTester>
+ <propertyTester
+ class="org.eclipse.papyrus.infra.onefile.testers.PapyrusClipboardTester"
+ id="org.eclipse.papyrus.infra.onefile.handlers.tester"
+ namespace="org.eclipse.papyrus.infra.onefile.handlers.tester"
+ properties="toto"
+ type="java.util.Collection">
+ </propertyTester>
+</extension>
+</plugin>
diff --git a/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/action/CopyFilesAndFoldersOperation.java b/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/action/CopyFilesAndFoldersOperation.java
new file mode 100644
index 0000000..86e0f98
--- /dev/null
+++ b/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/action/CopyFilesAndFoldersOperation.java
@@ -0,0 +1,1959 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2013 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ * Serge Beauchamp (Freescale Semiconductor) - [229633] Group Support
+ *******************************************************************************/
+
+package org.eclipse.papyrus.infra.onefile.action;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.filesystem.EFS;
+import org.eclipse.core.filesystem.IFileInfo;
+import org.eclipse.core.filesystem.IFileStore;
+import org.eclipse.core.filesystem.URIUtil;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.WorkspaceJob;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.window.Window;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.eclipse.ui.dialogs.IOverwriteQuery;
+import org.eclipse.ui.ide.dialogs.ImportTypeDialog;
+import org.eclipse.ui.ide.undo.AbstractWorkspaceOperation;
+import org.eclipse.ui.ide.undo.CopyResourcesOperation;
+import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
+import org.eclipse.ui.internal.ide.IDEInternalPreferences;
+import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+import org.eclipse.ui.internal.ide.StatusUtil;
+import org.eclipse.ui.internal.ide.dialogs.IDEResourceInfoUtils;
+import org.eclipse.ui.statushandlers.StatusManager;
+import org.eclipse.ui.wizards.datatransfer.FileStoreStructureProvider;
+import org.eclipse.ui.wizards.datatransfer.ImportOperation;
+
+
+/**
+ * Perform the copy of file and folder resources from the clipboard when paste
+ * action is invoked.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class CopyFilesAndFoldersOperation {
+
+ /**
+ * Status containing the errors detected when running the operation or
+ * <code>null</code> if no errors detected.
+ */
+ private MultiStatus errorStatus;
+
+ /**
+ * The parent shell used to show any dialogs.
+ */
+ protected Shell messageShell;
+
+ /**
+ * Whether or not the copy has been canceled by the user.
+ */
+ private boolean canceled = false;
+
+ /**
+ * Whether or not the operation creates virtual folders and links instead of folders
+ * and files.
+ */
+ private boolean createVirtualFoldersAndLinks = false;
+
+ /**
+ * Whether or not the operation creates links instead of folders and files.
+ */
+ private boolean createLinks = false;
+
+ private String relativeVariable = null;
+ /**
+ * Overwrite all flag.
+ */
+ private boolean alwaysOverwrite = false;
+
+ private String[] modelProviderIds;
+
+ /**
+ * Returns a new name for a copy of the resource at the given path in the
+ * given workspace. This name is determined automatically.
+ *
+ * @param originalName
+ * the full path of the resource
+ * @param workspace
+ * the workspace
+ * @return the new full path for the copy
+ */
+ static IPath getAutoNewNameFor(IPath originalName, IWorkspace workspace) {
+ int counter = 1;
+ String resourceName = originalName.lastSegment();
+ IPath leadupSegment = originalName.removeLastSegments(1);
+
+ while (true) {
+ String nameSegment;
+
+ if (counter > 1) {
+ nameSegment = NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyNameTwoArgs,
+ new Integer(counter), resourceName);
+ } else {
+ nameSegment = NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyNameOneArg,
+ resourceName);
+ }
+
+ IPath pathToTry = leadupSegment.append(nameSegment);
+
+ if (!workspace.getRoot().exists(pathToTry)) {
+ return pathToTry;
+ }
+
+ counter++;
+ }
+ }
+
+ /**
+ * Creates a new operation initialized with a shell.
+ *
+ * @param shell
+ * parent shell for error dialogs
+ */
+ public CopyFilesAndFoldersOperation(Shell shell) {
+ messageShell = shell;
+ }
+
+ /**
+ * Returns whether this operation is able to perform on-the-fly
+ * auto-renaming of resources with name collisions.
+ *
+ * @return <code>true</code> if auto-rename is supported, and
+ * <code>false</code> otherwise
+ */
+ protected boolean canPerformAutoRename() {
+ return true;
+ }
+
+ /**
+ * Returns the message for querying deep copy/move of a linked resource.
+ *
+ * @param source
+ * resource the query is made for
+ * @return the deep query message
+ */
+ protected String getDeepCheckQuestion(IResource source) {
+ return NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_deepCopyQuestion,
+ source.getFullPath().makeRelative());
+ }
+
+ /**
+ * Checks whether the infos exist.
+ *
+ * @param stores
+ * the file infos to test
+ * @return Multi status with one error message for each missing file.
+ */
+ IStatus checkExist(IFileStore[] stores) {
+ MultiStatus multiStatus = new MultiStatus(PlatformUI.PLUGIN_ID,
+ IStatus.OK, getProblemsMessage(), null);
+
+ for (int i = 0; i < stores.length; i++) {
+ if (stores[i].fetchInfo().exists() == false) {
+ String message = NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceDeleted,
+ stores[i].getName());
+ IStatus status = new Status(IStatus.ERROR,
+ PlatformUI.PLUGIN_ID, IStatus.OK, message, null);
+ multiStatus.add(status);
+ }
+ }
+ return multiStatus;
+ }
+
+ /**
+ * Checks whether the resources with the given names exist.
+ *
+ * @param resources
+ * IResources to checl
+ * @return Multi status with one error message for each missing file.
+ */
+ IStatus checkExist(IResource[] resources) {
+ MultiStatus multiStatus = new MultiStatus(PlatformUI.PLUGIN_ID,
+ IStatus.OK, getProblemsMessage(), null);
+
+ for (int i = 0; i < resources.length; i++) {
+ IResource resource = resources[i];
+ if (resource != null && !resource.isVirtual()) {
+ URI location = resource.getLocationURI();
+ String message = null;
+ if (location != null) {
+ IFileInfo info = IDEResourceInfoUtils.getFileInfo(location);
+ if (info == null || info.exists() == false) {
+ if (resource.isLinked()) {
+ message = NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_missingLinkTarget,
+ resource.getName());
+ } else {
+ message = NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceDeleted,
+ resource.getName());
+ }
+ }
+ }
+ if (message != null) {
+ IStatus status = new Status(IStatus.ERROR,
+ PlatformUI.PLUGIN_ID, IStatus.OK, message, null);
+ multiStatus.add(status);
+ }
+ }
+ }
+ return multiStatus;
+ }
+
+ /**
+ * Check if the user wishes to overwrite the supplied resource or all
+ * resources.
+ *
+ * @param source
+ * the source resource
+ * @param destination
+ * the resource to be overwritten
+ * @return one of IDialogConstants.YES_ID, IDialogConstants.YES_TO_ALL_ID,
+ * IDialogConstants.NO_ID, IDialogConstants.CANCEL_ID indicating
+ * whether the current resource or all resources can be overwritten,
+ * or if the operation should be canceled.
+ */
+ private int checkOverwrite(final IResource source,
+ final IResource destination) {
+ final int[] result = new int[1];
+
+ // Dialogs need to be created and opened in the UI thread
+ Runnable query = new Runnable() {
+ public void run() {
+ String message;
+ int resultId[] = { IDialogConstants.YES_ID,
+ IDialogConstants.YES_TO_ALL_ID, IDialogConstants.NO_ID,
+ IDialogConstants.CANCEL_ID };
+ String labels[] = new String[] { IDialogConstants.YES_LABEL,
+ IDialogConstants.YES_TO_ALL_LABEL,
+ IDialogConstants.NO_LABEL,
+ IDialogConstants.CANCEL_LABEL };
+
+ if (destination.getType() == IResource.FOLDER) {
+ if (homogenousResources(source, destination)) {
+ message = NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteMergeQuestion,
+ destination.getFullPath()
+ .makeRelative());
+ } else {
+ if (destination.isLinked()) {
+ message = NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteNoMergeLinkQuestion,
+ destination.getFullPath()
+ .makeRelative());
+ } else {
+ message = NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteNoMergeNoLinkQuestion,
+ destination.getFullPath()
+ .makeRelative());
+ }
+ resultId = new int[] { IDialogConstants.YES_ID,
+ IDialogConstants.NO_ID,
+ IDialogConstants.CANCEL_ID };
+ labels = new String[] { IDialogConstants.YES_LABEL,
+ IDialogConstants.NO_LABEL,
+ IDialogConstants.CANCEL_LABEL };
+ }
+ } else {
+ String[] bindings = new String[] {
+ IDEResourceInfoUtils.getLocationText(destination),
+ IDEResourceInfoUtils
+ .getDateStringValue(destination),
+ IDEResourceInfoUtils.getLocationText(source),
+ IDEResourceInfoUtils.getDateStringValue(source) };
+ message = NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteWithDetailsQuestion,
+ bindings);
+ }
+ MessageDialog dialog = new MessageDialog(
+ messageShell,
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceExists,
+ null, message, MessageDialog.QUESTION, labels, 0) {
+ protected int getShellStyle() {
+ return super.getShellStyle() | SWT.SHEET;
+ }
+ };
+ dialog.open();
+ if (dialog.getReturnCode() == SWT.DEFAULT) {
+ // A window close returns SWT.DEFAULT, which has to be
+ // mapped to a cancel
+ result[0] = IDialogConstants.CANCEL_ID;
+ } else {
+ result[0] = resultId[dialog.getReturnCode()];
+ }
+ }
+ };
+ messageShell.getDisplay().syncExec(query);
+ return result[0];
+ }
+
+ /**
+ * Recursively collects existing files in the specified destination path.
+ *
+ * @param destinationPath
+ * destination path to check for existing files
+ * @param copyResources
+ * resources that may exist in the destination
+ * @param existing
+ * holds the collected existing files
+ */
+ private void collectExistingReadonlyFiles(IPath destinationPath,
+ IResource[] copyResources, ArrayList existing) {
+ IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
+
+ for (int i = 0; i < copyResources.length; i++) {
+ IResource source = copyResources[i];
+ IPath newDestinationPath = destinationPath.append(source.getName());
+ IResource newDestination = workspaceRoot
+ .findMember(newDestinationPath);
+ IFolder folder;
+
+ if (newDestination == null) {
+ continue;
+ }
+ folder = getFolder(newDestination);
+ if (folder != null) {
+ IFolder sourceFolder = getFolder(source);
+
+ if (sourceFolder != null) {
+ try {
+ collectExistingReadonlyFiles(newDestinationPath,
+ sourceFolder.members(), existing);
+ } catch (CoreException exception) {
+ recordError(exception);
+ }
+ }
+ } else {
+ IFile file = getFile(newDestination);
+
+ if (file != null) {
+ if (file.isReadOnly()) {
+ existing.add(file);
+ }
+ if (getValidateConflictSource()) {
+ IFile sourceFile = getFile(source);
+ if (sourceFile != null) {
+ existing.add(sourceFile);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Copies the resources to the given destination. This method is called
+ * recursively to merge folders during folder copy.
+ *
+ * @param resources
+ * the resources to copy
+ * @param destination
+ * destination to which resources will be copied
+ * @param subMonitor
+ * a progress monitor for showing progress and for cancelation
+ *
+ * @deprecated As of 3.3, the work is performed in the undoable operation
+ * created in
+ * {@link #getUndoableCopyOrMoveOperation(IResource[], IPath)}
+ */
+ protected void copy(IResource[] resources, IPath destination,
+ IProgressMonitor subMonitor) throws CoreException {
+
+ subMonitor
+ .beginTask(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_CopyResourcesTask,
+ resources.length);
+
+ for (int i = 0; i < resources.length; i++) {
+ IResource source = resources[i];
+ IPath destinationPath = destination.append(source.getName());
+ IWorkspace workspace = source.getWorkspace();
+ IWorkspaceRoot workspaceRoot = workspace.getRoot();
+ IResource existing = workspaceRoot.findMember(destinationPath);
+ if (source.getType() == IResource.FOLDER && existing != null) {
+ // the resource is a folder and it exists in the destination,
+ // copy the
+ // children of the folder.
+ if (homogenousResources(source, existing)) {
+ IResource[] children = ((IContainer) source).members();
+ copy(children, destinationPath, new SubProgressMonitor(
+ subMonitor, 1));
+ } else {
+ // delete the destination folder, copying a linked folder
+ // over an unlinked one or vice versa. Fixes bug 28772.
+ delete(existing, new SubProgressMonitor(subMonitor, 0));
+ source.copy(destinationPath, IResource.SHALLOW,
+ new SubProgressMonitor(subMonitor, 1));
+ }
+ } else {
+ if (existing != null) {
+ if (homogenousResources(source, existing)) {
+ copyExisting(source, existing, new SubProgressMonitor(
+ subMonitor, 1));
+ } else {
+ if (existing != null) {
+ // Copying a linked resource over unlinked or vice
+ // versa.
+ // Can't use setContents here. Fixes bug 28772.
+ delete(existing, new SubProgressMonitor(subMonitor, 0));
+ }
+
+ if ((createLinks || createVirtualFoldersAndLinks)
+ && (source.isLinked() == false)
+ && (source.isVirtual() == false)) {
+ if (source.getType() == IResource.FILE) {
+ IFile file = workspaceRoot.getFile(destinationPath);
+ file.createLink(createRelativePath(source.getLocationURI(), file), 0,
+ new SubProgressMonitor(subMonitor, 1));
+ } else {
+ IFolder folder = workspaceRoot
+ .getFolder(destinationPath);
+ if (createVirtualFoldersAndLinks) {
+ folder.create(IResource.VIRTUAL, true,
+ new SubProgressMonitor(subMonitor,
+ 1));
+ IResource[] members = ((IContainer) source)
+ .members();
+ if (members.length > 0)
+ copy(members, destinationPath,
+ new SubProgressMonitor(subMonitor,
+ 1));
+ } else
+ folder.createLink(createRelativePath(source.getLocationURI(), folder), 0,
+ new SubProgressMonitor(subMonitor, 1));
+ }
+ } else
+ source.copy(destinationPath, IResource.SHALLOW,
+ new SubProgressMonitor(subMonitor, 1));
+ }
+
+ if (subMonitor.isCanceled()) {
+ throw new OperationCanceledException();
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Transform an absolute path URI to a relative path one (i.e. from
+ * "C:\foo\bar\file.txt" to "VAR\file.txt" granted that the relativeVariable
+ * is "VAR" and points to "C:\foo\bar\").
+ *
+ * @param locationURI
+ * @return an URI that was made relative to a variable
+ */
+ private URI createRelativePath(URI locationURI, IResource resource) {
+ if (relativeVariable == null)
+ return locationURI;
+ IPath location = URIUtil.toPath(locationURI);
+ IPath result;
+ try {
+ result = URIUtil.toPath(resource.getPathVariableManager().convertToRelative(URIUtil.toURI(location), true, relativeVariable));
+ } catch (CoreException e) {
+ return locationURI;
+ }
+ return URIUtil.toURI(result);
+ }
+
+ /**
+ * Sets the content of the existing file to the source file content.
+ *
+ * @param source
+ * source file to copy
+ * @param existing
+ * existing file to set the source content in
+ * @param subMonitor
+ * a progress monitor for showing progress and for cancelation
+ * @throws CoreException
+ * setContents failed
+ */
+ private void copyExisting(IResource source, IResource existing,
+ IProgressMonitor subMonitor) throws CoreException {
+ IFile existingFile = getFile(existing);
+
+ if (existingFile != null) {
+ IFile sourceFile = getFile(source);
+
+ if (sourceFile != null) {
+ existingFile.setContents(sourceFile.getContents(),
+ IResource.KEEP_HISTORY, new SubProgressMonitor(
+ subMonitor, 0));
+ }
+ }
+ }
+
+ /**
+ * Copies the given resources to the destination. The current Thread is
+ * halted while the resources are copied using a WorkspaceModifyOperation.
+ * This method should be called from the UIThread.
+ *
+ * @param resources
+ * the resources to copy
+ * @param destination
+ * destination to which resources will be copied
+ * @return the resources which actually got copied
+ * @see WorkspaceModifyOperation
+ * @see Display#getThread()
+ * @see Thread#currentThread()
+ */
+ public IResource[] copyResources(final IResource[] resources,
+ IContainer destination) {
+ return copyResources(resources, destination, true);
+ }
+
+ /**
+ * Copies the given resources to the destination in the current Thread
+ * without forking a new Thread or blocking using a
+ * WorkspaceModifyOperation. It recommended that this method only be called
+ * from a {@link WorkspaceJob} to avoid possible deadlock.
+ *
+ * @param resources
+ * the resources to copy
+ * @param destination
+ * destination to which resources will be copied
+ * @param monitor
+ * the monitor that information will be sent to.
+ * @return IResource[] the resulting {@link IResource}[]
+ * @see WorkspaceModifyOperation
+ * @see WorkspaceJob
+ * @since 3.2
+ */
+ public IResource[] copyResourcesInCurrentThread(
+ final IResource[] resources, IContainer destination,
+ IProgressMonitor monitor) {
+ return copyResources(resources, destination, false);
+ }
+
+ /**
+ * Copies the given resources to the destination.
+ *
+ * @param resources
+ * the resources to copy
+ * @param destination
+ * destination to which resources will be copied
+ * @return IResource[] the resulting {@link IResource}[]
+ */
+ private IResource[] copyResources(final IResource[] resources,
+ IContainer destination, boolean fork) {
+ final IPath destinationPath = destination.getFullPath();
+ final IResource[][] copiedResources = new IResource[1][0];
+
+ // test resources for existence separate from validate API.
+ // Validate is performance critical and resource exists
+ // check is potentially slow. Fixes bugs 16129/28602.
+ IStatus resourceStatus = checkExist(resources);
+ if (resourceStatus.getSeverity() != IStatus.OK) {
+ displayError(resourceStatus);
+ return copiedResources[0];
+ }
+ String errorMsg = validateDestination(destination, resources);
+ if (errorMsg != null) {
+ displayError(errorMsg);
+ return copiedResources[0];
+ }
+
+ IRunnableWithProgress op = new IRunnableWithProgress() {
+ public void run(IProgressMonitor monitor) {
+ copyResources(resources, destinationPath, copiedResources,
+ monitor);
+ }
+ };
+
+ try {
+ PlatformUI.getWorkbench().getProgressService().run(fork, true, op);
+ } catch (InterruptedException e) {
+ return copiedResources[0];
+ } catch (InvocationTargetException e) {
+ display(e);
+ }
+
+ // If errors occurred, open an Error dialog
+ if (errorStatus != null) {
+ displayError(errorStatus);
+ errorStatus = null;
+ }
+
+ return copiedResources[0];
+ }
+
+ /**
+ * Return whether the operation is a move or a copy
+ *
+ * @return whether the operation is a move or a copy
+ * @since 3.2
+ */
+ protected boolean isMove() {
+ return false;
+ }
+
+ private void display(InvocationTargetException e) {
+ // CoreExceptions are collected above, but unexpected runtime
+ // exceptions and errors may still occur.
+ String format = "Exception in "+getClass().getName()+".performCopy(): "+e.getTargetException();
+
+ IDEWorkbenchPlugin.getDefault().getLog().log(
+ StatusUtil.newStatus(IStatus.ERROR, format, null));
+ displayError(NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_internalError,
+ e.getTargetException().getMessage()));
+ }
+
+ /**
+ * Copies the given URIS and folders to the destination. The current Thread
+ * is halted while the resources are copied using a
+ * WorkspaceModifyOperation. This method should be called from the UI
+ * Thread.
+ *
+ * @param uris
+ * the URIs to copy
+ * @param destination
+ * destination to which files will be copied
+ * @see WorkspaceModifyOperation
+ * @see Display#getThread()
+ * @see Thread#currentThread()
+ * @since 3.2
+ */
+ public void copyFiles(URI[] uris, IContainer destination) {
+ IFileStore[] stores = buildFileStores(uris);
+ if (stores == null) {
+ return;
+ }
+
+ copyFileStores(destination, stores, true, null);
+ }
+
+ /**
+ * Copies the given files and folders to the destination without forking a
+ * new Thread or blocking using a WorkspaceModifyOperation. It is
+ * recommended that this method only be called from a {@link WorkspaceJob}
+ * to avoid possible deadlock.
+ *
+ * @param uris
+ * the URIs to copy
+ * @param destination
+ * destination to which URIS will be copied
+ * @param monitor
+ * the monitor that information will be sent to.
+ * @see WorkspaceModifyOperation
+ * @see WorkspaceJob
+ * @since 3.2
+ */
+ public void copyFilesInCurrentThread(URI[] uris, IContainer destination,
+ IProgressMonitor monitor) {
+ IFileStore[] stores = buildFileStores(uris);
+ if (stores == null) {
+ return;
+ }
+
+ copyFileStores(destination, stores, false, monitor);
+ }
+
+ /**
+ * Build the collection of fileStores that map to fileNames. If any of them
+ * cannot be found then match then return <code>null</code>.
+ *
+ * @param uris
+ * @return IFileStore[]
+ */
+ private IFileStore[] buildFileStores(URI[] uris) {
+ IFileStore[] stores = new IFileStore[uris.length];
+ for (int i = 0; i < uris.length; i++) {
+ IFileStore store;
+ try {
+ store = EFS.getStore(uris[i]);
+ } catch (CoreException e) {
+ StatusManager.getManager().handle(e, IDEWorkbenchPlugin.IDE_WORKBENCH);
+ reportFileInfoNotFound(uris[i].toString());
+ return null;
+ }
+ if (store == null) {
+ reportFileInfoNotFound(uris[i].toString());
+ return null;
+ }
+ stores[i] = store;
+ }
+ return stores;
+
+ }
+
+ /**
+ * Depending on the 'Linked Resources' preferences it copies the given files and folders to the
+ * destination or creates links or shows a dialog that lets the user choose. The current thread
+ * is halted while the resources are copied using a {@link WorkspaceModifyOperation}. This
+ * method should be called from the UI Thread.
+ *
+ * @param fileNames names of the files to copy
+ * @param destination destination to which files will be copied
+ * @param dropOperation the drop operation ({@link DND#DROP_NONE}, {@link DND#DROP_MOVE}
+ * {@link DND#DROP_COPY}, {@link DND#DROP_LINK}, {@link DND#DROP_DEFAULT})
+ * @see WorkspaceModifyOperation
+ * @see Display#getThread()
+ * @see Thread#currentThread()
+ * @since 3.6
+ */
+ public void copyOrLinkFiles(final String[] fileNames, IContainer destination, int dropOperation) {
+ IPreferenceStore store= IDEWorkbenchPlugin.getDefault().getPreferenceStore();
+ boolean targetIsVirtual= destination.isVirtual();
+ String dndPreference= store.getString(targetIsVirtual ? IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_VIRTUAL_FOLDER_MODE : IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE);
+
+ int mode= ImportTypeDialog.IMPORT_NONE;
+ String variable= null;
+
+ //check if resource linking is disabled
+ if (ResourcesPlugin.getPlugin().getPluginPreferences().getBoolean(ResourcesPlugin.PREF_DISABLE_LINKING))
+ mode= ImportTypeDialog.IMPORT_COPY;
+ else {
+ if (dndPreference.equals(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_PROMPT)) {
+ ImportTypeDialog dialog= new ImportTypeDialog(messageShell, dropOperation, fileNames, destination);
+ dialog.setResource(destination);
+ if (dialog.open() == Window.OK) {
+ mode= dialog.getSelection();
+ variable= dialog.getVariable();
+ }
+ } else if (dndPreference.equals(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_MOVE_COPY)) {
+ mode= ImportTypeDialog.IMPORT_COPY;
+ } else if (dndPreference.equals(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_LINK)) {
+ mode= ImportTypeDialog.IMPORT_LINK;
+ } else if (dndPreference.equals(IDEInternalPreferences.IMPORT_FILES_AND_FOLDERS_MODE_LINK_AND_VIRTUAL_FOLDER)) {
+ mode= ImportTypeDialog.IMPORT_VIRTUAL_FOLDERS_AND_LINKS;
+ }
+ }
+
+ switch (mode) {
+ case ImportTypeDialog.IMPORT_COPY:
+ copyFiles(fileNames, destination);
+ break;
+ case ImportTypeDialog.IMPORT_VIRTUAL_FOLDERS_AND_LINKS:
+ if (variable != null)
+ setRelativeVariable(variable);
+ createVirtualFoldersAndLinks(fileNames, destination);
+ break;
+ case ImportTypeDialog.IMPORT_LINK:
+ if (variable != null)
+ setRelativeVariable(variable);
+ linkFiles(fileNames, destination);
+ break;
+ case ImportTypeDialog.IMPORT_NONE:
+ break;
+ }
+
+ }
+
+ /**
+ * Copies the given files and folders to the destination. The current Thread is halted while the
+ * resources are copied using a WorkspaceModifyOperation. This method should be called from the
+ * UI Thread.
+ *
+ * @param fileNames names of the files to copy
+ * @param destination destination to which files will be copied
+ * @see WorkspaceModifyOperation
+ * @see Display#getThread()
+ * @see Thread#currentThread()
+ * @since 3.2
+ */
+ public void copyFiles(final String[] fileNames, IContainer destination) {
+ IFileStore[] stores = buildFileStores(fileNames);
+ if (stores == null) {
+ return;
+ }
+
+ copyFileStores(destination, stores, true, null);
+ }
+
+ /**
+ * Copies the given files and folders to the destination without forking a
+ * new Thread or blocking using a WorkspaceModifyOperation. It is
+ * recommended that this method only be called from a {@link WorkspaceJob}
+ * to avoid possible deadlock.
+ *
+ * @param fileNames
+ * names of the files to copy
+ * @param destination
+ * destination to which files will be copied
+ * @param monitor
+ * the monitor that information will be sent to.
+ * @see WorkspaceModifyOperation
+ * @see WorkspaceJob
+ * @since 3.2
+ */
+ public void copyFilesInCurrentThread(final String[] fileNames,
+ IContainer destination, IProgressMonitor monitor) {
+ IFileStore[] stores = buildFileStores(fileNames);
+ if (stores == null) {
+ return;
+ }
+
+ copyFileStores(destination, stores, false, monitor);
+ }
+
+ /**
+ * Build the collection of fileStores that map to fileNames. If any of them
+ * cannot be found then match then return null.
+ *
+ * @param fileNames
+ * @return IFileStore[]
+ */
+ private IFileStore[] buildFileStores(final String[] fileNames) {
+ IFileStore[] stores = new IFileStore[fileNames.length];
+ for (int i = 0; i < fileNames.length; i++) {
+ IFileStore store = IDEResourceInfoUtils.getFileStore(fileNames[i]);
+ if (store == null) {
+ reportFileInfoNotFound(fileNames[i]);
+ return null;
+ }
+ stores[i] = store;
+ }
+ return stores;
+ }
+
+ /**
+ * Report that a file info could not be found.
+ *
+ * @param fileName
+ */
+ private void reportFileInfoNotFound(final String fileName) {
+
+ messageShell.getDisplay().syncExec(new Runnable() {
+ public void run() {
+ ErrorDialog
+ .openError(
+ messageShell,
+ getProblemsTitle(),
+ NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_infoNotFound,
+ fileName), null);
+ }
+ });
+ }
+
+ /**
+ * Copies the given files and folders to the destination.
+ *
+ * @param stores
+ * the file stores to copy
+ * @param destination
+ * destination to which files will be copied
+ */
+ private void copyFileStores(IContainer destination,
+ final IFileStore[] stores, boolean fork, IProgressMonitor monitor) {
+ // test files for existence separate from validate API
+ // because an external file may not exist until the copy actually
+ // takes place (e.g., WinZip contents).
+ IStatus fileStatus = checkExist(stores);
+ if (fileStatus.getSeverity() != IStatus.OK) {
+ displayError(fileStatus);
+ return;
+ }
+ String errorMsg = validateImportDestinationInternal(destination, stores);
+ if (errorMsg != null) {
+ displayError(errorMsg);
+ return;
+ }
+ final IPath destinationPath = destination.getFullPath();
+
+ if (fork) {
+ WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
+ public void execute(IProgressMonitor monitor) {
+ copyFileStores(stores, destinationPath, monitor);
+ }
+ };
+ try {
+ PlatformUI.getWorkbench().getProgressService().run(true, true,
+ op);
+ } catch (InterruptedException e) {
+ return;
+ } catch (InvocationTargetException exception) {
+ display(exception);
+ }
+ } else {
+ copyFileStores(stores, destinationPath, monitor);
+ }
+
+ // If errors occurred, open an Error dialog
+ if (errorStatus != null) {
+ displayError(errorStatus);
+ errorStatus = null;
+ }
+ }
+
+ /**
+ * Display the supplied status in an error dialog.
+ *
+ * @param status
+ * The status to display
+ */
+ protected void displayError(final IStatus status) {
+ messageShell.getDisplay().syncExec(new Runnable() {
+ public void run() {
+ ErrorDialog.openError(messageShell, getProblemsTitle(), null,
+ status);
+ }
+ });
+ }
+
+ /**
+ * Creates a file or folder handle for the source resource as if it were to
+ * be created in the destination container.
+ *
+ * @param destination
+ * destination container
+ * @param source
+ * source resource
+ * @return IResource file or folder handle, depending on the source type.
+ */
+ IResource createLinkedResourceHandle(IContainer destination,
+ IResource source) {
+ IWorkspace workspace = destination.getWorkspace();
+ IWorkspaceRoot workspaceRoot = workspace.getRoot();
+ IPath linkPath = destination.getFullPath().append(source.getName());
+ IResource linkHandle;
+
+ if (source.getType() == IResource.FOLDER) {
+ linkHandle = workspaceRoot.getFolder(linkPath);
+ } else {
+ linkHandle = workspaceRoot.getFile(linkPath);
+ }
+ return linkHandle;
+ }
+
+ /**
+ * Removes the given resource from the workspace.
+ *
+ * @param resource
+ * resource to remove from the workspace
+ * @param monitor
+ * a progress monitor for showing progress and for cancelation
+ * @return true the resource was deleted successfully false the resource was
+ * not deleted because a CoreException occurred
+ */
+ boolean delete(IResource resource, IProgressMonitor monitor) {
+ boolean force = false; // don't force deletion of out-of-sync resources
+
+ if (resource.getType() == IResource.PROJECT) {
+ // if it's a project, ask whether content should be deleted too
+ IProject project = (IProject) resource;
+ try {
+ project.delete(true, force, monitor);
+ } catch (CoreException e) {
+ recordError(e); // log error
+ return false;
+ }
+ } else {
+ // if it's not a project, just delete it
+ int flags = IResource.KEEP_HISTORY;
+ if (force) {
+ flags = flags | IResource.FORCE;
+ }
+ try {
+ resource.delete(flags, monitor);
+ } catch (CoreException e) {
+ recordError(e); // log error
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Opens an error dialog to display the given message.
+ *
+ * @param message
+ * the error message to show
+ */
+ protected void displayError(final String message) {
+ messageShell.getDisplay().syncExec(new Runnable() {
+ public void run() {
+ MessageDialog.openError(messageShell, getProblemsTitle(),
+ message);
+ }
+ });
+ }
+
+ /**
+ * Returns the resource either casted to or adapted to an IFile.
+ *
+ * @param resource
+ * resource to cast/adapt
+ * @return the resource either casted to or adapted to an IFile.
+ * <code>null</code> if the resource does not adapt to IFile
+ */
+ protected IFile getFile(IResource resource) {
+ if (resource instanceof IFile) {
+ return (IFile) resource;
+ }
+ return (IFile) ((IAdaptable) resource).getAdapter(IFile.class);
+ }
+
+ /**
+ * Returns java.io.File objects for the given file names.
+ *
+ * @param fileNames
+ * files to return File object for.
+ * @return java.io.File objects for the given file names.
+ * @deprecated As of 3.3, this method is no longer in use anywhere in this
+ * class and is only provided for backwards compatability with
+ * subclasses of the receiver.
+ */
+ protected File[] getFiles(String[] fileNames) {
+ File[] files = new File[fileNames.length];
+
+ for (int i = 0; i < fileNames.length; i++) {
+ files[i] = new File(fileNames[i]);
+ }
+ return files;
+ }
+
+ /**
+ * Returns the resource either casted to or adapted to an IFolder.
+ *
+ * @param resource
+ * resource to cast/adapt
+ * @return the resource either casted to or adapted to an IFolder.
+ * <code>null</code> if the resource does not adapt to IFolder
+ */
+ protected IFolder getFolder(IResource resource) {
+ if (resource instanceof IFolder) {
+ return (IFolder) resource;
+ }
+ return (IFolder) ((IAdaptable) resource).getAdapter(IFolder.class);
+ }
+
+ /**
+ * Returns a new name for a copy of the resource at the given path in the
+ * given workspace.
+ *
+ * @param originalName
+ * the full path of the resource
+ * @param workspace
+ * the workspace
+ * @return the new full path for the copy, or <code>null</code> if the
+ * resource should not be copied
+ */
+ protected IPath getNewNameFor(final IPath originalName,
+ final IWorkspace workspace) {
+ final IResource resource = workspace.getRoot().findMember(originalName);
+ final IPath prefix = resource.getFullPath().removeLastSegments(1);
+ final String returnValue[] = { "" }; //$NON-NLS-1$
+
+ messageShell.getDisplay().syncExec(new Runnable() {
+ public void run() {
+ IInputValidator validator = new IInputValidator() {
+ public String isValid(String string) {
+ if (resource.getName().equals(string)) {
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_nameMustBeDifferent;
+ }
+ IStatus status = workspace.validateName(string,
+ resource.getType());
+ if (!status.isOK()) {
+ return status.getMessage();
+ }
+ if (workspace.getRoot().exists(prefix.append(string))) {
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_nameExists;
+ }
+ return null;
+ }
+ };
+
+ InputDialog dialog = new InputDialog(
+ messageShell,
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_inputDialogTitle,
+ NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_inputDialogMessage,
+ resource.getName()), getAutoNewNameFor(
+ originalName, workspace).lastSegment()
+ .toString(), validator);
+ dialog.setBlockOnOpen(true);
+ dialog.open();
+ if (dialog.getReturnCode() == Window.CANCEL) {
+ returnValue[0] = null;
+ } else {
+ returnValue[0] = dialog.getValue();
+ }
+ }
+ });
+ if (returnValue[0] == null) {
+ throw new OperationCanceledException();
+ }
+ return prefix.append(returnValue[0]);
+ }
+
+ /**
+ * Returns the task title for this operation's progress dialog.
+ *
+ * @return the task title
+ */
+ protected String getOperationTitle() {
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_operationTitle;
+ }
+
+ /**
+ * Returns the message for this operation's problems dialog.
+ *
+ * @return the problems message
+ */
+ protected String getProblemsMessage() {
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_problemMessage;
+ }
+
+ /**
+ * Returns the title for this operation's problems dialog.
+ *
+ * @return the problems dialog title
+ */
+ protected String getProblemsTitle() {
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyFailedTitle;
+ }
+
+ /**
+ * Returns whether the source file in a destination collision will be
+ * validateEdited together with the collision itself. Returns false. Should
+ * return true if the source file is to be deleted after the operation.
+ *
+ * @return boolean <code>true</code> if the source file in a destination
+ * collision should be validateEdited. <code>false</code> if only
+ * the destination should be validated.
+ */
+ protected boolean getValidateConflictSource() {
+ return false;
+ }
+
+ /**
+ * Returns whether the given resources are either both linked or both
+ * unlinked.
+ *
+ * @param source
+ * source resource
+ * @param destination
+ * destination resource
+ * @return boolean <code>true</code> if both resources are either linked
+ * or unlinked. <code>false</code> otherwise.
+ */
+ protected boolean homogenousResources(IResource source,
+ IResource destination) {
+ boolean isSourceLinked = source.isLinked();
+ boolean isDestinationLinked = destination.isLinked();
+
+ return (isSourceLinked && isDestinationLinked || isSourceLinked == false
+ && isDestinationLinked == false);
+ }
+
+ /**
+ * Returns whether the given resource is accessible. Files and folders are
+ * always considered accessible and a project is accessible if it is open.
+ *
+ * @param resource
+ * the resource
+ * @return <code>true</code> if the resource is accessible, and
+ * <code>false</code> if it is not
+ */
+ private boolean isAccessible(IResource resource) {
+ switch (resource.getType()) {
+ case IResource.FILE:
+ return true;
+ case IResource.FOLDER:
+ return true;
+ case IResource.PROJECT:
+ return ((IProject) resource).isOpen();
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Returns whether any of the given source resources are being recopied to
+ * their current container.
+ *
+ * @param sourceResources
+ * the source resources
+ * @param destination
+ * the destination container
+ * @return <code>true</code> if at least one of the given source
+ * resource's parent container is the same as the destination
+ */
+ boolean isDestinationSameAsSource(IResource[] sourceResources,
+ IContainer destination) {
+ IPath destinationLocation = destination.getLocation();
+
+ for (int i = 0; i < sourceResources.length; i++) {
+ IResource sourceResource = sourceResources[i];
+ if (sourceResource.getParent().equals(destination)) {
+ return true;
+ } else if (destinationLocation != null) {
+ // do thorough check to catch linked resources. Fixes bug 29913.
+ IPath sourceLocation = sourceResource.getLocation();
+ IPath destinationResource = destinationLocation
+ .append(sourceResource.getName());
+ if (sourceLocation != null
+ && sourceLocation.isPrefixOf(destinationResource)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Copies the given resources to the destination container with the given
+ * name.
+ * <p>
+ * Note: the destination container may need to be created prior to copying
+ * the resources.
+ * </p>
+ *
+ * @param resources
+ * the resources to copy
+ * @param destination
+ * the path of the destination container
+ * @param monitor
+ * a progress monitor for showing progress and for cancelation
+ * @return <code>true</code> if the copy operation completed without
+ * errors
+ */
+ protected boolean performCopy(IResource[] resources, IPath destination,
+ IProgressMonitor monitor) {
+ try {
+ AbstractWorkspaceOperation op = getUndoableCopyOrMoveOperation(
+ resources, destination);
+ op.setModelProviderIds(getModelProviderIds());
+ if (op instanceof CopyResourcesOperation) {
+ CopyResourcesOperation copyMoveOp = (CopyResourcesOperation) op;
+ copyMoveOp.setCreateVirtualFolders(createVirtualFoldersAndLinks);
+ copyMoveOp.setCreateLinks(createLinks);
+ copyMoveOp.setRelativeVariable(relativeVariable);
+ }
+ PlatformUI.getWorkbench().getOperationSupport()
+ .getOperationHistory().execute(op, monitor,
+ WorkspaceUndoUtil.getUIInfoAdapter(messageShell));
+ } catch (ExecutionException e) {
+ if (e.getCause() instanceof CoreException) {
+ recordError((CoreException) e.getCause());
+ } else {
+ IDEWorkbenchPlugin.log(e.getMessage(), e);
+ displayError(e.getMessage());
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Individually copies the given resources to the specified destination
+ * container checking for name collisions. If a collision is detected, it is
+ * saved with a new name.
+ * <p>
+ * Note: the destination container may need to be created prior to copying
+ * the resources.
+ * </p>
+ *
+ * @param resources
+ * the resources to copy
+ * @param destination
+ * the path of the destination container
+ * @return <code>true</code> if the copy operation completed without
+ * errors.
+ */
+ protected boolean performCopyWithAutoRename(IResource[] resources,
+ IPath destination, IProgressMonitor monitor) {
+ IWorkspace workspace = resources[0].getWorkspace();
+ IPath[] destinationPaths = new IPath[resources.length];
+ try {
+ for (int i = 0; i < resources.length; i++) {
+ IResource source = resources[i];
+ destinationPaths[i] = destination.append(source.getName());
+
+ if (workspace.getRoot().exists(destinationPaths[i])) {
+ destinationPaths[i] = getNewNameFor(destinationPaths[i],
+ workspace);
+ }
+ }
+ CopyResourcesOperation op = new CopyResourcesOperation(resources,
+ destinationPaths,
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyTitle);
+ op.setModelProviderIds(getModelProviderIds());
+ PlatformUI.getWorkbench().getOperationSupport()
+ .getOperationHistory().execute(op, monitor,
+ WorkspaceUndoUtil.getUIInfoAdapter(messageShell));
+ } catch (ExecutionException e) {
+ if (e.getCause() instanceof CoreException) {
+ recordError((CoreException) e.getCause());
+ } else {
+ IDEWorkbenchPlugin.log(e.getMessage(), e);
+ displayError(e.getMessage());
+ }
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Performs an import of the given stores into the provided container.
+ * Returns a status indicating if the import was successful.
+ *
+ * @param stores
+ * stores that are to be imported
+ * @param target
+ * container to which the import will be done
+ * @param monitor
+ * a progress monitor for showing progress and for cancelation
+ */
+ private void performFileImport(IFileStore[] stores, IContainer target,
+ IProgressMonitor monitor) {
+ IOverwriteQuery query = new IOverwriteQuery() {
+ public String queryOverwrite(String pathString) {
+ if (alwaysOverwrite) {
+ return ALL;
+ }
+
+ final String returnCode[] = { CANCEL };
+ final String msg = NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteQuestion,
+ pathString);
+ final String[] options = { IDialogConstants.YES_LABEL,
+ IDialogConstants.YES_TO_ALL_LABEL,
+ IDialogConstants.NO_LABEL,
+ IDialogConstants.CANCEL_LABEL };
+ messageShell.getDisplay().syncExec(new Runnable() {
+ public void run() {
+ MessageDialog dialog = new MessageDialog(
+ messageShell,
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_question,
+ null, msg, MessageDialog.QUESTION, options, 0) {
+ protected int getShellStyle() {
+ return super.getShellStyle() | SWT.SHEET;
+ }
+ };
+ dialog.open();
+ int returnVal = dialog.getReturnCode();
+ String[] returnCodes = { YES, ALL, NO, CANCEL };
+ returnCode[0] = returnVal == -1 ? CANCEL
+ : returnCodes[returnVal];
+ }
+ });
+ if (returnCode[0] == ALL) {
+ alwaysOverwrite = true;
+ } else if (returnCode[0] == CANCEL) {
+ canceled = true;
+ }
+ return returnCode[0];
+ }
+ };
+
+ ImportOperation op = new ImportOperation(target.getFullPath(),
+ stores[0].getParent(), FileStoreStructureProvider.INSTANCE,
+ query, Arrays.asList(stores));
+ op.setContext(messageShell);
+ op.setCreateContainerStructure(false);
+ op.setVirtualFolders(createVirtualFoldersAndLinks);
+ op.setCreateLinks(createLinks);
+ op.setRelativeVariable(relativeVariable);
+ try {
+ op.run(monitor);
+ } catch (InterruptedException e) {
+ return;
+ } catch (InvocationTargetException e) {
+ if (e.getTargetException() instanceof CoreException) {
+ displayError(((CoreException) e.getTargetException())
+ .getStatus());
+ } else {
+ display(e);
+ }
+ return;
+ }
+ // Special case since ImportOperation doesn't throw a CoreException on
+ // failure.
+ IStatus status = op.getStatus();
+ if (!status.isOK()) {
+ if (errorStatus == null) {
+ errorStatus = new MultiStatus(PlatformUI.PLUGIN_ID,
+ IStatus.ERROR, getProblemsMessage(), null);
+ }
+ errorStatus.merge(status);
+ }
+ }
+
+ /**
+ * Records the core exception to be displayed to the user once the action is
+ * finished.
+ *
+ * @param error
+ * a <code>CoreException</code>
+ */
+ protected void recordError(CoreException error) {
+ if (errorStatus == null) {
+ errorStatus = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.ERROR,
+ getProblemsMessage(), error);
+ }
+
+ errorStatus.merge(error.getStatus());
+ }
+
+ /**
+ * Checks whether the destination is valid for copying the source resources.
+ * <p>
+ * Note this method is for internal use only. It is not API.
+ * </p>
+ *
+ * @param destination
+ * the destination container
+ * @param sourceResources
+ * the source resources
+ * @return an error message, or <code>null</code> if the path is valid
+ */
+ public String validateDestination(IContainer destination,
+ IResource[] sourceResources) {
+ if (!isAccessible(destination)) {
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationAccessError;
+ }
+ IContainer firstParent = null;
+ URI destinationLocation = destination.getLocationURI();
+ for (int i = 0; i < sourceResources.length; i++) {
+ IResource sourceResource = sourceResources[i];
+ if (firstParent == null) {
+ firstParent = sourceResource.getParent();
+ } else if (firstParent.equals(sourceResource.getParent()) == false) {
+ // Resources must have common parent. Fixes bug 33398.
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_parentNotEqual;
+ }
+
+ // verify that if the destination is a virtual folder, the resource must be
+ // either a link or another virtual folder
+ if (destination.isVirtual()) {
+ if (!sourceResource.isLinked() && !sourceResource.isVirtual()
+ && !createLinks && !createVirtualFoldersAndLinks) {
+ return NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_sourceCannotBeCopiedIntoAVirtualFolder,
+ sourceResource.getName());
+ }
+ }
+ URI sourceLocation = sourceResource.getLocationURI();
+ if (sourceLocation == null) {
+ if (sourceResource.isLinked()) {
+ // Don't allow copying linked resources with undefined path
+ // variables. See bug 28754.
+ return NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_missingPathVariable,
+ sourceResource.getName());
+ }
+ return NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_resourceDeleted,
+ sourceResource.getName());
+
+ }
+ if (!destination.isVirtual()) {
+ if (sourceLocation.equals(destinationLocation)) {
+ return NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_sameSourceAndDest,
+ sourceResource.getName());
+ }
+ // is the source a parent of the destination?
+ if (new Path(sourceLocation.toString()).isPrefixOf(new Path(
+ destinationLocation.toString()))) {
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationDescendentError;
+ }
+ }
+
+ String linkedResourceMessage = validateLinkedResource(destination,
+ sourceResource);
+ if (linkedResourceMessage != null) {
+ return linkedResourceMessage;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Validates that the given source resources can be copied to the
+ * destination as decided by the VCM provider.
+ *
+ * @param destination
+ * copy destination
+ * @param sourceResources
+ * source resources
+ * @return <code>true</code> all files passed validation or there were no
+ * files to validate. <code>false</code> one or more files did not
+ * pass validation.
+ */
+ private boolean validateEdit(IContainer destination,
+ IResource[] sourceResources) {
+ ArrayList copyFiles = new ArrayList();
+
+ collectExistingReadonlyFiles(destination.getFullPath(),
+ sourceResources, copyFiles);
+ if (copyFiles.size() > 0) {
+ IFile[] files = (IFile[]) copyFiles.toArray(new IFile[copyFiles
+ .size()]);
+ IWorkspace workspace = ResourcesPlugin.getWorkspace();
+ IStatus status = workspace.validateEdit(files, messageShell);
+
+ canceled = status.isOK() == false;
+ return status.isOK();
+ }
+ return true;
+ }
+
+ /**
+ * Checks whether the destination is valid for copying the source files.
+ * <p>
+ * Note this method is for internal use only. It is not API.
+ * </p>
+ *
+ * @param destination
+ * the destination container
+ * @param sourceNames
+ * the source file names
+ * @return an error message, or <code>null</code> if the path is valid
+ */
+ public String validateImportDestination(IContainer destination,
+ String[] sourceNames) {
+
+ IFileStore[] stores = new IFileStore[sourceNames.length];
+ for (int i = 0; i < sourceNames.length; i++) {
+ IFileStore store = IDEResourceInfoUtils
+ .getFileStore(sourceNames[i]);
+ if (store == null) {
+ return NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_infoNotFound,
+ sourceNames[i]);
+ }
+ stores[i] = store;
+ }
+ return validateImportDestinationInternal(destination, stores);
+
+ }
+
+ /**
+ * Checks whether the destination is valid for copying the source file
+ * stores.
+ * <p>
+ * Note this method is for internal use only. It is not API.
+ * </p>
+ * <p>
+ * TODO Bug 117804. This method has been renamed to avoid a bug in the
+ * Eclipse compiler with regards to visibility and type resolution when
+ * linking.
+ * </p>
+ *
+ * @param destination
+ * the destination container
+ * @param sourceStores
+ * the source IFileStore
+ * @return an error message, or <code>null</code> if the path is valid
+ */
+ private String validateImportDestinationInternal(IContainer destination,
+ IFileStore[] sourceStores) {
+ if (!isAccessible(destination))
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationAccessError;
+
+ if (!destination.isVirtual()) {
+ IFileStore destinationStore;
+ try {
+ destinationStore = EFS.getStore(destination.getLocationURI());
+ } catch (CoreException exception) {
+ IDEWorkbenchPlugin.log(exception.getLocalizedMessage(), exception);
+ return NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_internalError,
+ exception.getLocalizedMessage());
+ }
+ for (int i = 0; i < sourceStores.length; i++) {
+ IFileStore sourceStore = sourceStores[i];
+ IFileStore sourceParentStore = sourceStore.getParent();
+
+ if (sourceStore != null) {
+ if (destinationStore.equals(sourceStore)
+ || (sourceParentStore != null && destinationStore
+ .equals(sourceParentStore))) {
+ return NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_importSameSourceAndDest,
+ sourceStore.getName());
+ }
+ // work around bug 16202. replacement for
+ // sourcePath.isPrefixOf(destinationPath)
+ if (sourceStore.isParentOf(destinationStore)) {
+ return IDEWorkbenchMessages.CopyFilesAndFoldersOperation_destinationDescendentError;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Check if the destination is valid for the given source resource.
+ *
+ * @param destination
+ * destination container of the operation
+ * @param source
+ * source resource
+ * @return String error message or null if the destination is valid
+ */
+ private String validateLinkedResource(IContainer destination,
+ IResource source) {
+ if ((source.isLinked() == false) || source.isVirtual()) {
+ return null;
+ }
+ IWorkspace workspace = destination.getWorkspace();
+ IResource linkHandle = createLinkedResourceHandle(destination, source);
+ IStatus locationStatus = workspace.validateLinkLocationURI(linkHandle,
+ source.getRawLocationURI());
+
+ if (locationStatus.getSeverity() == IStatus.ERROR) {
+ return locationStatus.getMessage();
+ }
+ IPath sourceLocation = source.getLocation();
+ if (source.getProject().equals(destination.getProject()) == false
+ && source.getType() == IResource.FOLDER
+ && sourceLocation != null) {
+ // prevent merging linked folders that point to the same
+ // file system folder
+ try {
+ IResource[] members = destination.members();
+ for (int j = 0; j < members.length; j++) {
+ if (sourceLocation.equals(members[j].getLocation())
+ && source.getName().equals(members[j].getName())) {
+ return NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_sameSourceAndDest,
+ source.getName());
+ }
+ }
+ } catch (CoreException exception) {
+ displayError(NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_internalError,
+ exception.getMessage()));
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns whether moving all of the given source resources to the given
+ * destination container could be done without causing name collisions.
+ *
+ * @param destination
+ * the destination container
+ * @param sourceResources
+ * the list of resources
+ * @return <code>true</code> if there would be no name collisions, and
+ * <code>false</code> if there would
+ */
+ private IResource[] validateNoNameCollisions(IContainer destination,
+ IResource[] sourceResources) {
+ List copyItems = new ArrayList();
+ IWorkspaceRoot workspaceRoot = destination.getWorkspace().getRoot();
+ int overwrite = IDialogConstants.NO_ID;
+
+ // Check to see if we would be overwriting a parent folder.
+ // Cancel entire copy operation if we do.
+ for (int i = 0; i < sourceResources.length; i++) {
+ final IResource sourceResource = sourceResources[i];
+ final IPath destinationPath = destination.getFullPath().append(
+ sourceResource.getName());
+ final IPath sourcePath = sourceResource.getFullPath();
+
+ IResource newResource = workspaceRoot.findMember(destinationPath);
+ if (newResource != null && destinationPath.isPrefixOf(sourcePath)) {
+ displayError(NLS
+ .bind(
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_overwriteProblem,
+ destinationPath, sourcePath));
+
+ canceled = true;
+ return null;
+ }
+ }
+ // Check for overwrite conflicts
+ for (int i = 0; i < sourceResources.length; i++) {
+ final IResource source = sourceResources[i];
+ final IPath destinationPath = destination.getFullPath().append(
+ source.getName());
+
+ IResource newResource = workspaceRoot.findMember(destinationPath);
+ if (newResource != null) {
+ if (overwrite != IDialogConstants.YES_TO_ALL_ID
+ || (newResource.getType() == IResource.FOLDER && homogenousResources(
+ source, destination) == false)) {
+ overwrite = checkOverwrite(source, newResource);
+ }
+ if (overwrite == IDialogConstants.YES_ID
+ || overwrite == IDialogConstants.YES_TO_ALL_ID) {
+ copyItems.add(source);
+ } else if (overwrite == IDialogConstants.CANCEL_ID) {
+ canceled = true;
+ return null;
+ }
+ } else {
+ copyItems.add(source);
+ }
+ }
+ return (IResource[]) copyItems.toArray(new IResource[copyItems.size()]);
+ }
+
+ private void copyResources(final IResource[] resources,
+ final IPath destinationPath, final IResource[][] copiedResources,
+ IProgressMonitor monitor) {
+ IResource[] copyResources = resources;
+
+ // Fix for bug 31116. Do not provide a task name when
+ // creating the task.
+ monitor.beginTask("", 100); //$NON-NLS-1$
+ monitor.setTaskName(getOperationTitle());
+ monitor.worked(10); // show some initial progress
+
+ // Checks only required if this is an exisiting container path.
+ boolean copyWithAutoRename = false;
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ if (root.exists(destinationPath)) {
+ IContainer container = (IContainer) root
+ .findMember(destinationPath);
+ // If we're copying to the source container then perform
+ // auto-renames on all resources to avoid name collisions.
+ if (isDestinationSameAsSource(copyResources, container)
+ && canPerformAutoRename()) {
+ copyWithAutoRename = true;
+ } else {
+ // If no auto-renaming will be happening, check for
+ // potential name collisions at the target resource
+ copyResources = validateNoNameCollisions(container,
+ copyResources);
+ if (copyResources == null) {
+ if (canceled) {
+ return;
+ }
+ displayError(IDEWorkbenchMessages.CopyFilesAndFoldersOperation_nameCollision);
+ return;
+ }
+ if (validateEdit(container, copyResources) == false) {
+ return;
+ }
+ }
+ }
+
+ errorStatus = null;
+ if (copyResources.length > 0) {
+ if (copyWithAutoRename) {
+ performCopyWithAutoRename(copyResources, destinationPath,
+ new SubProgressMonitor(monitor, 90));
+ } else {
+ performCopy(copyResources, destinationPath, new SubProgressMonitor(monitor, 90));
+ }
+ }
+ monitor.done();
+ copiedResources[0] = copyResources;
+ }
+
+ private void copyFileStores(final IFileStore[] stores,
+ final IPath destinationPath, IProgressMonitor monitor) {
+ // Checks only required if this is an exisiting container path.
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ if (root.exists(destinationPath)) {
+ IContainer container = (IContainer) root
+ .findMember(destinationPath);
+
+ performFileImport(stores, container, monitor);
+ }
+ }
+
+ /**
+ * Returns the model provider ids that are known to the client that
+ * instantiated this operation.
+ *
+ * @return the model provider ids that are known to the client that
+ * instantiated this operation.
+ * @since 3.2
+ */
+ public String[] getModelProviderIds() {
+ return modelProviderIds;
+ }
+
+ /**
+ * Sets the model provider ids that are known to the client that
+ * instantiated this operation. Any potential side effects reported by these
+ * models during validation will be ignored.
+ *
+ * @param modelProviderIds
+ * the model providers known to the client who is using this
+ * operation.
+ * @since 3.2
+ */
+ public void setModelProviderIds(String[] modelProviderIds) {
+ this.modelProviderIds = modelProviderIds;
+ }
+
+ /**
+ * Create virtual folders and links of the given files and folders to the
+ * destination. The current Thread is halted while the resources are copied
+ * using a WorkspaceModifyOperation. This method should be called from the
+ * UI Thread.
+ *
+ * @param fileNames
+ * names of the files to copy
+ * @param destination
+ * destination to which files will be copied
+ * @see WorkspaceModifyOperation
+ * @see Display#getThread()
+ * @see Thread#currentThread()
+ * @since 3.6
+ */
+ public void createVirtualFoldersAndLinks(final String[] fileNames,
+ IContainer destination) {
+ IFileStore[] stores = buildFileStores(fileNames);
+ if (stores == null) {
+ return;
+ }
+
+ createVirtualFoldersAndLinks = true;
+ copyFileStores(destination, stores, true, null);
+ }
+
+ /**
+ * Create links of the given files and folders to the destination. The
+ * current Thread is halted while the resources are copied using a
+ * WorkspaceModifyOperation. This method should be called from the UI
+ * Thread.
+ *
+ * @param fileNames
+ * names of the files to copy
+ * @param destination
+ * destination to which files will be copied
+ * @see WorkspaceModifyOperation
+ * @see Display#getThread()
+ * @see Thread#currentThread()
+ * @since 3.6
+ */
+ public void linkFiles(final String[] fileNames, IContainer destination) {
+ IFileStore[] stores = buildFileStores(fileNames);
+ if (stores == null) {
+ return;
+ }
+
+ createLinks = true;
+ copyFileStores(destination, stores, true, null);
+ }
+
+ /**
+ * Set whether or not virtual folders and links will be created under the destination
+ * container.
+ *
+ * @param value
+ * @since 3.6
+ */
+ public void setVirtualFolders(boolean value) {
+ createVirtualFoldersAndLinks = value;
+ }
+
+ /**
+ * Set whether or not links will be created under the destination container.
+ *
+ * @param value
+ * @since 3.6
+ */
+ public void setCreateLinks(boolean value) {
+ createLinks = value;
+ }
+
+ /**
+ * Set a variable relative to which the links are created
+ *
+ * @param variable
+ * @since 3.6
+ */
+ public void setRelativeVariable(String variable) {
+ relativeVariable = variable;
+ }
+
+ /**
+ * Returns an AbstractWorkspaceOperation suitable for performing the move or
+ * copy operation that will move or copy the given resources to the given
+ * destination path.
+ *
+ * @param resources
+ * the resources to be moved or copied
+ * @param destinationPath
+ * the destination path to which the resources should be moved
+ * @return the operation that should be used to perform the move or cop
+ * @since 3.3
+ */
+ protected AbstractWorkspaceOperation getUndoableCopyOrMoveOperation(
+ IResource[] resources, IPath destinationPath) {
+ return new CopyResourcesOperation(resources, destinationPath,
+ IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyTitle);
+
+ }
+}
diff --git a/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/action/PapyrusCopyFilesAndFoldersOperation.java b/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/action/PapyrusCopyFilesAndFoldersOperation.java
new file mode 100644
index 0000000..2706699
--- /dev/null
+++ b/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/action/PapyrusCopyFilesAndFoldersOperation.java
@@ -0,0 +1,190 @@
+/*****************************************************************************
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Benoit Maggi benoit.maggi@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.onefile.action;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.DiModel;
+import org.eclipse.papyrus.infra.emf.resource.DependencyManagementHelper;
+import org.eclipse.papyrus.infra.emf.resource.MoveFileURIReplacementStrategy;
+import org.eclipse.papyrus.infra.emf.resource.RestoreDependencyHelper;
+import org.eclipse.papyrus.infra.emf.utils.ResourceUtils;
+import org.eclipse.papyrus.infra.onefile.Activator;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.ide.undo.CopyResourcesOperation;
+import org.eclipse.ui.ide.undo.WorkspaceUndoUtil;
+import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
+import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
+
+
+
+/**
+ * Implementation of Papyrus paste for model
+ */
+public class PapyrusCopyFilesAndFoldersOperation extends CopyFilesAndFoldersOperation {
+
+ protected Map<String, String> renameMapping = new HashMap<String, String>();
+
+ protected IPath[] destinationPaths = null;
+
+ public PapyrusCopyFilesAndFoldersOperation(Shell shell) {
+ super(shell);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.infra.onefile.action.CopyFilesAndFoldersOperation#performCopyWithAutoRename(org.eclipse.core.resources.IResource[],
+ * org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ // perform rename only for .di
+ protected boolean performCopyWithAutoRename(IResource[] resources, IPath destination, IProgressMonitor monitor) {
+ IWorkspace workspace = resources[0].getWorkspace();
+ destinationPaths = new IPath[resources.length];
+ try {
+ String oldName = ""; //$NON-NLS-1$
+ String newName = ""; //$NON-NLS-1$
+ for(int i = 0; i < resources.length; i++) {
+ IResource source = resources[i];
+ destinationPaths[i] = destination.append(source.getName());
+ IPath relativSourcePath = source.getFullPath();
+ String sourceFileName = relativSourcePath.removeFileExtension().lastSegment();
+ if(sourceFileName.equals(oldName)) {
+ String fileExtension = relativSourcePath.getFileExtension();
+ destinationPaths[i] = relativSourcePath.removeLastSegments(1).append(newName).addFileExtension(fileExtension);
+ } else {
+ oldName = sourceFileName;
+ if(workspace.getRoot().exists(destinationPaths[i]) && destinationPaths[i].getFileExtension().equals(DiModel.MODEL_FILE_EXTENSION)) {
+ destinationPaths[i] = getNewNameFor(destinationPaths[i], workspace);
+ newName = destinationPaths[i].removeFileExtension().lastSegment();
+ }
+ renameMapping.put(oldName, newName);
+ }
+
+ }
+ CopyResourcesOperation op = new CopyResourcesOperation(resources, destinationPaths, IDEWorkbenchMessages.CopyFilesAndFoldersOperation_copyTitle);
+ op.setModelProviderIds(getModelProviderIds());
+ PlatformUI.getWorkbench().getOperationSupport().getOperationHistory().execute(op, monitor, WorkspaceUndoUtil.getUIInfoAdapter(messageShell));
+ } catch (ExecutionException e) {
+ if(e.getCause() instanceof CoreException) {
+ recordError((CoreException)e.getCause());
+ } else {
+ IDEWorkbenchPlugin.log(e.getMessage(), e);
+ displayError(e.getMessage());
+ }
+ return false;
+ }
+ return true;
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.infra.onefile.action.CopyFilesAndFoldersOperation#performCopy(org.eclipse.core.resources.IResource[],
+ * org.eclipse.core.runtime.IPath, org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ // store path of created files
+ protected boolean performCopy(IResource[] resources, IPath destination, IProgressMonitor monitor) {
+ boolean performCopy = super.performCopy(resources, destination, monitor);
+ if(performCopy) {
+ destinationPaths = new IPath[resources.length];
+ for(int i = 0; i < resources.length; i++) {
+ String name = resources[i].getName();
+ destinationPaths[i] = destination.append(name);
+ }
+ }
+ return performCopy;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.infra.onefile.action.CopyFilesAndFoldersOperation#copyResources(org.eclipse.core.resources.IResource[],
+ * org.eclipse.core.resources.IContainer)
+ */
+ @Override
+ // restore internal and external link coherence
+ public IResource[] copyResources(IResource[] resources, IContainer destination) {
+ IResource[] copyResources = super.copyResources(resources, destination);
+ try {
+ ModelSet modelSet = new ModelSet();
+ restoreInternalLinks(modelSet, resources, copyResources);
+ restoreExternalLinks(modelSet, resources, copyResources);
+ } catch (IOException e) {
+ Activator.log.error("It was not possible to restore broken links", e); //$NON-NLS-1$
+ }
+ return copyResources;
+ }
+
+
+ /**
+ * Restore referenced URI following the pattern ;
+ * - if there is an accessible Resource use it
+ * - else search the resource in the source location of the copy
+ * @param resources
+ * @param copyResources
+ * @throws IOException
+ */
+ protected void restoreExternalLinks(ModelSet modelSet, IResource[] resources, IResource[] copyResources) throws IOException {
+ for(int i = 0; i < destinationPaths.length; i++) {
+ IPath iPath = destinationPaths[i];
+ URI uri = URI.createPlatformResourceURI(iPath.toString(), Boolean.TRUE);
+ Resource resource = modelSet.getResource(uri, Boolean.TRUE);
+ for(int j = 0; j < copyResources.length; j++) {
+ IPath targetPath = destinationPaths[j];
+ IResource sourceResource = copyResources[j];
+ URI targetURI = URI.createPlatformResourceURI(targetPath.toString(), true);
+ URI sourceURI = URI.createPlatformResourceURI(sourceResource.getFullPath().toString(), true);
+ DependencyManagementHelper.updateDependencies(sourceURI, targetURI, resource);
+ }
+ resource.save(ResourceUtils.getSaveOptions());
+ }
+ }
+
+ /**
+ * Restore links to maintain coherence in the 3 files: uml-notation-di
+ * @param resources
+ * @param copyResources
+ * @throws IOException
+ */
+ protected void restoreInternalLinks(ModelSet modelSet, IResource[] resources, IResource[] copyResources) throws IOException {
+ for(int i = 0; i < destinationPaths.length; i++) {
+ IPath iPath = destinationPaths[i];
+ MoveFileURIReplacementStrategy iURIReplacementStrategy = new MoveFileURIReplacementStrategy(new HashMap<URI, URI>(), resources[i].getFullPath().removeLastSegments(1), iPath.removeLastSegments(1));
+ RestoreDependencyHelper restoreDependencyHelper = new RestoreDependencyHelper(iURIReplacementStrategy);
+ URI uri = URI.createPlatformResourceURI(iPath.toString(), Boolean.TRUE);
+ Resource resource = modelSet.getResource(uri, Boolean.TRUE);
+ restoreDependencyHelper.restoreDependencies(resource);
+ resource.save(ResourceUtils.getSaveOptions());
+ }
+ }
+
+}
diff --git a/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/action/PapyrusModelPasteAction.java b/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/action/PapyrusModelPasteAction.java
new file mode 100644
index 0000000..9c78949
--- /dev/null
+++ b/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/action/PapyrusModelPasteAction.java
@@ -0,0 +1,50 @@
+/*****************************************************************************
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Benoit Maggi benoit.maggi@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.onefile.action;
+
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.widgets.Shell;
+
+
+/**
+ * Action for pasting IPapyrusfiles
+ *
+ */
+public class PapyrusModelPasteAction extends PasteAction {
+
+
+ /**
+ * Action for pasting IPapyrusfiles
+ *
+ * @param shell
+ * @param clipboard
+ */
+ public PapyrusModelPasteAction(Shell shell, Clipboard clipboard) {
+ super(shell, clipboard);
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.papyrus.infra.onefile.action.PasteAction#createCopyFilesAndFolderOperation(org.eclipse.swt.widgets.Shell)
+ */
+ @Override
+ protected CopyFilesAndFoldersOperation createCopyFilesAndFolderOperation(Shell shell) {
+ return new PapyrusCopyFilesAndFoldersOperation(shell);
+ }
+
+
+}
diff --git a/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/action/PasteAction.java b/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/action/PasteAction.java
new file mode 100644
index 0000000..c167657
--- /dev/null
+++ b/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/action/PasteAction.java
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation 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:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.papyrus.infra.onefile.action;
+
+
+import java.util.List;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.CopyProjectOperation;
+import org.eclipse.ui.actions.SelectionListenerAction;
+import org.eclipse.ui.internal.navigator.resources.plugin.WorkbenchNavigatorMessages;
+import org.eclipse.ui.part.ResourceTransfer;
+
+/**
+ * Standard action for pasting resources on the clipboard to the selected resource's location.
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.
+ * </p>
+ *
+ * @since 2.0
+ */
+/*package*/class PasteAction extends SelectionListenerAction {
+
+ /**
+ * The id of this action.
+ */
+ public static final String ID = PlatformUI.PLUGIN_ID + ".PasteAction";//$NON-NLS-1$
+
+ /**
+ * The shell in which to show any dialogs.
+ */
+ protected Shell shell;
+
+ /**
+ * System clipboard
+ */
+ protected Clipboard clipboard;
+
+ /**
+ * Creates a new action.
+ *
+ * @param shell the shell for any dialogs
+ * @param clipboard the clipboard
+ */
+ public PasteAction(Shell shell, Clipboard clipboard) {
+ super(WorkbenchNavigatorMessages.PasteAction_Past_);
+ Assert.isNotNull(shell);
+ Assert.isNotNull(clipboard);
+ this.shell = shell;
+ this.clipboard = clipboard;
+ setToolTipText(WorkbenchNavigatorMessages.PasteAction_Paste_selected_resource_s_);
+ setId(PasteAction.ID);
+ PlatformUI.getWorkbench().getHelpSystem().setHelp(this, "HelpId"); //$NON-NLS-1$
+ // TODO INavigatorHelpContextIds.PASTE_ACTION);
+ }
+
+ /**
+ * Returns the actual target of the paste action. Returns null
+ * if no valid target is selected.
+ *
+ * @return the actual target of the paste action
+ */
+ private IResource getTarget() {
+ List<IResource> selectedResources = getSelectedResources();
+
+ for (IResource resource : selectedResources) {
+ if (resource instanceof IProject && !((IProject) resource).isOpen()) {
+ return null;
+ }
+ if (resource.getType() == IResource.FILE) {
+ resource = resource.getParent();
+ }
+ if (resource != null) {
+ return resource;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns whether any of the given resources are linked resources.
+ *
+ * @param resources resource to check for linked type. may be null
+ * @return true=one or more resources are linked. false=none of the
+ * resources are linked
+ */
+ private boolean isLinked(IResource[] resources) {
+ for (int i = 0; i < resources.length; i++) {
+ if (resources[i].isLinked()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Implementation of method defined on <code>IAction</code>.
+ */
+ public void run() {
+ // try a resource transfer
+ ResourceTransfer resTransfer = ResourceTransfer.getInstance();
+ IResource[] resourceData = (IResource[]) clipboard
+ .getContents(resTransfer);
+
+ if (resourceData != null && resourceData.length > 0) {
+ if (resourceData[0].getType() == IResource.PROJECT) {
+ // enablement checks for all projects
+ for (int i = 0; i < resourceData.length; i++) {
+ CopyProjectOperation operation = new CopyProjectOperation(
+ this.shell);
+ operation.copyProject((IProject) resourceData[i]);
+ }
+ } else {
+ // enablement should ensure that we always have access to a container
+ IContainer container = getContainer();
+
+ CopyFilesAndFoldersOperation operation = createCopyFilesAndFolderOperation(this.shell);
+ operation.copyResources(resourceData, container);
+ }
+ return;
+ }
+
+ // try a file transfer
+ FileTransfer fileTransfer = FileTransfer.getInstance();
+ String[] fileData = (String[]) clipboard.getContents(fileTransfer);
+
+ if (fileData != null) {
+ // enablement should ensure that we always have access to a container
+ IContainer container = getContainer();
+
+ CopyFilesAndFoldersOperation operation = createCopyFilesAndFolderOperation(this.shell);
+ operation.copyFiles(fileData, container);
+ }
+ }
+
+ protected CopyFilesAndFoldersOperation createCopyFilesAndFolderOperation(Shell shell) {
+ return new CopyFilesAndFoldersOperation(shell);
+ }
+
+
+
+
+ /**
+ * Returns the container to hold the pasted resources.
+ */
+ protected IContainer getContainer() {
+ List selectedResources = getSelectedResources();
+ List<IResource> selection = selectedResources;
+ if (selection.get(0) instanceof IFile) {
+ return ((IFile) selection.get(0)).getParent();
+ }
+ return (IContainer) selection.get(0);
+ }
+
+ /**
+ * The <code>PasteAction</code> implementation of this
+ * <code>SelectionListenerAction</code> method enables this action if
+ * a resource compatible with what is on the clipboard is selected.
+ *
+ * -Clipboard must have IResource or java.io.File
+ * -Projects can always be pasted if they are open
+ * -Workspace folder may not be copied into itself
+ * -Files and folders may be pasted to a single selected folder in open
+ * project or multiple selected files in the same folder
+ */
+ protected boolean updateSelection(IStructuredSelection selection) {
+ if (!super.updateSelection(selection)) {
+ return false;
+ }
+
+ final IResource[][] clipboardData = new IResource[1][];
+ shell.getDisplay().syncExec(new Runnable() {
+ public void run() {
+ // clipboard must have resources or files
+ ResourceTransfer resTransfer = ResourceTransfer.getInstance();
+ clipboardData[0] = (IResource[]) clipboard
+ .getContents(resTransfer);
+ }
+ });
+ IResource[] resourceData = clipboardData[0];
+ boolean isProjectRes = resourceData != null && resourceData.length > 0
+ && resourceData[0].getType() == IResource.PROJECT;
+
+ if (isProjectRes) {
+ for (int i = 0; i < resourceData.length; i++) {
+ // make sure all resource data are open projects
+ // can paste open projects regardless of selection
+ if (resourceData[i].getType() != IResource.PROJECT
+ || ((IProject) resourceData[i]).isOpen() == false) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ if (getSelectedNonResources().size() > 0) {
+ return false;
+ }
+
+ IResource targetResource = getTarget();
+ // targetResource is null if no valid target is selected (e.g., open project)
+ // or selection is empty
+ if (targetResource == null) {
+ return false;
+ }
+
+ // can paste files and folders to a single selection (file, folder,
+ // open project) or multiple file selection with the same parent
+ List<IResource> selectedResources = getSelectedResources();
+ if (selectedResources.size() > 1) {
+ for (IResource resource : selectedResources) {
+ if (resource.getType() != IResource.FILE) {
+ return false;
+ }
+ if (!targetResource.equals(resource.getParent())) {
+ return false;
+ }
+ }
+ }
+ if (resourceData != null) {
+ // linked resources can only be pasted into projects
+ if (isLinked(resourceData)
+ && targetResource.getType() != IResource.PROJECT
+ && targetResource.getType() != IResource.FOLDER) {
+ return false;
+ }
+
+ if (targetResource.getType() == IResource.FOLDER) {
+ // don't try to copy folder to self
+ for (int i = 0; i < resourceData.length; i++) {
+ if (targetResource.equals(resourceData[i])) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ TransferData[] transfers = clipboard.getAvailableTypes();
+ FileTransfer fileTransfer = FileTransfer.getInstance();
+ for (int i = 0; i < transfers.length; i++) {
+ if (fileTransfer.isSupportedType(transfers[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
diff --git a/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/providers/CopyToClipboardAction.java b/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/providers/CopyToClipboardAction.java
new file mode 100644
index 0000000..4aa834f
--- /dev/null
+++ b/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/providers/CopyToClipboardAction.java
@@ -0,0 +1,70 @@
+/*****************************************************************************
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Benoit Maggi benoit.maggi@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.onefile.providers;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.window.IShellProvider;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.actions.CopyResourceAction;
+import org.eclipse.ui.part.ResourceTransfer;
+
+/**
+ * Copy to the clipboard the payrus model as 3 IResource
+ *
+ */
+public class CopyToClipboardAction extends CopyResourceAction {
+
+ protected Clipboard fClipboard;
+
+ public CopyToClipboardAction(IShellProvider shellProvider) {
+ super(shellProvider);
+ }
+
+ @Override
+ public void run() {
+ Display display = shellProvider.getShell().getDisplay();
+ fClipboard= new Clipboard(display);
+ IStructuredSelection structuredSelection = getStructuredSelection();
+ try {
+ copytoClipboardStructuredSelection(structuredSelection);
+ } finally {
+ fClipboard.dispose();
+ }
+ }
+
+
+ /**
+ * Copy in the clipboard the selection
+ * @param selection
+ */
+ public void copytoClipboardStructuredSelection(IStructuredSelection selection) {
+ Display display = Display.getCurrent();
+ Clipboard clipboard = new Clipboard(display);
+ Object[] array = selection.toArray();
+ IResource[] associatedResources = new IResource[array.length];
+ for(int i = 0; i < associatedResources.length; i++) {
+ Object object = array[i];
+ if (object instanceof IResource){
+ associatedResources[i]= (IResource) object;
+ }
+ }
+ clipboard.setContents(new Object[] { associatedResources },
+ new Transfer[] { ResourceTransfer.getInstance() });
+ clipboard.dispose();
+ }
+}
diff --git a/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/providers/PapyrusEditActionProvider.java b/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/providers/PapyrusEditActionProvider.java
new file mode 100644
index 0000000..adfd7f5
--- /dev/null
+++ b/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/providers/PapyrusEditActionProvider.java
@@ -0,0 +1,147 @@
+/*****************************************************************************
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Benoit Maggi benoit.maggi@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.onefile.providers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.papyrus.infra.onefile.action.PapyrusModelPasteAction;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchCommandConstants;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.navigator.CommonActionProvider;
+import org.eclipse.ui.navigator.ICommonActionExtensionSite;
+import org.eclipse.ui.navigator.ICommonMenuConstants;
+import org.eclipse.ui.navigator.ICommonViewerWorkbenchSite;
+
+/**
+ * Action provider for paste Papyrus models
+ */
+public class PapyrusEditActionProvider extends CommonActionProvider {
+
+ private boolean fInViewPart = false;
+
+ private ICommonViewerWorkbenchSite workbenchSite;
+
+ private Action pasteAction;
+
+ public PapyrusEditActionProvider() {
+ }
+
+ @Override
+ public void fillActionBars(IActionBars actionBars) {
+ if(fInViewPart) {
+ actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), pasteAction);
+ }
+ super.fillActionBars(actionBars);
+ }
+
+ @Override
+ public void fillContextMenu(IMenuManager menu) {
+ super.fillContextMenu(menu);
+ appendToGroup(menu, pasteAction, ICommonMenuConstants.GROUP_EDIT);
+ }
+
+ private void appendToGroup(IMenuManager menu, IAction action, String id) {
+ if(action != null && action.isEnabled()) {
+ menu.appendToGroup(id, action);
+ }
+ }
+
+ @Override
+ public void init(ICommonActionExtensionSite site) {
+ if(site.getViewSite() instanceof ICommonViewerWorkbenchSite) {
+ workbenchSite = (ICommonViewerWorkbenchSite)site.getViewSite();
+ }
+ if(workbenchSite != null) {
+ if(workbenchSite.getPart() != null && workbenchSite.getPart() instanceof IViewPart) {
+ fInViewPart = true;
+ }
+ makeActions();
+ }
+ }
+
+ private void makeActions() {
+ final IWorkbenchPartSite provider = workbenchSite.getSite();
+
+ Shell shell = provider.getShell();
+ Clipboard clipboard = new Clipboard(shell.getDisplay());
+ pasteAction = new PapyrusModelPasteAction(shell, clipboard) {
+
+ //the helper is filtering Ipapyrus files
+
+ @Override
+ protected List getSelectedResources() {
+ ActionContext context = getContext();
+ List selectedResources = getSelectedResources(context);
+ return selectedResources;
+ }
+
+ protected List getSelectedResources(ActionContext context) {
+ ISelection selec = context.getSelection();
+ List<IResource> resources = new ArrayList<IResource>();
+
+ if(selec instanceof TreeSelection) {
+ TreeSelection tree = (TreeSelection)selec;
+ Object firstElement = tree.getFirstElement();
+ if(firstElement instanceof IResource) {
+ resources.add((IResource)firstElement);
+ }
+ }
+ return resources;
+ }
+ };
+
+ makeAction(pasteAction, IWorkbenchCommandConstants.EDIT_PASTE, ISharedImages.IMG_TOOL_PASTE, ISharedImages.IMG_TOOL_PASTE_DISABLED);
+ }
+
+ /**
+ * Create an action
+ *
+ * @param action
+ * @param id
+ * @param imgTool
+ * @param imgToolDisabled
+ */
+ protected void makeAction(Action action, String id, String imgTool, String imgToolDisabled) {
+ if(action != null) {
+ ISharedImages images = PlatformUI.getWorkbench().getSharedImages();
+ if(id != null) {
+ action.setId(id);
+ action.setActionDefinitionId(id);
+ }
+ if(imgTool != null) {
+ action.setImageDescriptor(images.getImageDescriptor(imgTool));
+ }
+ if(imgToolDisabled != null) {
+ action.setDisabledImageDescriptor(images.getImageDescriptor(imgToolDisabled));
+ }
+ }
+ }
+
+}
diff --git a/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/providers/PapyrusModelActionProvider.java b/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/providers/PapyrusModelActionProvider.java
index 300d395..dcad5bf 100644
--- a/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/providers/PapyrusModelActionProvider.java
+++ b/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/providers/PapyrusModelActionProvider.java
@@ -1,485 +1,479 @@
-/*****************************************************************************
- * Copyright (c) 2011 Atos Origin Integration - 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:
- * Tristan Faure (Atos Origin Integration) tristan.faure@atosorigin.com - Initial API and implementation
- * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr
- *****************************************************************************/
-package org.eclipse.papyrus.infra.onefile.providers;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.jface.action.Action;
-import org.eclipse.jface.action.IAction;
-import org.eclipse.jface.action.IMenuManager;
-import org.eclipse.jface.viewers.ISelection;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.jface.viewers.StructuredSelection;
-import org.eclipse.jface.wizard.IWizardPage;
-import org.eclipse.ltk.core.refactoring.RefactoringStatus;
-import org.eclipse.ltk.internal.core.refactoring.resource.RenameResourceProcessor;
-import org.eclipse.ltk.internal.ui.refactoring.RefactoringUIMessages;
-import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
-import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
-import org.eclipse.ltk.ui.refactoring.resource.RenameResourceWizard;
-import org.eclipse.papyrus.infra.onefile.Activator;
-import org.eclipse.papyrus.infra.onefile.model.IPapyrusFile;
-import org.eclipse.papyrus.infra.onefile.utils.OneFileUtils;
-import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.ModifyEvent;
-import org.eclipse.swt.events.ModifyListener;
-import org.eclipse.swt.layout.GridData;
-import org.eclipse.swt.layout.GridLayout;
-import org.eclipse.swt.widgets.Composite;
-import org.eclipse.swt.widgets.Label;
-import org.eclipse.swt.widgets.Shell;
-import org.eclipse.swt.widgets.Text;
-import org.eclipse.ui.IActionBars;
-import org.eclipse.ui.ISharedImages;
-import org.eclipse.ui.IViewPart;
-import org.eclipse.ui.IWorkbenchCommandConstants;
-import org.eclipse.ui.IWorkbenchPage;
-import org.eclipse.ui.IWorkbenchPartSite;
-import org.eclipse.ui.PlatformUI;
-import org.eclipse.ui.WorkbenchException;
-import org.eclipse.ui.actions.ActionContext;
-import org.eclipse.ui.actions.ActionFactory;
-import org.eclipse.ui.actions.DeleteResourceAction;
-import org.eclipse.ui.actions.MoveResourceAction;
-import org.eclipse.ui.actions.RefreshAction;
-import org.eclipse.ui.actions.RenameResourceAction;
-import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
-import org.eclipse.ui.navigator.CommonActionProvider;
-import org.eclipse.ui.navigator.ICommonActionConstants;
-import org.eclipse.ui.navigator.ICommonActionExtensionSite;
-import org.eclipse.ui.navigator.ICommonMenuConstants;
-import org.eclipse.ui.navigator.ICommonViewerWorkbenchSite;
-import org.eclipse.ui.part.FileEditorInput;
-
-/**
- * Actions available through an {@link IPapyrusFile}
- *
- * @author tfaure
- *
- */
-@SuppressWarnings({ "restriction", "rawtypes" })
-public class PapyrusModelActionProvider extends CommonActionProvider {
-
- private boolean fInViewPart = false;
-
- private ICommonViewerWorkbenchSite workbenchSite;
-
- private Action openAction;
-
- private Action deleteAction;
-
- //Disabled. The CopyResourceAction may create inconsistent changes (i.e. it renames files without editing the links).
- //We need to use a CopyToClipboard action instead
- //@unused
- private Action copyAction;
-
- private Action renameAction;
-
- private Action refreshAction;
-
- private Action moveAction;
-
- public PapyrusModelActionProvider() {
-
- }
-
- @Override
- protected boolean filterAction(IAction action) {
- return super.filterAction(action);
- }
-
- @Override
- public void fillActionBars(IActionBars actionBars) {
- if(fInViewPart) {
- actionBars.setGlobalActionHandler(ICommonActionConstants.OPEN, openAction);
- actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), deleteAction);
- actionBars.setGlobalActionHandler(ActionFactory.RENAME.getId(), renameAction);
- actionBars.setGlobalActionHandler(ActionFactory.MOVE.getId(), moveAction);
- // actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), copyAction);
- actionBars.setGlobalActionHandler(ActionFactory.REFRESH.getId(), refreshAction);
-
- }
- super.fillActionBars(actionBars);
- }
-
- @Override
- public void fillContextMenu(IMenuManager menu) {
- super.fillContextMenu(menu);
- appendToGroup(menu, openAction, ICommonMenuConstants.GROUP_OPEN);
- appendToGroup(menu, deleteAction, ICommonMenuConstants.GROUP_EDIT);
- appendToGroup(menu, moveAction, ICommonMenuConstants.GROUP_EDIT);
- // appendToGroup(menu, copyAction, ICommonMenuConstants.GROUP_EDIT);
- appendToGroup(menu, renameAction, ICommonMenuConstants.GROUP_EDIT);
- appendToGroup(menu, refreshAction, ICommonMenuConstants.GROUP_EDIT);
- }
-
- private void appendToGroup(IMenuManager menu, IAction action, String id) {
- if(action != null && action.isEnabled()) {
- menu.appendToGroup(id, action);
- }
- }
-
- @Override
- public void init(ICommonActionExtensionSite site) {
- if(site.getViewSite() instanceof ICommonViewerWorkbenchSite) {
- workbenchSite = (ICommonViewerWorkbenchSite)site.getViewSite();
- }
- if(workbenchSite != null) {
- if(workbenchSite.getPart() != null && workbenchSite.getPart() instanceof IViewPart) {
- fInViewPart = true;
- }
- makeActions();
- }
- }
-
- private void makeActions() {
- final IWorkbenchPartSite provider = workbenchSite.getSite();
- final ActionHelper helper = new ActionHelper();
- openAction = new Action() {
-
- @Override
- public void run() {
- if(getIFile() != null) {
- try {
- IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
- page.openEditor(new FileEditorInput(getIFile()), "org.eclipse.papyrus.infra.core.papyrusEditor", true, IWorkbenchPage.MATCH_ID | IWorkbenchPage.MATCH_INPUT);
- } catch (WorkbenchException e) {
- Activator.log.error(e);
- }
- }
- }
-
- public IFile getIFile() {
- return helper.getIFile(getContext());
- }
-
- @Override
- public boolean isEnabled() {
- return getIFile() != null;
- }
-
- @Override
- public String getText() {
- return IDEWorkbenchMessages.OpenFileAction_text;
- }
- };
-
- deleteAction = new DeleteResourceAction(provider) {
-
- @Override
- public boolean isEnabled() {
- return getSelectedResources() != null && getSelectedResources().size() > 0 && OneFileUtils.isDi((IResource)getSelectedResources().get(0));
-
- }
-
- @Override
- public IStructuredSelection getStructuredSelection() {
- return helper.getStructuredSelection(getContext());
- }
-
- @Override
- protected List getSelectedResources() {
- return helper.getSelectedResources(getContext());
- }
- };
-
- moveAction = new MoveResourceAction(provider) {
-
- @Override
- public IStructuredSelection getStructuredSelection() {
- return helper.getStructuredSelection(getContext());
- }
-
- @Override
- protected List getSelectedResources() {
- return helper.getSelectedResources(getContext());
- }
- };
-
-
- //FIXME: The CopyResourceAction is actually a copy + paste
- //It fails when the target folder is the same as the source folder (Because it needs to rename the copied files)
- //Replace this action with a Copy to Clipboard action
- // copyAction = new CopyResourceAction(provider) {
- //
- // @Override
- // public IStructuredSelection getStructuredSelection() {
- // return helper.getStructuredSelection(getContext());
- // }
- //
- // @Override
- // protected List getSelectedResources() {
- // return helper.getSelectedResources(getContext());
- // }
- // };
-
- renameAction = new OneFileRenameAction(provider);
-
- refreshAction = new RefreshAction(provider) {
-
- @Override
- public void run() {
- super.run();
- }
-
- };
-
- makeAction(openAction, ICommonActionConstants.OPEN, ISharedImages.IMG_TOOL_COPY, ISharedImages.IMG_TOOL_COPY_DISABLED);
- makeAction(deleteAction, IWorkbenchCommandConstants.EDIT_DELETE, ISharedImages.IMG_TOOL_DELETE, ISharedImages.IMG_TOOL_DELETE_DISABLED);
- makeAction(moveAction, ActionFactory.MOVE.getId(), null, null);
- // makeAction(copyAction, IWorkbenchCommandConstants.EDIT_CUT, ISharedImages.IMG_TOOL_CUT, ISharedImages.IMG_TOOL_CUT_DISABLED);
- // makeAction(copyAction, IWorkbenchCommandConstants.EDIT_COPY, ISharedImages.IMG_TOOL_COPY, ISharedImages.IMG_TOOL_COPY_DISABLED);
- makeAction(refreshAction, ActionFactory.REFRESH.getCommandId(), null, null);
- }
-
- /**
- * A Rename action applying to an IPapyrusFile
- * The action will rename only the *.di file
- * (Refactoring from infra.ui.resources will rename related files and fix URIs)
- *
- * The user won't be asked for a file extension (*.di will be kept)
- *
- * @author Camille Letavernier
- */
- public class OneFileRenameAction extends RenameResourceAction {
-
- final ActionHelper helper = new ActionHelper();
-
- private IWorkbenchPartSite partSiteProvider;
-
- public OneFileRenameAction(IWorkbenchPartSite provider) {
- super(provider);
- this.partSiteProvider = provider;
- }
-
- private Shell getShell() {
- return partSiteProvider.getShell();
- }
-
- @Override
- public void run() {
-
- ISelection selection = partSiteProvider.getSelectionProvider().getSelection();
-
- if(selection instanceof IStructuredSelection) {
- IStructuredSelection structuredSelection = (IStructuredSelection)selection;
- if(structuredSelection.size() != 1) {
- return;
- }
-
- Object selectedElement = structuredSelection.getFirstElement();
- if(selectedElement instanceof IPapyrusFile) {
- IPapyrusFile modelToRename = (IPapyrusFile)selectedElement;
-
- RenamePapyrusModelWizard refactoringWizard = new RenamePapyrusModelWizard(modelToRename);
- RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(refactoringWizard);
- try {
- op.run(getShell(), RefactoringUIMessages.RenameResourceHandler_title);
- } catch (InterruptedException e) {
- // do nothing
- }
- }
- }
- }
- }
-
- private static class RenamePapyrusModelWizard extends RenameResourceWizard {
-
- private IPapyrusFile papyrusFile;
-
- public RenamePapyrusModelWizard(IPapyrusFile papyrusFile) {
- super(papyrusFile.getMainFile());
- this.papyrusFile = papyrusFile;
- }
-
- @Override
- protected void addUserInputPages() {
- RenameResourceProcessor processor = (RenameResourceProcessor)getRefactoring().getAdapter(RenameResourceProcessor.class);
- addPage(new RenamePapyrusModelPage(processor));
- }
-
- private class RenamePapyrusModelPage extends UserInputWizardPage {
-
- private final RenameResourceProcessor fRefactoringProcessor;
-
- private Text fNameField;
-
- public RenamePapyrusModelPage(RenameResourceProcessor processor) {
- super("RenamePapyrusModelRefactoringInputPage"); //$NON-NLS-1$
- fRefactoringProcessor = processor;
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
- */
- public void createControl(Composite parent) {
- Composite composite = new Composite(parent, SWT.NONE);
- composite.setLayout(new GridLayout(2, false));
- composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- composite.setFont(parent.getFont());
-
- Label label = new Label(composite, SWT.NONE);
- label.setText(RefactoringUIMessages.RenameResourceWizard_name_field_label);
- label.setLayoutData(new GridData());
-
- fNameField = new Text(composite, SWT.BORDER);
- fNameField.setText(papyrusFile.getMainFile().getFullPath().removeFileExtension().lastSegment());
- fNameField.setFont(composite.getFont());
- fNameField.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false));
- fNameField.addModifyListener(new ModifyListener() {
-
- public void modifyText(ModifyEvent e) {
- validatePage();
- }
- });
-
- fNameField.selectAll();
- setPageComplete(false);
- setControl(composite);
- }
-
- @Override
- public void setVisible(boolean visible) {
- if(visible) {
- fNameField.setFocus();
- }
- super.setVisible(visible);
- }
-
- protected final void validatePage() {
- String text = fNameField.getText() + ".di";
- RefactoringStatus status = fRefactoringProcessor.validateNewElementName(text);
- setPageComplete(status);
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ltk.ui.refactoring.UserInputWizardPage#performFinish()
- */
- @Override
- protected boolean performFinish() {
- initializeRefactoring();
- storeSettings();
- return super.performFinish();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.ltk.ui.refactoring.UserInputWizardPage#getNextPage()
- */
- @Override
- public IWizardPage getNextPage() {
- initializeRefactoring();
- storeSettings();
- return super.getNextPage();
- }
-
- private void storeSettings() {
- }
-
- private void initializeRefactoring() {
- fRefactoringProcessor.setNewResourceName(fNameField.getText() + ".di");
- }
- }
- }
-
- protected void makeAction(Action action, String id, String imgTool, String imgToolDisabled) {
- if(action != null) {
- ISharedImages images = PlatformUI.getWorkbench().getSharedImages();
- if(id != null) {
- action.setId(id);
- action.setActionDefinitionId(id);
- }
- if(imgTool != null) {
- action.setImageDescriptor(images.getImageDescriptor(imgTool));
- }
- if(imgToolDisabled != null) {
- action.setDisabledImageDescriptor(images.getImageDescriptor(imgToolDisabled));
- }
- }
- }
-
- public static class ActionHelper {
-
- public IStructuredSelection getStructuredSelection(ActionContext context) {
- return new StructuredSelection(getSelectedResources(context));
- }
-
- public List getOneSelectedResources(ActionContext context) {
- List selectedResources = getSelectedResources(context);
- if(selectedResources.size() > 0) {
- for(Iterator<?> i = selectedResources.iterator(); i.hasNext();) {
- Object o = i.next();
- if(o instanceof IFile) {
- IFile file = (IFile)o;
- if(!OneFileUtils.isDi(file)) {
- i.remove();
- }
- }
- }
- return selectedResources;
- }
- return Collections.EMPTY_LIST;
- }
-
- public IStructuredSelection getOneStructuredSelection(ActionContext context) {
- List selectedResources = getOneSelectedResources(context);
- if(selectedResources.size() > 0) {
- return new StructuredSelection(selectedResources);
- }
- return null;
- }
-
- protected List getSelectedResources(ActionContext context) {
- ISelection selec = context.getSelection();
- List<IResource> resources = new ArrayList<IResource>();
- if(selec instanceof IStructuredSelection) {
- IStructuredSelection struc = (IStructuredSelection)selec;
- for(Iterator<Object> i = struc.iterator(); i.hasNext();) {
- Object o = i.next();
- if(o instanceof IPapyrusFile) {
- IPapyrusFile papy = (IPapyrusFile)o;
- resources.addAll(Arrays.asList(papy.getAssociatedResources()));
- }
- }
- }
- return resources;
- }
-
- public IFile getIFile(ActionContext context) {
- ISelection selec = context.getSelection();
- if(selec instanceof IStructuredSelection) {
- IStructuredSelection struc = (IStructuredSelection)selec;
- Object firstElement = struc.getFirstElement();
- if(firstElement instanceof IFile) {
- IFile file = (IFile)firstElement;
- return file;
- } else if(firstElement instanceof IPapyrusFile) {
- return ((IPapyrusFile)firstElement).getMainFile();
- }
- }
- return null;
- }
- }
-
-}
+/*****************************************************************************
+ * Copyright (c) 2011 Atos Origin Integration - 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:
+ * Tristan Faure (Atos Origin Integration) tristan.faure@atosorigin.com - Initial API and implementation
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr
+ * Benoit Maggi (CEA LIST) benoit.maggi@cea.fr - Add copy Action
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.onefile.providers;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.ltk.core.refactoring.RefactoringStatus;
+import org.eclipse.ltk.internal.core.refactoring.resource.RenameResourceProcessor;
+import org.eclipse.ltk.internal.ui.refactoring.RefactoringUIMessages;
+import org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation;
+import org.eclipse.ltk.ui.refactoring.UserInputWizardPage;
+import org.eclipse.ltk.ui.refactoring.resource.RenameResourceWizard;
+import org.eclipse.papyrus.infra.onefile.Activator;
+import org.eclipse.papyrus.infra.onefile.model.IPapyrusFile;
+import org.eclipse.papyrus.infra.onefile.utils.OneFileUtils;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.IViewPart;
+import org.eclipse.ui.IWorkbenchCommandConstants;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.WorkbenchException;
+import org.eclipse.ui.actions.ActionContext;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.actions.DeleteResourceAction;
+import org.eclipse.ui.actions.MoveResourceAction;
+import org.eclipse.ui.actions.RefreshAction;
+import org.eclipse.ui.actions.RenameResourceAction;
+import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
+import org.eclipse.ui.navigator.CommonActionProvider;
+import org.eclipse.ui.navigator.ICommonActionConstants;
+import org.eclipse.ui.navigator.ICommonActionExtensionSite;
+import org.eclipse.ui.navigator.ICommonMenuConstants;
+import org.eclipse.ui.navigator.ICommonViewerWorkbenchSite;
+import org.eclipse.ui.part.FileEditorInput;
+
+/**
+ * Actions available through an {@link IPapyrusFile}
+ *
+ * @author tfaure
+ *
+ */
+@SuppressWarnings({ "restriction", "rawtypes" })
+public class PapyrusModelActionProvider extends CommonActionProvider {
+
+ private boolean fInViewPart = false;
+
+ private ICommonViewerWorkbenchSite workbenchSite;
+
+ private Action openAction;
+
+ private Action deleteAction;
+
+ private Action copyAction;
+
+ private Action renameAction;
+
+ private Action refreshAction;
+
+ private Action moveAction;
+
+ public PapyrusModelActionProvider() {
+
+ }
+
+ @Override
+ protected boolean filterAction(IAction action) {
+ return super.filterAction(action);
+ }
+
+ @Override
+ public void fillActionBars(IActionBars actionBars) {
+ if(fInViewPart) {
+ actionBars.setGlobalActionHandler(ICommonActionConstants.OPEN, openAction);
+ actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), deleteAction);
+ actionBars.setGlobalActionHandler(ActionFactory.RENAME.getId(), renameAction);
+ actionBars.setGlobalActionHandler(ActionFactory.MOVE.getId(), moveAction);
+ actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), copyAction);
+ actionBars.setGlobalActionHandler(ActionFactory.REFRESH.getId(), refreshAction);
+ }
+ super.fillActionBars(actionBars);
+ }
+
+ @Override
+ public void fillContextMenu(IMenuManager menu) {
+ super.fillContextMenu(menu);
+ appendToGroup(menu, openAction, ICommonMenuConstants.GROUP_OPEN);
+ appendToGroup(menu, deleteAction, ICommonMenuConstants.GROUP_EDIT);
+ appendToGroup(menu, moveAction, ICommonMenuConstants.GROUP_EDIT);
+ appendToGroup(menu, copyAction, ICommonMenuConstants.GROUP_EDIT);
+ appendToGroup(menu, renameAction, ICommonMenuConstants.GROUP_EDIT);
+ appendToGroup(menu, refreshAction, ICommonMenuConstants.GROUP_EDIT);
+ }
+
+ private void appendToGroup(IMenuManager menu, IAction action, String id) {
+ if(action != null && action.isEnabled()) {
+ menu.appendToGroup(id, action);
+ }
+ }
+
+ @Override
+ public void init(ICommonActionExtensionSite site) {
+ if(site.getViewSite() instanceof ICommonViewerWorkbenchSite) {
+ workbenchSite = (ICommonViewerWorkbenchSite)site.getViewSite();
+ }
+ if(workbenchSite != null) {
+ if(workbenchSite.getPart() != null && workbenchSite.getPart() instanceof IViewPart) {
+ fInViewPart = true;
+ }
+ makeActions();
+ }
+ }
+
+ private void makeActions() {
+ final IWorkbenchPartSite provider = workbenchSite.getSite();
+ final ActionHelper helper = new ActionHelper();
+ openAction = new Action() {
+
+ @Override
+ public void run() {
+ if(getIFile() != null) {
+ try {
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ page.openEditor(new FileEditorInput(getIFile()), "org.eclipse.papyrus.infra.core.papyrusEditor", true, IWorkbenchPage.MATCH_ID | IWorkbenchPage.MATCH_INPUT);
+ } catch (WorkbenchException e) {
+ Activator.log.error(e);
+ }
+ }
+ }
+
+ public IFile getIFile() {
+ return helper.getIFile(getContext());
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return getIFile() != null;
+ }
+
+ @Override
+ public String getText() {
+ return IDEWorkbenchMessages.OpenFileAction_text;
+ }
+ };
+
+ deleteAction = new DeleteResourceAction(provider) {
+
+ @Override
+ public boolean isEnabled() {
+ return getSelectedResources() != null && getSelectedResources().size() > 0 && OneFileUtils.isDi((IResource)getSelectedResources().get(0));
+
+ }
+
+ @Override
+ public IStructuredSelection getStructuredSelection() {
+ return helper.getStructuredSelection(getContext());
+ }
+
+ @Override
+ protected List getSelectedResources() {
+ return helper.getSelectedResources(getContext());
+ }
+ };
+
+ moveAction = new MoveResourceAction(provider) {
+
+ @Override
+ public IStructuredSelection getStructuredSelection() {
+ return helper.getStructuredSelection(getContext());
+ }
+
+ @Override
+ protected List getSelectedResources() {
+ return helper.getSelectedResources(getContext());
+ }
+ };
+
+ copyAction = new CopyToClipboardAction(provider){
+
+ @Override
+ public IStructuredSelection getStructuredSelection() {
+ return helper.getStructuredSelection(getContext());
+ }
+
+ @Override
+ protected List getSelectedResources() {
+ return helper.getSelectedResources(getContext());
+ }
+
+ };
+
+ renameAction = new OneFileRenameAction(provider);
+
+ refreshAction = new RefreshAction(provider) {
+
+ @Override
+ public void run() {
+ super.run();
+ }
+
+ };
+
+ makeAction(openAction, ICommonActionConstants.OPEN, ISharedImages.IMG_TOOL_COPY, ISharedImages.IMG_TOOL_COPY_DISABLED);
+ makeAction(deleteAction, IWorkbenchCommandConstants.EDIT_DELETE, ISharedImages.IMG_TOOL_DELETE, ISharedImages.IMG_TOOL_DELETE_DISABLED);
+ makeAction(moveAction, ActionFactory.MOVE.getId(), null, null);
+ makeAction(copyAction, IWorkbenchCommandConstants.EDIT_CUT, ISharedImages.IMG_TOOL_CUT, ISharedImages.IMG_TOOL_CUT_DISABLED);
+ makeAction(copyAction, IWorkbenchCommandConstants.EDIT_COPY, ISharedImages.IMG_TOOL_COPY, ISharedImages.IMG_TOOL_COPY_DISABLED);
+ makeAction(refreshAction, ActionFactory.REFRESH.getCommandId(), null, null);
+ }
+
+ /**
+ * A Rename action applying to an IPapyrusFile
+ * The action will rename only the *.di file
+ * (Refactoring from infra.ui.resources will rename related files and fix URIs)
+ *
+ * The user won't be asked for a file extension (*.di will be kept)
+ *
+ * @author Camille Letavernier
+ */
+ public class OneFileRenameAction extends RenameResourceAction {
+
+ final ActionHelper helper = new ActionHelper();
+
+ private IWorkbenchPartSite partSiteProvider;
+
+ public OneFileRenameAction(IWorkbenchPartSite provider) {
+ super(provider);
+ this.partSiteProvider = provider;
+ }
+
+ private Shell getShell() {
+ return partSiteProvider.getShell();
+ }
+
+ @Override
+ public void run() {
+
+ ISelection selection = partSiteProvider.getSelectionProvider().getSelection();
+
+ if(selection instanceof IStructuredSelection) {
+ IStructuredSelection structuredSelection = (IStructuredSelection)selection;
+ if(structuredSelection.size() != 1) {
+ return;
+ }
+
+ Object selectedElement = structuredSelection.getFirstElement();
+ if(selectedElement instanceof IPapyrusFile) {
+ IPapyrusFile modelToRename = (IPapyrusFile)selectedElement;
+
+ RenamePapyrusModelWizard refactoringWizard = new RenamePapyrusModelWizard(modelToRename);
+ RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(refactoringWizard);
+ try {
+ op.run(getShell(), RefactoringUIMessages.RenameResourceHandler_title);
+ } catch (InterruptedException e) {
+ // do nothing
+ }
+ }
+ }
+ }
+ }
+
+ private static class RenamePapyrusModelWizard extends RenameResourceWizard {
+
+ private IPapyrusFile papyrusFile;
+
+ public RenamePapyrusModelWizard(IPapyrusFile papyrusFile) {
+ super(papyrusFile.getMainFile());
+ this.papyrusFile = papyrusFile;
+ }
+
+ @Override
+ protected void addUserInputPages() {
+ RenameResourceProcessor processor = (RenameResourceProcessor)getRefactoring().getAdapter(RenameResourceProcessor.class);
+ addPage(new RenamePapyrusModelPage(processor));
+ }
+
+ private class RenamePapyrusModelPage extends UserInputWizardPage {
+
+ private final RenameResourceProcessor fRefactoringProcessor;
+
+ private Text fNameField;
+
+ public RenamePapyrusModelPage(RenameResourceProcessor processor) {
+ super("RenamePapyrusModelRefactoringInputPage"); //$NON-NLS-1$
+ fRefactoringProcessor = processor;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+ */
+ public void createControl(Composite parent) {
+ Composite composite = new Composite(parent, SWT.NONE);
+ composite.setLayout(new GridLayout(2, false));
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ composite.setFont(parent.getFont());
+
+ Label label = new Label(composite, SWT.NONE);
+ label.setText(RefactoringUIMessages.RenameResourceWizard_name_field_label);
+ label.setLayoutData(new GridData());
+
+ fNameField = new Text(composite, SWT.BORDER);
+ fNameField.setText(papyrusFile.getMainFile().getFullPath().removeFileExtension().lastSegment());
+ fNameField.setFont(composite.getFont());
+ fNameField.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false));
+ fNameField.addModifyListener(new ModifyListener() {
+
+ public void modifyText(ModifyEvent e) {
+ validatePage();
+ }
+ });
+
+ fNameField.selectAll();
+ setPageComplete(false);
+ setControl(composite);
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ if(visible) {
+ fNameField.setFocus();
+ }
+ super.setVisible(visible);
+ }
+
+ protected final void validatePage() {
+ String text = fNameField.getText() + ".di";
+ RefactoringStatus status = fRefactoringProcessor.validateNewElementName(text);
+ setPageComplete(status);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ltk.ui.refactoring.UserInputWizardPage#performFinish()
+ */
+ @Override
+ protected boolean performFinish() {
+ initializeRefactoring();
+ storeSettings();
+ return super.performFinish();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.eclipse.ltk.ui.refactoring.UserInputWizardPage#getNextPage()
+ */
+ @Override
+ public IWizardPage getNextPage() {
+ initializeRefactoring();
+ storeSettings();
+ return super.getNextPage();
+ }
+
+ private void storeSettings() {
+ }
+
+ private void initializeRefactoring() {
+ fRefactoringProcessor.setNewResourceName(fNameField.getText() + ".di");
+ }
+ }
+ }
+
+ protected void makeAction(Action action, String id, String imgTool, String imgToolDisabled) {
+ if(action != null) {
+ ISharedImages images = PlatformUI.getWorkbench().getSharedImages();
+ if(id != null) {
+ action.setId(id);
+ action.setActionDefinitionId(id);
+ }
+ if(imgTool != null) {
+ action.setImageDescriptor(images.getImageDescriptor(imgTool));
+ }
+ if(imgToolDisabled != null) {
+ action.setDisabledImageDescriptor(images.getImageDescriptor(imgToolDisabled));
+ }
+ }
+ }
+
+ public static class ActionHelper {
+
+ public IStructuredSelection getStructuredSelection(ActionContext context) {
+ return new StructuredSelection(getSelectedResources(context));
+ }
+
+ public List getOneSelectedResources(ActionContext context) {
+ List selectedResources = getSelectedResources(context);
+ if(selectedResources.size() > 0) {
+ for(Iterator<?> i = selectedResources.iterator(); i.hasNext();) {
+ Object o = i.next();
+ if(o instanceof IFile) {
+ IFile file = (IFile)o;
+ if(!OneFileUtils.isDi(file)) {
+ i.remove();
+ }
+ }
+ }
+ return selectedResources;
+ }
+ return Collections.EMPTY_LIST;
+ }
+
+ public IStructuredSelection getOneStructuredSelection(ActionContext context) {
+ List selectedResources = getOneSelectedResources(context);
+ if(selectedResources.size() > 0) {
+ return new StructuredSelection(selectedResources);
+ }
+ return null;
+ }
+
+ protected List getSelectedResources(ActionContext context) {
+ ISelection selec = context.getSelection();
+ List<IResource> resources = new ArrayList<IResource>();
+ if(selec instanceof IStructuredSelection) {
+ IStructuredSelection struc = (IStructuredSelection)selec;
+ for(Iterator<Object> i = struc.iterator(); i.hasNext();) {
+ Object o = i.next();
+ if(o instanceof IPapyrusFile) {
+ IPapyrusFile papy = (IPapyrusFile)o;
+ resources.addAll(Arrays.asList(papy.getAssociatedResources()));
+ }
+ }
+ }
+ return resources;
+ }
+
+ public IFile getIFile(ActionContext context) {
+ ISelection selec = context.getSelection();
+ if(selec instanceof IStructuredSelection) {
+ IStructuredSelection struc = (IStructuredSelection)selec;
+ Object firstElement = struc.getFirstElement();
+ if(firstElement instanceof IFile) {
+ IFile file = (IFile)firstElement;
+ return file;
+ } else if(firstElement instanceof IPapyrusFile) {
+ return ((IPapyrusFile)firstElement).getMainFile();
+ }
+ }
+ return null;
+ }
+ }
+
+}
diff --git a/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/testers/PapyrusClipboardTester.java b/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/testers/PapyrusClipboardTester.java
new file mode 100644
index 0000000..fd78671
--- /dev/null
+++ b/plugins/infra/org.eclipse.papyrus.infra.onefile/src/org/eclipse/papyrus/infra/onefile/testers/PapyrusClipboardTester.java
@@ -0,0 +1,77 @@
+/*****************************************************************************
+ * 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 v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Benoit Maggi benoit.maggi@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.infra.onefile.testers;
+
+import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.papyrus.infra.core.resource.sasheditor.DiModel;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.part.ResourceTransfer;
+
+/**
+ * Papyrus tester on clipboard contents
+ * containsPapyrusModel : test if there is a papyrus model
+ */
+public class PapyrusClipboardTester extends PropertyTester {
+
+ public static final String CLIPBOARD_CONTAINS_PAPYRUS_MODEL = "containsPapyrusModel"; //$NON-NLS-1$
+
+ public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
+ if(receiver instanceof org.eclipse.swt.widgets.Shell) {
+ Clipboard clipboard = new Clipboard(Display.getDefault());
+ if(CLIPBOARD_CONTAINS_PAPYRUS_MODEL.equals(property)) {
+ boolean answer = containsPapyrusModel(clipboard);
+ return new Boolean(answer).equals(expectedValue);
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ * Test if the clipboard contains some Papyrus model (that is with a di extension)
+ * @param clipboard
+ * @return
+ */
+ protected boolean containsPapyrusModel(Clipboard clipboard) {
+ if (clipboard != null) {
+ String[] filePaths =(String[]) clipboard.getContents(FileTransfer.getInstance());
+ if (filePaths != null){
+ if (filePaths.length >0 ) {
+ for(int i = 0; i < filePaths.length; i++) {
+ if (filePaths[i].endsWith("."+DiModel.MODEL_FILE_EXTENSION)){ //$NON-NLS-1$
+ return true;
+ }
+ }
+ }
+ } else {
+ IResource[] resources = (IResource[]) clipboard.getContents(ResourceTransfer.getInstance());
+ if (resources != null){
+ if (resources.length >0 ) {
+ for(int i = 0; i < resources.length; i++) {
+ if (DiModel.MODEL_FILE_EXTENSION.equals(resources[i].getFileExtension())){
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+}