package com.aptana.ide.syncing.core.internal;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.MessageFormat;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import com.aptana.ide.core.io.vfs.IExtendedFileStore;
import com.aptana.ide.syncing.core.SyncingPlugin;
/**
* @author Max Stepanov
*
*/
public final class SyncUtils {
/**
*
*/
private SyncUtils() {
}
public static void copy(IFileStore source, IFileInfo sourceInfo, IFileStore destination, int options, IProgressMonitor monitor) throws CoreException {
try {
monitor = (monitor == null) ? new NullProgressMonitor() : monitor;
checkCanceled(monitor);
monitor.beginTask("", sourceInfo == null ? 3 : 2);
if (sourceInfo == null) {
sourceInfo = source.fetchInfo(IExtendedFileStore.DETAILED, subMonitorFor(monitor, 1));
}
checkCanceled(monitor);
if (sourceInfo.isDirectory()) {
destination.mkdir(EFS.NONE, subMonitorFor(monitor, 2));
} else {
final byte[] buffer = new byte[8192];
long length = sourceInfo.getLength();
int totalWork = (length == -1) ? IProgressMonitor.UNKNOWN : 1 + (int) (length / buffer.length);
InputStream in = null;
OutputStream out = null;
try {
in = source.openInputStream(EFS.NONE, subMonitorFor(monitor, 0));
out = destination.openOutputStream(EFS.NONE, subMonitorFor(monitor, 0));
IProgressMonitor subMonitor = subMonitorFor(monitor, 2);
subMonitor.beginTask(MessageFormat.format("Copying {0}", source.toString()), totalWork);
while (true) {
int bytesRead = -1;
try {
bytesRead = in.read(buffer);
} catch (IOException e) {
error(MessageFormat.format("Failed reading {0}", source.toString()), e);
}
if (bytesRead == -1)
break;
try {
out.write(buffer, 0, bytesRead);
} catch (IOException e) {
error(MessageFormat.format("Failed writing to {0}", destination.toString()), e);
}
subMonitor.worked(1);
}
subMonitor.done();
} finally {
safeClose(in);
safeClose(out);
}
}
destination.putInfo(sourceInfo, EFS.SET_ATTRIBUTES | EFS.SET_LAST_MODIFIED | options, subMonitorFor(monitor, 1));
} finally {
monitor.done();
}
}
private static IProgressMonitor subMonitorFor(IProgressMonitor monitor, int ticks) {
if (monitor == null) {
return new NullProgressMonitor();
}
if (monitor instanceof NullProgressMonitor) {
return monitor;
}
return new SubProgressMonitor(monitor, ticks);
}
private static void checkCanceled(IProgressMonitor monitor) {
if (monitor.isCanceled())
throw new OperationCanceledException();
}
private static void error(String message, Exception e) throws CoreException {
throw new CoreException(new Status(IStatus.ERROR, SyncingPlugin.PLUGIN_ID, message, e));
}
private static void safeClose(InputStream in) {
try {
if (in != null) {
in.close();
}
} catch (IOException ignore) {
}
}
private static void safeClose(OutputStream out) {
try {
if (out != null) {
out.close();
}
} catch (IOException ignore) {
}
}
}