Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'target_explorer/plugins/org.eclipse.tcf.te.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/operations/OpDelete.java')
-rw-r--r--target_explorer/plugins/org.eclipse.tcf.te.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/operations/OpDelete.java232
1 files changed, 232 insertions, 0 deletions
diff --git a/target_explorer/plugins/org.eclipse.tcf.te.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/operations/OpDelete.java b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/operations/OpDelete.java
new file mode 100644
index 000000000..5dea3e520
--- /dev/null
+++ b/target_explorer/plugins/org.eclipse.tcf.te.filesystem.core/src/org/eclipse/tcf/te/tcf/filesystem/core/internal/operations/OpDelete.java
@@ -0,0 +1,232 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 Wind River Systems, Inc. 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:
+ * Wind River Systems - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.tcf.te.tcf.filesystem.core.internal.operations;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tcf.protocol.IChannel;
+import org.eclipse.tcf.services.IFileSystem;
+import org.eclipse.tcf.te.tcf.core.Tcf;
+import org.eclipse.tcf.te.tcf.filesystem.core.interfaces.IConfirmCallback;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.exceptions.TCFException;
+import org.eclipse.tcf.te.tcf.filesystem.core.internal.exceptions.TCFFileSystemException;
+import org.eclipse.tcf.te.tcf.filesystem.core.model.FSTreeNode;
+import org.eclipse.tcf.te.tcf.filesystem.core.nls.Messages;
+
+/**
+ * FSDelete deletes the selected FSTreeNode list.
+ */
+public class OpDelete extends Operation {
+ private static final int RETRY_TIMES = 3;
+ //The nodes to be deleted.
+ List<FSTreeNode> nodes;
+ //The callback invoked to confirm deleting read-only files.
+ IConfirmCallback confirmCallback;
+
+ /**
+ * Create a delete operation using the specified nodes.
+ *
+ * @param nodes The nodes to be deleted.
+ */
+ public OpDelete(List<FSTreeNode> nodes, IConfirmCallback confirmCallback) {
+ this.nodes = getAncestors(nodes);
+ this.confirmCallback = confirmCallback;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.core.internal.operations.Operation#run(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+ super.run(monitor);
+ FSTreeNode head = nodes.get(0);
+ IChannel channel = null;
+ try {
+ channel = openChannel(head.peerNode.getPeer());
+ if (channel != null) {
+ IFileSystem service = getBlockingFileSystem(channel);
+ if (service != null) {
+ for (FSTreeNode node : nodes) {
+ remove(node, service);
+ }
+ }
+ else {
+ String message = NLS.bind(Messages.Operation_NoFileSystemError, head.peerNode.getPeerId());
+ throw new TCFFileSystemException(IStatus.ERROR, message);
+ }
+ }
+ }
+ catch (TCFException e) {
+ throw new InvocationTargetException(e, e.getMessage());
+ }
+ finally {
+ if (channel != null) Tcf.getChannelManager().closeChannel(channel);
+ monitor.done();
+ }
+ }
+
+ /**
+ * Delete the file/folder node using the file system service.
+ *
+ * @param monitor The monitor to report the progress.
+ * @param node The file/folder node to be deleted.
+ * @param service The file system service.
+ * @throws TCFFileSystemException The exception thrown during deleting.
+ * @throws InterruptedException Thrown when the operation is canceled.
+ */
+ void remove(FSTreeNode node, IFileSystem service) throws TCFFileSystemException, InterruptedException {
+ if (node.isFile()) {
+ removeFile(node, service);
+ }
+ else if (node.isDirectory()) {
+ removeFolder(node, service);
+ }
+ }
+
+ /**
+ * Delete the folder node and its children using the file system service.
+ *
+ * @param monitor The monitor to report the progress.
+ * @param node The folder node to be deleted.
+ * @param service The file system service.
+ * @throws TCFFileSystemException The exception thrown during deleting.
+ * @throws InterruptedException Thrown when the operation is canceled.
+ */
+ @Override
+ protected void removeFolder(final FSTreeNode node, IFileSystem service) throws TCFFileSystemException, InterruptedException {
+ List<FSTreeNode> children = getChildren(node, service);
+ if (!children.isEmpty()) {
+ for (FSTreeNode child : children) {
+ // Delete each child node.
+ remove(child, service);
+ }
+ }
+ monitor.subTask(NLS.bind(Messages.OpDelete_RemovingFileFolder, node.name));
+ super.removeFolder(node, service);
+ monitor.worked(1);
+ }
+
+ /**
+ * Delete the file node using the file system service.
+ *
+ * @param node The file node to be deleted.
+ * @param service The file system service.
+ * @throws TCFFileSystemException The exception thrown during deleting.
+ * @throws InterruptedException Thrown when the operation is canceled.
+ */
+ protected void removeFile(final FSTreeNode node, IFileSystem service) throws TCFFileSystemException, InterruptedException {
+ if (monitor.isCanceled()) throw new InterruptedException();
+ monitor.subTask(NLS.bind(Messages.OpDelete_RemovingFileFolder, node.name));
+ // If the file is read only on windows or not writable on unix, then make it deletable.
+ if (confirmCallback != null && confirmCallback.requires(node)) {
+ if (!yes2All) {
+ int result = confirmCallback.confirms(node);
+ if (result == 1) {
+ yes2All = true;
+ }
+ else if (result == 2) {
+ monitor.worked(1);
+ return;
+ }
+ else if (result == 3) {
+ // Cancel the whole operation
+ monitor.setCanceled(true);
+ throw new InterruptedException();
+ }
+ }
+ IStatus status = mkWritable(node);
+ if (!status.isOK()) return;
+ }
+ super.removeFile(node, service);
+ monitor.worked(1);
+ }
+
+ /**
+ * Make the file/folder writable by changing its properties.
+ * It will try several times before return.
+ *
+ * @param node the file/folder node.
+ */
+ private IStatus mkWritable(FSTreeNode node) {
+ final FSTreeNode clone = (FSTreeNode) node.clone();
+ if (node.isWindowsNode()) {
+ clone.setReadOnly(false);
+ }
+ else {
+ clone.setWritable(true);
+ }
+ // Make the file writable.
+ OpCommitAttr op = new OpCommitAttr(node, clone.attr);
+ IOpExecutor executor = new NullOpExecutor();
+ IStatus status = null;
+ for (int i = 0; i < RETRY_TIMES; i++) {
+ status = executor.execute(op);
+ if (status.isOK()) return status;
+ }
+ return status;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.core.interfaces.IOperation#getName()
+ */
+ @Override
+ public String getName() {
+ return Messages.OpDelete_Deleting;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.tcf.te.tcf.filesystem.core.interfaces.IOperation#getTotalWork()
+ */
+ @Override
+ public int getTotalWork() {
+ if(nodes != null && !nodes.isEmpty()) {
+ final AtomicReference<Integer> ref = new AtomicReference<Integer>();
+ SafeRunner.run(new ISafeRunnable(){
+ @Override
+ public void handleException(Throwable exception) {
+ // Ignore on purpose.
+ }
+ @Override
+ public void run() throws Exception {
+ FSTreeNode head = nodes.get(0);
+ IChannel channel = null;
+ try {
+ channel = openChannel(head.peerNode.getPeer());
+ if (channel != null) {
+ IFileSystem service = getBlockingFileSystem(channel);
+ if (service != null) {
+ ref.set(Integer.valueOf(count(service, nodes)));
+ }
+ else {
+ String message = NLS.bind(Messages.Operation_NoFileSystemError, head.peerNode.getPeerId());
+ throw new TCFFileSystemException(IStatus.ERROR, message);
+ }
+ }
+ }
+ finally {
+ if (channel != null) Tcf.getChannelManager().closeChannel(channel);
+ }
+ }});
+ Integer value = ref.get();
+ return value == null ? IProgressMonitor.UNKNOWN : value.intValue();
+ }
+ return IProgressMonitor.UNKNOWN;
+ }
+}

Back to the top