// Copyright (c) 2003-2008 by Leif Frenzel - see http://leiffrenzel.de // This code is made available under the terms of the Eclipse Public License, // version 1.0 (EPL). See http://www.eclipse.org/legal/epl-v10.html package net.sf.eclipsefp.haskell.ui.internal.wizards; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.zip.GZIPInputStream; import net.sf.eclipsefp.haskell.core.util.ResourceUtil; import net.sf.eclipsefp.haskell.ui.HaskellUIPlugin; import org.apache.tools.tar.TarEntry; import org.apache.tools.tar.TarInputStream; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; /** <p>extract contents of a tar.gz archive to a workspace project.</p> * * @author Leif Frenzel */ class Extractor { private static final int BUFFER = 2048; static void extract( final File source, final IProject dest ) throws CoreException { try { extract( new FileInputStream( source ), dest ); } catch( final IOException ioex ) { String pluginId = HaskellUIPlugin.getPluginId(); String msg = ioex.getMessage() == null ? "No message" : ioex.getMessage(); IStatus status = new Status( IStatus.ERROR, pluginId, 0, msg, ioex ); throw new CoreException( status ); } } // helping functions //////////////////// private static void extract( final InputStream stream, final IProject dest ) throws IOException, CoreException { try (TarInputStream tis = new TarInputStream( new GZIPInputStream( stream ) )) { TarEntry entry = tis.getNextEntry(); while( entry != null ) { if( !entry.isDirectory() ) { IPath entryPath = new Path( entry.getName() ); if( entryPath.segmentCount() > 0 ) { // strip the first segment, it's the package name entryPath = entryPath.removeFirstSegments( 1 ); } write( entryPath, dest, readPartially( tis ) ); } entry = tis.getNextEntry(); } } } private static void write( final IPath path, final IProject project, final InputStream is ) throws CoreException { if( path.segmentCount() > 1 ) { ResourceUtil.mkdirs( path.removeLastSegments( 1 ), project ); } IFile file = project.getFile( path ); if( file.exists() ) { file.setContents( is, true, false, new NullProgressMonitor() ); } else { file.create( is, true, new NullProgressMonitor() ); } } public static InputStream readPartially( final InputStream is ) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] data = new byte[ BUFFER ]; int currentByte = is.read( data, 0, BUFFER ); while( currentByte != -1 ) { baos.write( data, 0, currentByte ); currentByte = is.read( data, 0, BUFFER ); } return new ByteArrayInputStream( baos.toByteArray() ); } }