001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2012 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 File 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 InputStream input = null; 089 try { 090 input = zipFile.getInputStream(entry); 091 IOUtils.copy(input, fos); 092 } finally { 093 IOUtils.closeQuietly(input); 094 IOUtils.closeQuietly(fos); 095 } 096 } 097 } 098 } 099 return toDir; 100 101 } finally { 102 zipFile.close(); 103 } 104 } 105 106 public static void zipDir(File dir, File zip) throws IOException { 107 OutputStream out = null; 108 ZipOutputStream zout = null; 109 try { 110 out = FileUtils.openOutputStream(zip); 111 zout = new ZipOutputStream(out); 112 zip(dir, zout, null); 113 114 } finally { 115 IOUtils.closeQuietly(zout); 116 IOUtils.closeQuietly(out); 117 } 118 } 119 120 121 private static void _zip(String entryName, InputStream in, ZipOutputStream out) throws IOException { 122 ZipEntry zentry = new ZipEntry(entryName); 123 out.putNextEntry(zentry); 124 IOUtils.copy(in, out); 125 out.closeEntry(); 126 } 127 128 private static void _zip(String entryName, File file, ZipOutputStream out) throws IOException { 129 if (file.isDirectory()) { 130 entryName += '/'; 131 ZipEntry zentry = new ZipEntry(entryName); 132 out.putNextEntry(zentry); 133 out.closeEntry(); 134 File[] files = file.listFiles(); 135 for (int i = 0, len = files.length; i < len; i++) { 136 _zip(entryName + files[i].getName(), files[i], out); 137 } 138 139 } else { 140 InputStream in = null; 141 try { 142 in = new BufferedInputStream(new FileInputStream(file)); 143 _zip(entryName, in, out); 144 } finally { 145 IOUtils.closeQuietly(in); 146 } 147 } 148 } 149 150 private static void zip(File file, ZipOutputStream out, String prefix) throws IOException { 151 if (prefix != null) { 152 int len = prefix.length(); 153 if (len == 0) { 154 prefix = null; 155 } else if (prefix.charAt(len - 1) != '/') { 156 prefix += '/'; 157 } 158 } 159 for (File child : file.listFiles()) { 160 String name = prefix != null ? prefix + child.getName() : child.getName(); 161 _zip(name, child, out); 162 } 163 } 164 165 public interface ZipEntryFilter { 166 boolean accept(ZipEntry entry); 167 } 168 169 } 170