/*
* Copyright 2010-2015 Institut Pasteur.
*
* This file is part of Icy.
*
* Icy is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Icy 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Icy. If not, see <http://www.gnu.org/licenses/>.
*/
package icy.util;
import icy.file.FileUtil;
import icy.network.NetworkUtil;
import icy.system.IcyExceptionHandler;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* @author Stephane
*/
public class ZipUtil
{
/**
* Compress the specified array of byte with given level of compression and return packed data.<br/>
*
* @param packer
* the packer object, can be <code>null</code> in which case we create a new Deflater object
* @param rawData
* raw data to compress
* @param level
* level of compression where 0 is low and 9 is high (use -1 to keep current / use default level)
*/
public static byte[] pack(Deflater packer, byte[] rawData, int level)
{
final Deflater compressor;
if (packer != null)
{
compressor = packer;
compressor.reset();
}
else
compressor = new Deflater();
if (level != -1)
compressor.setLevel(level);
// give data to compress
compressor.setInput(rawData);
compressor.finish();
// create an expandable byte array to hold the compressed data.
final ByteArrayOutputStream bos = new ByteArrayOutputStream(rawData.length);
final byte[] buf = new byte[65536];
// pack data
while (!compressor.finished())
{
final int count = compressor.deflate(buf);
// nothing more to do ? --> end here
if (count == 0)
break;
bos.write(buf, 0, count);
}
try
{
bos.close();
}
catch (IOException e)
{
// we can freely ignore this one
}
// return packed data
return bos.toByteArray();
}
/**
* Compress the specified array of byte and return packed data
*/
public static byte[] pack(byte[] rawData)
{
return pack(null, rawData, -1);
}
/**
* Uncompress the specified array of byte and return unpacked data
*
* @param unpacker
* the unpacker object, can be <code>null</code> in which case we create a new Inflater object
* @param packedData
* packed data to uncompress
* @throws DataFormatException
*/
public static byte[] unpack(Inflater unpacker, byte[] packedData) throws DataFormatException
{
final Inflater decompressor;
if (unpacker != null)
{
decompressor = unpacker;
decompressor.reset();
}
else
decompressor = new Inflater();
// give the data to uncompress
decompressor.setInput(packedData);
// create an expandable byte array to hold the uncompressed data
final ByteArrayOutputStream bos = new ByteArrayOutputStream(packedData.length);
final byte[] buf = new byte[65536];
// unpack data
while (!decompressor.finished())
{
final int count = decompressor.inflate(buf);
// nothing more to do ? --> end here
if (count == 0)
break;
bos.write(buf, 0, count);
}
try
{
bos.close();
}
catch (IOException e)
{
// we can freely ignore this one
}
// return unpacked data
return bos.toByteArray();
}
/**
* Uncompress the specified array of byte and return unpacked data
*
* @throws DataFormatException
*/
public static byte[] unpack(byte[] packedData) throws DataFormatException
{
return unpack(null, packedData);
}
/**
* Extract the specified zip file to the specified destination directory.
*
* @param zipFile
* input zip file name
* @param outputDirectory
* output directory name
* @return true if file was correctly extracted, false otherwise
*/
public static boolean extract(String zipFile, String outputDirectory)
{
boolean ok = true;
try
{
final ZipFile file = new ZipFile(zipFile);
final Enumeration<? extends ZipEntry> entries = file.entries();
while (entries.hasMoreElements())
{
ZipEntry entry = entries.nextElement();
if (entry.isDirectory())
{
if (!FileUtil.createDir(outputDirectory + FileUtil.separator + entry.getName()))
{
System.err.println("ZipUtil.extract(" + zipFile + "," + outputDirectory + ") error :");
System.err.println("Can't create directory : '" + outputDirectory + FileUtil.separator
+ entry.getName() + "'");
ok = false;
break;
}
}
else if (!FileUtil.save(outputDirectory + FileUtil.separator + entry.getName(),
NetworkUtil.download(file.getInputStream(entry)), true))
{
System.err.println("ZipUtil.extract(" + zipFile + "," + outputDirectory + ") failed.");
ok = false;
break;
}
}
file.close();
}
catch (IOException ioe)
{
System.err.println("ZipUtil.extract(" + zipFile + "," + outputDirectory + ") error :");
IcyExceptionHandler.showErrorMessage(ioe, false);
ok = false;
}
return ok;
}
/**
* Extract the specified zip file in to default location.
*
* @param zipFile
* input zip file name
* @return true if file was correctly extracted, false otherwise
*/
public static boolean extract(String zipFile)
{
return extract(zipFile, FileUtil.getDirectory(zipFile) + FileUtil.getFileName(zipFile, false));
}
/**
* Verify that specified file is a valid ZIP file
*
* @param zipFile
* input zip file name
* @throws IOException
* if the input file is not a valid zip file.
*/
public static void isValid(String zipFile) throws IOException
{
final ZipFile file = new ZipFile(zipFile);
try
{
final Enumeration<? extends ZipEntry> entries = file.entries();
while (entries.hasMoreElements())
{
ZipEntry entry = entries.nextElement();
entry.getName();
}
}
finally
{
file.close();
}
}
/**
* Verify that specified file is a valid ZIP file
*
* @param zipFile
* input zip file name
* @param showError
* indicate if the method should show the error (in the output console) if the verify operation failed.
* @return true if the specified file is a valid ZIP file
*/
public static boolean isValid(String zipFile, boolean showError)
{
try
{
isValid(zipFile);
}
catch (IOException e)
{
if (showError)
{
System.err.println("ZipUtil.isValid(" + zipFile + ") error :");
IcyExceptionHandler.showErrorMessage(e, false);
}
return false;
}
return true;
}
}