// 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() );
}
}