blob: be0064624eb7dd98a9000ed08442d02ffe3c7d18 [file] [log] [blame]
/******************************************************************************
* Copyright (c) David Orme and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* David Orme - initial API and implementation
******************************************************************************/
package org.eclipse.e4.ui.test.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* UnZip -- print or unzip a JAR or PKZIP file using java.util.zip.<p>
* Command-line version: extracts files.<p>
* @author Ian Darwin, Ian@DarwinSys.com<p>
* $Id: UnZip.java,v 1.1 2010/07/13 22:18:22 dorme Exp $
* <p>
* Based on code in: <i>The Java Cookbook</i><p>
* Ian F. Darwin<br/>
* ISBN: 0-596-00170-3 (First Edition, 2001)<br/>
* ISBN: 0-596-00701-9 (Second Edition, 2004)<br/>
* Publisher: O'Reilly & Associates
*/
public class UnZip {
/** Constants for mode listing or mode extracting. */
public static final int LIST = 0, EXTRACT = 1;
/** Whether we are extracting or just printing TOC */
protected int mode = EXTRACT;
/** The ZipFile that is used to read an archive */
protected ZipInputStream zipStream;
/** The buffer for reading/writing the ZipFile data */
protected byte[] b = new byte[8092];
private File baseDir;
/** Simple main program, construct an UnZipper, process each
* .ZIP file from argv[] through that object.
* @throws IOException
*/
public static void main(String[] argv) throws IOException {
UnZip u = new UnZip(new File("."));
for (int i=0; i<argv.length; i++) {
if ("-x".equals(argv[i])) {
u.setMode(EXTRACT);
continue;
}
String candidate = argv[i];
// System.err.println("Trying path " + candidate);
if (candidate.startsWith("http")) {
URL url = new URL(candidate);
u.unZip(url.openStream());
} else {
if (candidate.endsWith(".zip") ||
candidate.endsWith(".jar"))
u.unZip(candidate);
else System.err.println("Not a zip file? " + candidate);
}
}
System.err.println("All done!");
}
public UnZip(File baseDir) {
this.baseDir = baseDir;
}
/** Set the Mode (list, extract). */
protected void setMode(int m) {
if (m == LIST ||
m == EXTRACT)
mode = m;
}
/** Cache of paths we've mkdir()ed. */
protected SortedSet dirsMade;
/** For a given Zip file, process each entry. */
public void unZip(String fileName) {
dirsMade = new TreeSet();
try {
zipStream = new ZipInputStream(new FileInputStream(fileName));
readZipStream();
zipStream.close();
} catch (IOException err) {
System.err.println("IO Error: " + err);
return;
}
}
public void unZip(InputStream input) {
dirsMade = new TreeSet();
try {
zipStream = new ZipInputStream(input);
readZipStream();
zipStream.close();
} catch (IOException err) {
System.err.println("IO Error: " + err);
return;
}
}
private void readZipStream() throws IOException {
ZipEntry entry = zipStream.getNextEntry();
while (entry != null) {
getFile(entry);
entry = zipStream.getNextEntry();
}
}
protected boolean warnedMkDir = false;
/** Process one file from the zip, given its name.
* Either print the name, or create the file on disk.
*/
protected void getFile(ZipEntry e) throws IOException {
String zipName = e.getName();
switch (mode) {
case EXTRACT:
if (zipName.startsWith("/")) {
if (!warnedMkDir)
System.out.println("Ignoring absolute paths");
warnedMkDir = true;
zipName = zipName.substring(1);
}
// if a directory, just return. We mkdir for every file,
// since some widely-used Zip creators don't put out
// any directory entries, or put them in the wrong place.
if (zipName.endsWith("/")) {
return;
}
// Else must be a file; open the file for output
// Get the directory part.
int ix = zipName.lastIndexOf('/');
if (ix > 0) {
String dirName = zipName.substring(0, ix);
if (!dirsMade.contains(dirName)) {
File d = new File(baseDir, dirName);
// If it already exists as a dir, don't do anything
if (!(d.exists() && d.isDirectory())) {
// Try to create the directory, warn if it fails
System.out.println("Creating Directory: " + dirName);
if (!d.mkdirs()) {
System.err.println(
"Warning: unable to mkdir " + dirName);
}
dirsMade.add(dirName);
}
}
}
System.out.println("Creating " + zipName);
FileOutputStream os = new FileOutputStream(new File(baseDir, zipName));
int n = 0;
while ((n = zipStream.read(b)) != -1)
os.write(b, 0, n);
os.close();
break;
case LIST:
// Not extracting, just list
if (e.isDirectory()) {
System.out.println("Directory " + zipName);
} else {
System.out.println("File " + zipName);
}
break;
default:
throw new IllegalStateException("mode value (" + mode + ") bad");
}
}
}