package org.jactr.eclipse.ui.commands;
/*
* default logging
*/
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.MultiRule;
import org.jactr.eclipse.ui.UIPlugin;
public class ArchiveAndDeleteJob extends WorkspaceJob
{
/**
* Logger definition
*/
static private final transient Log LOGGER = LogFactory
.getLog(ArchiveAndDeleteJob.class);
static private final int WORK_UNITS = 1000;
final private boolean _deleteWhenDone;
final private IFolder _root;
final private IFile _archive;
public ArchiveAndDeleteJob(IFolder folder, boolean delete)
{
super("Archiving " + folder.getName());
_root = folder;
_deleteWhenDone = delete;
_archive = _root.getParent().getFile(new Path(_root.getName() + ".zip"));
ISchedulingRule refreshRule = ResourcesPlugin.getWorkspace()
.getRuleFactory().refreshRule(_root.getParent());
ISchedulingRule archiveRule = ResourcesPlugin.getWorkspace()
.getRuleFactory().createRule(_archive);
ISchedulingRule rule = null;
if (_deleteWhenDone)
rule = MultiRule.combine(new ISchedulingRule[] { archiveRule,
ResourcesPlugin.getWorkspace().getRuleFactory().deleteRule(_root),
refreshRule });
else
rule = MultiRule.combine(archiveRule, refreshRule);
setRule(rule);
}
@Override
public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException
{
monitor.beginTask("Archiving " + _root.getName(), WORK_UNITS + 1);
Collection<IResource> resources = getResources(_root, monitor);
IStatus returnStatus = Status.OK_STATUS;
int lastTotal = 0;
int currentTotal = 0;
try
{
IPath strip = _root.getFullPath().removeLastSegments(1);
ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(
new FileOutputStream(_archive.getLocation().toFile())));
byte[] block = new byte[4096];
float count = 0;
for (IResource resource : resources)
{
IPath path = resource.getFullPath();
// strip prefix
if (strip.isPrefixOf(path))
path = path.removeFirstSegments(strip.segmentCount());
String name = path.toString();
if (name.startsWith("/")) name = name.substring(1, name.length());
if (resource instanceof IContainer) name += "/"; // make sure folders
monitor.setTaskName("Archiving " + name);
ZipEntry entry = new ZipEntry(name);
zos.putNextEntry(entry);
if (resource instanceof IFile)
{
IFile file = (IFile) resource;
InputStream is = file.getContents(true);
int read = 0;
int written = 0;
while ((read = is.read(block)) > 0)
{
zos.write(block, 0, read);
written += read;
}
is.close();
if (LOGGER.isDebugEnabled()) LOGGER.debug(written + " bytes ");
}
zos.closeEntry();
count++;
currentTotal = (int) (WORK_UNITS * count / resources.size());
if (currentTotal > lastTotal)
{
monitor.worked(currentTotal - lastTotal);
lastTotal = currentTotal;
}
}
zos.close();
return returnStatus;
}
catch (IOException ioe)
{
if (_archive.exists()) _archive.delete(true, monitor);
return new Status(IStatus.ERROR, UIPlugin.ID, "Failed to archive "
+ _root.getName(), ioe);
}
finally
{
if (returnStatus.isOK() && _deleteWhenDone) delete(monitor);
_root.getParent().refreshLocal(IResource.DEPTH_INFINITE, monitor);
monitor.done();
}
}
private Collection<IResource> getResources(IFolder root,
IProgressMonitor monitor) throws CoreException
{
ArrayList<IResource> resources = new ArrayList<IResource>();
monitor = new SubProgressMonitor(monitor, 1);
monitor.beginTask("Scanning for children of " + root.getName(), 1);
try
{
getResources(root, resources);
return resources;
}
finally
{
monitor.done();
}
}
private void getResources(IContainer root, Collection<IResource> resources)
throws CoreException
{
resources.add(root);
for (IResource resource : root.members(false))
if (resource.isAccessible()) if (resource instanceof IContainer)
getResources((IContainer) resource, resources);
else
resources.add(resource);
}
private void delete(IProgressMonitor monitor) throws CoreException
{
_root.delete(true, monitor);
}
}