/*
* (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser General Public License
* (LGPL) version 2.1 which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl.html
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* Contributors:
* Nuxeo - initial API and implementation
*
*
* $$Id$$
*/
package org.nuxeo.common.utils;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
/**
* @author bstefanescu
*/
public final class ZipUtils {
// This is an utility class
private ZipUtils() {
}
// _____________________________ ZIP ________________________________
public static void _putDirectoryEntry(String entryName, ZipOutputStream out)
throws IOException {
ZipEntry zentry = new ZipEntry(entryName + '/');
out.putNextEntry(zentry);
out.closeEntry();
}
public static void _putFileEntry(File file, String entryName,
ZipOutputStream out) throws IOException {
FileInputStream in = null;
try {
in = new FileInputStream(file);
_zip(entryName, in, out);
} finally {
if (in != null) {
in.close();
}
}
}
public static void _zip(String entryName, InputStream in,
ZipOutputStream out) throws IOException {
ZipEntry zentry = new ZipEntry(entryName);
out.putNextEntry(zentry);
// Transfer bytes from the input stream to the ZIP file
FileUtils.copy(in, out);
out.closeEntry();
}
public static void _zip(String entryName, File file, ZipOutputStream out)
throws IOException {
// System.out.println("Compressing "+entryName);
if (file.isDirectory()) {
entryName += '/';
ZipEntry zentry = new ZipEntry(entryName);
out.putNextEntry(zentry);
out.closeEntry();
File[] files = file.listFiles();
for (int i = 0, len = files.length; i < len; i++) {
_zip(entryName + files[i].getName(), files[i], out);
}
} else {
InputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(file));
_zip(entryName, in, out);
} finally {
if (in != null) {
in.close();
}
}
}
}
public static void _zip(File[] files, ZipOutputStream out, String prefix)
throws IOException {
if (prefix != null) {
int len = prefix.length();
if (len == 0) {
prefix = null;
} else if (prefix.charAt(len - 1) != '/') {
prefix += '/';
}
}
for (int i = 0, len = files.length; i < len; i++) {
String name = prefix != null ? prefix + files[i].getName()
: files[i].getName();
_zip(name, files[i], out);
}
}
public static void zip(File file, OutputStream out, String prefix)
throws IOException {
if (prefix != null) {
int len = prefix.length();
if (len == 0) {
prefix = null;
} else if (prefix.charAt(len - 1) != '/') {
prefix += '/';
}
}
String name = prefix != null ? prefix + file.getName() : file.getName();
ZipOutputStream zout = null;
try {
zout = new ZipOutputStream(out);
_zip(name, file, zout);
} finally {
if (zout != null) {
zout.finish();
}
}
}
public static void zip(File[] files, OutputStream out, String prefix)
throws IOException {
ZipOutputStream zout = null;
try {
zout = new ZipOutputStream(out);
_zip(files, zout, prefix);
} finally {
if (zout != null) {
zout.finish();
}
}
}
public static void zip(File file, File zip) throws IOException {
OutputStream out = null;
try {
out = new BufferedOutputStream(new FileOutputStream(zip));
zip(file, out, null);
} finally {
if (out != null) {
out.close();
}
}
}
public static void zip(File[] files, File zip) throws IOException {
OutputStream out = null;
try {
out = new BufferedOutputStream(new FileOutputStream(zip));
zip(files, out, null);
} finally {
if (out != null) {
out.close();
}
}
}
public static void zip(File file, File zip, String prefix)
throws IOException {
OutputStream out = null;
try {
out = new BufferedOutputStream(new FileOutputStream(zip));
zip(file, out, prefix);
} finally {
if (out != null) {
out.close();
}
}
}
public static void zip(File[] files, File zip, String prefix)
throws IOException {
OutputStream out = null;
try {
out = new BufferedOutputStream(new FileOutputStream(zip));
zip(files, out, prefix);
} finally {
if (out != null) {
out.close();
}
}
}
public static void zipFilesUsingPrefix(String prefix, File[] files,
OutputStream out) throws IOException {
ZipOutputStream zout = null;
try {
zout = new ZipOutputStream(out);
if (prefix != null && prefix.length() > 0) {
int p = prefix.indexOf('/');
while (p > -1) {
_putDirectoryEntry(prefix.substring(0, p), zout);
p = prefix.indexOf(p + 1, '/');
}
_putDirectoryEntry(prefix, zout);
prefix += '/';
} else {
prefix = "";
}
// prefix = prefix + '/';
for (File file : files) {
_putFileEntry(file, prefix + file.getName(), zout);
}
} finally {
if (zout != null) {
zout.finish();
}
}
}
// _____________________________ UNZIP ________________________________
public static void unzip(String prefix, InputStream zipStream, File dir)
throws IOException {
ZipInputStream in = null;
try {
in = new ZipInputStream(new BufferedInputStream(zipStream));
unzip(prefix, in, dir);
} finally {
if (in != null) {
in.close();
}
}
}
public static void unzip(InputStream zipStream, File dir)
throws IOException {
ZipInputStream in = null;
try {
in = new ZipInputStream(new BufferedInputStream(zipStream));
unzip(in, dir);
} finally {
if (in != null) {
in.close();
}
}
}
public static void unzip(String prefix, URL zip, File dir)
throws IOException {
ZipInputStream in = null;
try {
in = new ZipInputStream(new BufferedInputStream(zip.openStream()));
unzip(prefix, in, dir);
} finally {
if (in != null) {
in.close();
}
}
}
public static void unzip(URL zip, File dir) throws IOException {
ZipInputStream in = null;
try {
in = new ZipInputStream(new BufferedInputStream(zip.openStream()));
unzip(in, dir);
} finally {
if (in != null) {
in.close();
}
}
}
public static void unzip(String prefix, File zip, File dir)
throws IOException {
ZipInputStream in = null;
try {
in = new ZipInputStream(new BufferedInputStream(
new FileInputStream(zip)));
unzip(prefix, in, dir);
} finally {
if (in != null) {
in.close();
}
}
}
public static void unzip(File zip, File dir) throws IOException {
ZipInputStream in = null;
try {
in = new ZipInputStream(new BufferedInputStream(
new FileInputStream(zip)));
unzip(in, dir);
} finally {
if (in != null) {
in.close();
}
}
}
public static void unzip(String prefix, ZipInputStream in, File dir)
throws IOException {
dir.mkdirs();
ZipEntry entry = in.getNextEntry();
while (entry != null) {
if (!entry.getName().startsWith(prefix)) {
entry = in.getNextEntry();
continue;
}
File file = new File(dir,
entry.getName().substring(prefix.length()));
if (entry.isDirectory()) {
file.mkdirs();
} else {
file.getParentFile().mkdirs();
FileUtils.copyToFile(in, file);
}
entry = in.getNextEntry();
}
}
public static void unzip(ZipInputStream in, File dir) throws IOException {
dir.mkdirs();
ZipEntry entry = in.getNextEntry();
while (entry != null) {
// System.out.println("Extracting "+entry.getName());
File file = new File(dir, entry.getName());
if (entry.isDirectory()) {
file.mkdirs();
} else {
file.getParentFile().mkdirs();
FileUtils.copyToFile(in, file);
}
entry = in.getNextEntry();
}
}
public static void unzipIgnoreDirs(ZipInputStream in, File dir)
throws IOException {
dir.mkdirs();
ZipEntry entry = in.getNextEntry();
while (entry != null) {
String entryName = entry.getName();
if (entry.isDirectory()) {
} else {
int p = entryName.lastIndexOf('/');
if (p > -1) {
entryName = entryName.substring(p + 1);
}
File file = new File(dir, entryName);
FileUtils.copyToFile(in, file);
}
entry = in.getNextEntry();
}
}
public static void unzipIgnoreDirs(InputStream zipStream, File dir)
throws IOException {
ZipInputStream in = null;
try {
in = new ZipInputStream(new BufferedInputStream(zipStream));
unzipIgnoreDirs(in, dir);
} finally {
if (in != null) {
in.close();
}
}
}
public static void unzip(File zip, File dir, PathFilter filter)
throws IOException {
ZipInputStream in = null;
try {
in = new ZipInputStream(new BufferedInputStream(
new FileInputStream(zip)));
unzip(in, dir, filter);
} finally {
if (in != null) {
in.close();
}
}
}
public static void unzip(ZipInputStream in, File dir, PathFilter filter)
throws IOException {
if (filter == null) {
unzip(in, dir);
return;
}
ZipEntry entry = in.getNextEntry();
while (entry != null) {
String entryName = entry.getName();
if (filter.accept(new Path(entryName))) {
// System.out.println("Extracting "+entryName);
File file = new File(dir, entryName);
if (entry.isDirectory()) {
file.mkdirs();
} else {
file.getParentFile().mkdirs();
FileUtils.copyToFile(in, file);
}
}
entry = in.getNextEntry();
}
}
public static void unzip(String prefix, File zip, File dir,
PathFilter filter) throws IOException {
ZipInputStream in = null;
try {
in = new ZipInputStream(new BufferedInputStream(
new FileInputStream(zip)));
unzip(prefix, in, dir, filter);
} finally {
if (in != null) {
in.close();
}
}
}
public static void unzip(String prefix, ZipInputStream in, File dir, PathFilter filter)
throws IOException {
if (filter == null) {
unzip(prefix,in, dir);
return;
}
dir.mkdirs();
ZipEntry entry = in.getNextEntry();
while (entry != null) {
String entryName = entry.getName();
if (filter.accept(new Path(entryName))) {
if (!entry.getName().startsWith(prefix)) {
entry = in.getNextEntry();
continue;
}
File file = new File(dir,
entry.getName().substring(prefix.length()));
if (entry.isDirectory()) {
file.mkdirs();
} else {
file.getParentFile().mkdirs();
FileUtils.copyToFile(in, file);
}
}
entry = in.getNextEntry();
}
}
// ________________ Entries ________________
/**
* Unzip directly the entry. The returned InputStream has to be closed.
*
* @return the input stream of the desired entry - has to be closed by the
* caller, or null if not found
* @param file the source file
* @param entryName the entry name that has to be extracted
*/
public static InputStream getEntryContentAsStream(File file,
String entryName) throws IOException {
InputStream result = null;
ZipFile zip = new ZipFile(file);
ZipEntry entry = zip.getEntry(entryName);
if (entry != null) {
result = zip.getInputStream(entry);
}
return result;
}
/**
* Unzip directly the entry.
*
* @return the String content of the entry with name entryName
* @param file the source file
* @param entryName the entry name that has to be extracted
*/
public static String getEntryContentAsString(File file, String entryName)
throws IOException {
InputStream resultStream = getEntryContentAsStream(file, entryName);
// resultStream has been closed by FileUtils call
return FileUtils.read(resultStream);
}
/**
* Unzips directly the entry.
*
* @return The byte array content of the entry with name entryName
* @param file the source file
* @param entryName the entry name that has to be extracted
*/
public static byte[] getEntryContentAsBytes(File file, String entryName)
throws IOException {
InputStream resultStream = getEntryContentAsStream(file, entryName);
// resultStream has been closed by FileUtils call
return FileUtils.readBytes(resultStream);
}
/**
* Lists the entries on the zip file.
*
* @param file The zip file
* @return The list of entries
*/
public static List<String> getEntryNames(File file) throws IOException {
List<String> result = new ArrayList<String>();
ZipFile zip = new ZipFile(file);
try {
Enumeration<? extends ZipEntry> entries = zip.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
result.add(entry.getName());
}
} finally {
zip.close();
}
return result;
}
/**
* Checks if a zip file contains a specified entry name.
*
* @param file the zip file
* @param entryName The content to be checked
* @return True if the file contains entryName. False otherwise
*/
public static boolean hasEntry(File file, String entryName)
throws IOException {
List<String> elements = getEntryNames(file);
return elements.contains(entryName);
}
public static InputStream getEntryContentAsStream(InputStream stream,
String entryName) throws IOException {
ZipInputStream zip = new ZipInputStream(stream);
ZipEntry entry = zip.getNextEntry();
while (entry != null) {
if (entry.getName().equals(entryName)) {
return zip;
}
entry = zip.getNextEntry();
}
return null;
}
public static String getEntryContentAsString(InputStream stream,
String searchedEntryName) throws IOException {
InputStream resultStream = getEntryContentAsStream(stream,
searchedEntryName);
// resultStream has been closed by FileUtils call
return FileUtils.read(resultStream);
}
public static byte[] getEntryContentAsBytes(InputStream stream,
String searchedEntryName) throws IOException {
InputStream resultStream = getEntryContentAsStream(stream,
searchedEntryName);
// resultStream has been closed by FileUtils call
return FileUtils.readBytes(resultStream);
}
public static List<String> getEntryNames(InputStream stream)
throws IOException {
List<String> result = new ArrayList<String>();
ZipInputStream zip = new ZipInputStream(stream);
try {
while (zip.available() == 1) {
ZipEntry entry = zip.getNextEntry();
if (entry != null) {
result.add(entry.getName());
}
}
} finally {
zip.close();
}
return result;
}
public static boolean hasEntry(InputStream stream, String entryName)
throws IOException {
List<String> elements = getEntryNames(stream);
return elements.contains(entryName);
}
public static InputStream getEntryContentAsStream(URL url, String entryName)
throws IOException {
return getEntryContentAsStream(url.openStream(), entryName);
}
public static String getEntryContentAsString(URL url, String entryName)
throws IOException {
InputStream resultStream = getEntryContentAsStream(url, entryName);
// resultStream has been closed by FileUtils call
return FileUtils.read(resultStream);
}
public static byte[] getEntryContentAsBytes(URL url, String entryName)
throws IOException {
InputStream resultStream = getEntryContentAsStream(url, entryName);
// resultStream has been closed by FileUtils call
return FileUtils.readBytes(resultStream);
}
public static List<String> getEntryNames(URL url) throws IOException {
return getEntryNames(url.openStream());
}
public static boolean hasEntry(URL url, String entryName)
throws IOException {
return hasEntry(url.openStream(), entryName);
}
}