Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Chen2012-02-27 03:36:52 -0500
committerWilliam Chen2012-02-27 03:37:40 -0500
commit873578be96dd9bdf53bb53df4aafb0a6921b4b7c (patch)
tree195d268bfe5f8ae03538951166c3f6e2d36310b2
parent39b347cdbd94cd71dec594d8050977a894aaab1e (diff)
downloadorg.eclipse.tcf-873578be96dd9bdf53bb53df4aafb0a6921b4b7c.tar.gz
org.eclipse.tcf-873578be96dd9bdf53bb53df4aafb0a6921b4b7c.tar.xz
org.eclipse.tcf-873578be96dd9bdf53bb53df4aafb0a6921b4b7c.zip
Target Explorer: [372622] Dragging directories from external programs
to File System does not work!
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSUpload.java158
1 files changed, 142 insertions, 16 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSUpload.java b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSUpload.java
index 9dcd18b4b..bb15b5a80 100644
--- a/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSUpload.java
+++ b/target_explorer/plugins/org.eclipse.tcf.te.tcf.filesystem/src/org/eclipse/tcf/te/tcf/filesystem/internal/operations/FSUpload.java
@@ -14,10 +14,16 @@ import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.util.SafeRunnable;
@@ -45,7 +51,7 @@ public class FSUpload extends FSUIOperation implements IConfirmCallback {
// The callback invoked after uploading.
ICallback callback;
// The current children
- List<FSTreeNode> targetChildren;
+ Map<File, FSTreeNode> parentFolders;
/**
* Create an instance with specified files, target folder and a callback.
@@ -60,11 +66,7 @@ public class FSUpload extends FSUIOperation implements IConfirmCallback {
System.arraycopy(sourceFiles, 0, this.sourceFiles, 0, sourceFiles.length);
this.targetFolder = targetFolder;
this.callback = callback;
- SafeRunner.run(new SafeRunnable(){
- @Override
- public void run() throws Exception {
- targetChildren = getChildren(targetFolder);
- }});
+ parentFolders = Collections.synchronizedMap(new HashMap<File, FSTreeNode>());
}
/*
@@ -80,13 +82,11 @@ public class FSUpload extends FSUIOperation implements IConfirmCallback {
else
message = NLS.bind(Messages.CacheManager_UploadNFiles, Long.valueOf(sourceFiles.length));
monitor.beginTask(message, 100);
- File[] files = new File[sourceFiles.length];
- URL[] urls = new URL[sourceFiles.length];
- URL folderURL = targetFolder.getLocationURL();
- for (int i=0;i<files.length;i++) {
- files[i] = new File(sourceFiles[i]);
- urls[i] = new URL(folderURL, files[i].getName());
- }
+ List<File> fileList = new ArrayList<File>();
+ List<URL> urlList = new ArrayList<URL>();
+ prepareDirStruct(fileList, urlList);
+ File[] files = fileList.toArray(new File[fileList.size()]);
+ URL[] urls = urlList.toArray(new URL[urlList.size()]);
CacheManager.getInstance().uploadFiles(monitor, files, urls, this);
} catch (MalformedURLException e) {
throw new InvocationTargetException(e);
@@ -97,6 +97,115 @@ public class FSUpload extends FSUIOperation implements IConfirmCallback {
}
}
+ /**
+ * Prepare the directory structure on the remote target, creating necessary intermediate directories
+ * and found all files that should be uploaded. The resulting files to be uploaded should be stored
+ * to the file list. The resulting corresponding target file URLs should be stored in the url list.
+ *
+ * @param fileList The file list to store the files that should be uploaded.
+ * @param urlList The list containing the corresponding urls.
+ */
+ private void prepareDirStruct(List<File> fileList, List<URL> urlList) {
+ List<File> files = new ArrayList<File>();
+ for(String path: sourceFiles) {
+ files.add(new File(path));
+ }
+ // Find the root nodes of these files.
+ List<File> topFiles = getTopFiles(files);
+ for(File topFile : topFiles) {
+ appendFile(topFile, fileList, urlList, targetFolder);
+ }
+ }
+
+ /**
+ * Append the specified file object to the file list and url list. If the file object is a file
+ * then append it to the two lists. If the file object is a directory, then recursively
+ * add its children and grand children to the two list. During this process, the parents of
+ * these files and directories traversed should be put into the parent folders map so that
+ * it could be queried to check if it has a file/directory with a same name.
+ *
+ * @param file The file to be added
+ * @param fileList The file list
+ * @param urlList The url list
+ * @param parent The current parent node
+ */
+ private void appendFile(final File file, final List<File> fileList, final List<URL> urlList, final FSTreeNode parent) {
+ parentFolders.put(file, parent);
+ if(file.isFile()) {
+ SafeRunner.run(new SafeRunnable(){
+ @Override
+ public void run() throws Exception {
+ URL folderURL = parent.getLocationURL();
+ URL url = new URL(folderURL, file.getName());
+ fileList.add(file);
+ urlList.add(url);
+ }});
+ } else if(file.isDirectory()) {
+ FSTreeNode node = findNode(file);
+ if(node == null) {
+ final AtomicReference<FSTreeNode> reference = new AtomicReference<FSTreeNode>();
+ SafeRunner.run(new SafeRunnable(){
+ @Override
+ public void run() throws Exception {
+ FSCreateFolder create = new FSCreateFolder(parent, file.getName());
+ create.run(new NullProgressMonitor());
+ reference.set(create.getNode());
+ }});
+ node = reference.get();
+ }
+ File[] children = file.listFiles();
+ for(File child : children) {
+ appendFile(child, fileList, urlList, node);
+ }
+ }
+ }
+
+ /**
+ * Get the root files of the specified files/folders in the list.
+ *
+ * @param files The files to be checked.
+ * @return Root nodes of these files that has no parent.
+ */
+ private List<File> getTopFiles(List<File>files) {
+ List<File> result = new ArrayList<File>();
+ for(File file : files) {
+ if(!hasFileAncestor(file, files)) {
+ result.add(file);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Check if the target file has an ancestral parent in the specified list.
+ *
+ * @param target The target file to be checked.
+ * @param files The file list to be searched.
+ * @return true if it has an ancestral parent.
+ */
+ private boolean hasFileAncestor(File target, List<File> files) {
+ for(File file : files) {
+ if(isFileAncestor(file, target)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check if the specified "file" is an ancestral parent of the "target" file.
+ *
+ * @param file The ancestral file.
+ * @param target The target file.
+ * @return true if "file" is an ancestral parent of "target"
+ */
+ private boolean isFileAncestor(File file, File target) {
+ if(target == null) return false;
+ File parent = target.getParentFile();
+ if(file.equals(parent)) return true;
+ return isFileAncestor(file, parent);
+ }
+
/*
* (non-Javadoc)
* @see org.eclipse.tcf.te.tcf.filesystem.internal.operations.FSUIOperation#doit()
@@ -116,13 +225,30 @@ public class FSUpload extends FSUIOperation implements IConfirmCallback {
*/
@Override
public boolean requires(Object object) {
- File file = (File) object;
+ return findNode((File) object) != null;
+ }
+
+ /**
+ * Check if the specified file has a same-named file under its corresponding
+ * parent folder.
+ *
+ * @param file The file to checked.
+ * @return the node that has the same name with the file.
+ */
+ private FSTreeNode findNode(File file) {
+ final FSTreeNode parent = parentFolders.get(file);
+ final List<FSTreeNode> targetChildren = new ArrayList<FSTreeNode>();
+ SafeRunner.run(new SafeRunnable(){
+ @Override
+ public void run() throws Exception {
+ targetChildren.addAll(getChildren(parent));
+ }});
String name = file.getName();
for(FSTreeNode child:targetChildren) {
if(name.equals(child.name))
- return true;
+ return child;
}
- return false;
+ return null;
}
/*

Back to the top