package org.eclipse.buckminster.ant.materializer; import java.io.File; import java.io.FileFilter; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.tools.tar.TarEntry; import org.apache.tools.tar.TarInputStream; import org.eclipse.buckminster.ant.Messages; import org.eclipse.buckminster.core.helpers.AbstractExtension; import org.eclipse.buckminster.core.helpers.NullOutputStream; import org.eclipse.buckminster.download.IExpander; import org.eclipse.buckminster.runtime.BuckminsterException; import org.eclipse.buckminster.runtime.IOUtils; import org.eclipse.buckminster.runtime.MonitorUtils; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.osgi.util.NLS; /** * @author Thomas Hallgren * @author Guillaume CHATELET */ public class TarExpander extends AbstractExtension implements IExpander { private FileFilter filter; private boolean flatten = false; @Override public void expand(InputStream inputs, File destinationFolder, IProgressMonitor monitor) throws CoreException { TarEntry entry; TarInputStream input = null; int ticksLeft = 600; MonitorUtils.begin(monitor, ticksLeft); if (destinationFolder != null) { if (!(destinationFolder.isDirectory() || destinationFolder.mkdirs())) throw BuckminsterException.fromMessage(NLS.bind(Messages.TarExpander_unable_to_unzip_into_directory_0, destinationFolder)); MonitorUtils.worked(monitor, 10); ticksLeft -= 10; } try { input = new TarInputStream(inputs); while ((entry = input.getNextEntry()) != null) { if (entry.isDirectory() && flatten) continue; String name = getName(entry); if (entry.isDirectory()) { if (destinationFolder == null) continue; File subDir = new File(destinationFolder, name); if (!(subDir.isDirectory() || subDir.mkdirs())) throw BuckminsterException.fromMessage(NLS.bind(Messages.TarExpander_unable_to_unzip_into_directory_0, destinationFolder)); if (ticksLeft >= 10) { MonitorUtils.worked(monitor, 10); ticksLeft -= 10; } continue; } OutputStream output = null; try { if (destinationFolder == null) output = NullOutputStream.INSTANCE; else { // TarEntry can contain e.g. // "exo-enterprise-webos-r20927-tomcat\webapps\ROOT\build.xml" // - // folders need to be created File subDir = new File(destinationFolder, name).getParentFile(); if (subDir != null && !(subDir.isDirectory() || subDir.mkdirs())) throw BuckminsterException .fromMessage(NLS.bind(Messages.TarExpander_unable_to_unzip_into_directory_0, destinationFolder)); if (filter == null || filter.accept(new File(entry.getName()))) output = new FileOutputStream(new File(destinationFolder, name)); else output = NullOutputStream.INSTANCE; } IProgressMonitor subMon = null; if (ticksLeft >= 20) { subMon = MonitorUtils.subMonitor(monitor, 10); ticksLeft -= 10; } IOUtils.copy(input, output, subMon); } finally { IOUtils.close(output); } } if (ticksLeft > 0) MonitorUtils.worked(monitor, ticksLeft); } catch (IOException e) { throw BuckminsterException.wrap(e); } finally { MonitorUtils.done(monitor); } } @Override public void setFilter(FileFilter filter) { this.filter = filter; } @Override public void setFlattenHierarchy(boolean shouldFlatten) { flatten = shouldFlatten; } private String getName(TarEntry entry) { final String name = entry.getName(); return flatten ? new File(name).getName() : name; } }