| /******************************************************************************* |
| * Copyright (c) 2004, 2010 BREDEX GmbH. |
| * 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: |
| * BREDEX GmbH - initial API and implementation and/or initial documentation |
| *******************************************************************************/ |
| package org.eclipse.jubula.tools.internal.utils; |
| |
| 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.util.ArrayList; |
| import java.util.Enumeration; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.zip.ZipEntry; |
| import java.util.zip.ZipFile; |
| import java.util.zip.ZipOutputStream; |
| |
| import org.apache.commons.lang.StringUtils; |
| /** |
| * This Util class contains methods to ZIP and unzip directories |
| * |
| * @author BREDEX GmbH |
| * @created 13.08.2010 |
| */ |
| public class ZipUtil { |
| |
| /** file extension for JAR files, in lower case */ |
| private static final String JAR_FILE_EXT = ".jar"; //$NON-NLS-1$ |
| |
| /** mapping from a ZIP file to its extracted temporary JAR files */ |
| private static Map<File, File[]> zipToTempJars = |
| new HashMap<File, File[]>(); |
| |
| /** |
| * |
| * @author BREDEX GmbH |
| * @created 23.06.2011 |
| */ |
| public static interface IZipEntryFilter { |
| |
| /** |
| * |
| * @param entry The ZIP entry to filter. |
| * @return <code>true</code> if the ZIP entry should be accepted. |
| * Otherwise, <code>false</code>. |
| */ |
| public boolean accept(ZipEntry entry); |
| |
| } |
| |
| /** to prevent instantiation */ |
| private ZipUtil() { |
| //do nothing |
| } |
| /** |
| * This method converts a directory into a zip file |
| * @param directory The directory to zip |
| * @param zip The destination zip file |
| * @throws IOException |
| */ |
| public static final void zipDirectory(File directory, File zip) |
| throws IOException { |
| ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip)); |
| zip(directory, directory, zos); |
| zos.close(); |
| } |
| |
| /** |
| * This method converts a directory into a zip file |
| * @param directory The directory to zip |
| * @param base The directory to zip |
| * @param zos A ZipOutputStream |
| * @throws IOException |
| */ |
| private static final void zip(File directory, File base, |
| ZipOutputStream zos) |
| throws IOException { |
| File[] files = directory.listFiles(); |
| byte[] buffer = new byte[8192]; |
| int read = 0; |
| for (int i = 0, n = files.length; i < n; i++) { |
| if (files[i].isDirectory()) { |
| zip(files[i], base, zos); |
| } else { |
| FileInputStream in = new FileInputStream(files[i]); |
| ZipEntry entry = new ZipEntry(files[i].getPath().substring( |
| base.getPath().length() + 1)); |
| zos.putNextEntry(entry); |
| while (-1 != (read = in.read(buffer))) { |
| zos.write(buffer, 0, read); |
| } |
| in.close(); |
| } |
| } |
| } |
| /** |
| * This method unzip's a zip file into a given folder |
| * @param zip The zip file |
| * @param extractTo The destination folder |
| * @throws IOException |
| */ |
| public static final void unzip(File zip, File extractTo) |
| throws IOException { |
| |
| unzipFiles(zip, extractTo, new IZipEntryFilter() { |
| public boolean accept(ZipEntry entry) { |
| return true; |
| } |
| }); |
| } |
| |
| /** |
| * Extracts all JAR files from the given ZIP file into temporary JAR files. |
| * The directory structure of the extracted contents is not maintained. |
| * A mapping from ZIP file to extracted JARs is maintained by this class, |
| * so multiple calls to this method for a single ZIP file will extract JAR |
| * files once and return references to those files for each subsequent call. |
| * The extracted JAR files are deleted on VM exit. |
| * @param srcZip The ZIP file to extract. |
| * @return all extracted files. |
| * @throws IOException |
| */ |
| public static File[] unzipTempJars(File srcZip) |
| throws IOException { |
| |
| if (zipToTempJars.containsKey(srcZip)) { |
| return zipToTempJars.get(srcZip); |
| } |
| |
| IZipEntryFilter filter = new IZipEntryFilter() { |
| public boolean accept(ZipEntry entry) { |
| return entry.getName().toLowerCase().endsWith(JAR_FILE_EXT); |
| } |
| }; |
| ZipFile archive = new ZipFile(srcZip); |
| Enumeration<? extends ZipEntry> e = archive.entries(); |
| List<File> extractedFiles = new ArrayList<File>(); |
| while (e.hasMoreElements()) { |
| ZipEntry entry = e.nextElement(); |
| if (filter.accept(entry)) { |
| if (!entry.isDirectory()) { |
| String prefix = entry.getName().substring( |
| entry.getName().lastIndexOf("/") + 1, //$NON-NLS-1$ |
| entry.getName().toLowerCase().lastIndexOf( |
| JAR_FILE_EXT)); |
| File file = File.createTempFile( |
| StringUtils.rightPad(prefix, 3), |
| JAR_FILE_EXT); |
| extractedFiles.add(file); |
| file.deleteOnExit(); |
| unzipFile(archive, file, entry); |
| } |
| } |
| } |
| |
| File [] files = extractedFiles.toArray( |
| new File[extractedFiles.size()]); |
| zipToTempJars.put(srcZip, files); |
| return files; |
| } |
| |
| /** |
| * Unzips the contents of the given zip file into the given directory. |
| * |
| * @param srcZip The zip file to extract. |
| * @param targetDir The base directory for extracted files. |
| * @param filter Only files accepted by this filter will be extracted. |
| * @return all extracted files. |
| * @throws IOException |
| */ |
| public static File[] unzipFiles(File srcZip, File targetDir, |
| IZipEntryFilter filter) throws IOException { |
| |
| ZipFile archive = new ZipFile(srcZip); |
| Enumeration e = archive.entries(); |
| List<File> extractedFiles = new ArrayList<File>(); |
| while (e.hasMoreElements()) { |
| ZipEntry entry = (ZipEntry)e.nextElement(); |
| if (filter.accept(entry)) { |
| File file = new File(targetDir, entry.getName()); |
| if (entry.isDirectory() && !file.exists()) { |
| file.mkdirs(); |
| } else { |
| if (!file.getParentFile().exists()) { |
| file.getParentFile().mkdirs(); |
| } |
| |
| extractedFiles.add(file); |
| unzipFile(archive, file, entry); |
| } |
| } |
| } |
| return extractedFiles.toArray(new File[extractedFiles.size()]); |
| } |
| |
| /** |
| * |
| * @param archive The zip file from which to extract. |
| * @param targetFile The file to which the entry contents will be extracted. |
| * @param entry The entry to extract. |
| * @throws IOException |
| */ |
| private static void unzipFile(ZipFile archive, File targetFile, |
| ZipEntry entry) throws IOException { |
| InputStream in = null; |
| BufferedOutputStream out = null; |
| try { |
| in = archive.getInputStream(entry); |
| out = new BufferedOutputStream( |
| new FileOutputStream(targetFile)); |
| |
| byte[] buffer = new byte[8192]; |
| int read; |
| |
| while (-1 != (read = in.read(buffer))) { |
| out.write(buffer, 0, read); |
| } |
| } finally { |
| if (in != null) { |
| in.close(); |
| } |
| if (out != null) { |
| out.close(); |
| } |
| } |
| } |
| } |