001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2011 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * Sonar is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * Sonar is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with Sonar; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 019 */ 020 package org.sonar.api.utils; 021 022 import org.apache.commons.io.FileUtils; 023 import org.apache.commons.io.IOUtils; 024 025 import java.io.*; 026 import java.util.Enumeration; 027 import java.util.zip.ZipEntry; 028 import java.util.zip.ZipFile; 029 import java.util.zip.ZipOutputStream; 030 031 /** 032 * @since 1.10 033 */ 034 public final class ZipUtils { 035 036 private ZipUtils() { 037 // only static methods 038 } 039 040 /** 041 * Unzip a file into a new temporary directory. The directory is not deleted on JVM exit, so it 042 * must be explicitely deleted. 043 * @return the temporary directory 044 * @since 2.2 045 */ 046 public static File unzipToTempDir(File zip) throws IOException { 047 File toDir = TempFileUtils.createTempDirectory(); 048 unzip (zip, toDir); 049 return toDir; 050 } 051 052 /** 053 * Unzip a file into a directory. The directory is created if it does not exist. 054 * @return the target directory 055 */ 056 public static File unzip(File zip, File toDir) throws IOException { 057 unzip(zip, toDir, new ZipEntryFilter() { 058 public boolean accept(ZipEntry entry) { 059 return true; 060 } 061 }); 062 return toDir; 063 } 064 065 public static void unzip(File zip, File toDir, ZipEntryFilter filter) throws IOException { 066 if (!toDir.exists()) { 067 FileUtils.forceMkdir(toDir); 068 } 069 070 ZipFile zipFile = new ZipFile(zip); 071 try { 072 Enumeration<? extends ZipEntry> entries = zipFile.entries(); 073 while (entries.hasMoreElements()) { 074 ZipEntry entry = entries.nextElement(); 075 if (filter.accept(entry)) { 076 File to = new File(toDir, entry.getName()); 077 if (entry.isDirectory()) { 078 if (!to.exists() && !to.mkdirs()) { 079 throw new IOException("Error creating directory: " + to); 080 } 081 } else { 082 File parent = to.getParentFile(); 083 if (parent != null && !parent.exists() && !parent.mkdirs()) { 084 throw new IOException("Error creating directory: " + parent); 085 } 086 087 FileOutputStream fos = new FileOutputStream(to); 088 try { 089 IOUtils.copy(zipFile.getInputStream(entry), fos); 090 } finally { 091 IOUtils.closeQuietly(fos); 092 } 093 } 094 } 095 } 096 } finally { 097 zipFile.close(); 098 } 099 } 100 101 public static void zipDir(File dir, File zip) throws IOException { 102 OutputStream out = null; 103 ZipOutputStream zout = null; 104 try { 105 out = FileUtils.openOutputStream(zip); 106 zout = new ZipOutputStream(out); 107 zip(dir, zout, null); 108 109 } finally { 110 IOUtils.closeQuietly(zout); 111 IOUtils.closeQuietly(out); 112 } 113 } 114 115 116 private static void _zip(String entryName, InputStream in, ZipOutputStream out) throws IOException { 117 ZipEntry zentry = new ZipEntry(entryName); 118 out.putNextEntry(zentry); 119 IOUtils.copy(in, out); 120 out.closeEntry(); 121 } 122 123 private static void _zip(String entryName, File file, ZipOutputStream out) throws IOException { 124 if (file.isDirectory()) { 125 entryName += '/'; 126 ZipEntry zentry = new ZipEntry(entryName); 127 out.putNextEntry(zentry); 128 out.closeEntry(); 129 File[] files = file.listFiles(); 130 for (int i = 0, len = files.length; i < len; i++) { 131 _zip(entryName + files[i].getName(), files[i], out); 132 } 133 134 } else { 135 InputStream in = null; 136 try { 137 in = new BufferedInputStream(new FileInputStream(file)); 138 _zip(entryName, in, out); 139 } finally { 140 IOUtils.closeQuietly(in); 141 } 142 } 143 } 144 145 private static void zip(File file, ZipOutputStream out, String prefix) throws IOException { 146 if (prefix != null) { 147 int len = prefix.length(); 148 if (len == 0) { 149 prefix = null; 150 } else if (prefix.charAt(len - 1) != '/') { 151 prefix += '/'; 152 } 153 } 154 for (File child : file.listFiles()) { 155 String name = prefix != null ? prefix + child.getName() : child.getName(); 156 _zip(name, child, out); 157 } 158 } 159 160 public static interface ZipEntryFilter { 161 boolean accept(ZipEntry entry); 162 } 163 164 } 165