/*******************************************************************************
* Copyright (c) 2011, 2015 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 static java.text.MessageFormat.format;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.osgi.util.NLS;
import org.eclipse.tcf.te.tcf.filesystem.core.interfaces.IConfirmCallback;
import org.eclipse.tcf.te.tcf.filesystem.core.interfaces.runtime.IFSTreeNode;
import org.eclipse.tcf.te.tcf.filesystem.core.internal.FSTreeNode;
import org.eclipse.tcf.te.tcf.filesystem.core.internal.utils.StatusHelper;
import org.eclipse.tcf.te.tcf.filesystem.core.nls.Messages;
/**
* The operation class that copies selected FSTreeNodes to a specify destination folder.
*/
public class OpCopyLocal extends OpCopyBase<File> {
private static final boolean IGNORE_CASE = new File("a").equals(new File("A")); //$NON-NLS-1$ //$NON-NLS-2$
private static final File[] NO_FILES = {};
private final Map<File, File[]> fChildrenCache = new HashMap<File, File[]>();
public OpCopyLocal(List<? extends IFSTreeNode> nodes, File dest, IConfirmCallback confirmCallback) {
super(nodes, dest, confirmCallback);
}
@Override
protected File findChild(File destination, String name) {
for (File child : getChildren(destination)) {
String childName = child.getName();
if (IGNORE_CASE ? childName.equalsIgnoreCase(name) : childName.equals(name))
return child;
}
return null;
}
private File[] getChildren(File destination) {
File[] result = fChildrenCache.get(destination);
if (result == null) {
result = destination.listFiles();
if (result == null)
result = NO_FILES;
fChildrenCache.put(destination, result);
}
return result;
}
@Override
protected void notifyChange(File destination) {
}
@Override
protected IStatus refreshDestination(File destination, long startTime, IProgressMonitor monitor) {
return Status.OK_STATUS;
}
@Override
protected boolean isDirectory(File node) {
return node.isDirectory();
}
@Override
protected boolean isFile(File node) {
return node.isFile();
}
@Override
protected String getLocation(File node) {
return node.getAbsolutePath();
}
@Override
protected IStatus performCopy(final FSTreeNode source, final File destination, final String newName, final File existing, IProgressMonitor monitor) {
monitor.subTask(NLS.bind(Messages.OpCopy_Copying, source.getLocation()));
if (monitor.isCanceled())
return Status.CANCEL_STATUS;
if (source.isFile()) {
return copyFile(source, destination, newName, new SubProgressMonitor(monitor, 0));
}
if (source.isDirectory()) {
return copyFolder(source, destination, newName);
}
return Status.OK_STATUS;
}
private IStatus copyFolder(final FSTreeNode source, final File dest, final String newName) {
File newFolder = new File(dest, newName);
if (!newFolder.mkdir())
return StatusHelper.createStatus(format(Messages.Operation_CannotCreateDirectory, newName), null);
fChildrenCache.remove(dest);
addWorkItem(source.getChildren(), newFolder);
return Status.OK_STATUS;
}
private IStatus copyFile(final FSTreeNode source, final File dest, final String newName, IProgressMonitor monitor) {
File fileDest = new File(dest, newName);
fChildrenCache.remove(dest);
OutputStream output;
try {
output = new BufferedOutputStream(new FileOutputStream(fileDest));
} catch (FileNotFoundException e) {
return StatusHelper.createStatus(format(Messages.OpCopy_CannotCopyFile, newName), e);
}
IStatus result = source.operationDownload(output).run(monitor);
try {
output.close();
} catch (IOException e) {
}
return result;
}
@Override
public String getName() {
return Messages.OpCopy_CopyingFile;
}
}