001 /* 002 * SonarQube, open source software quality management tool. 003 * Copyright (C) 2008-2014 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * SonarQube 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 * SonarQube 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 License 017 * along with this program; if not, write to the Free Software Foundation, 018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 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.BufferedInputStream; 026 import java.io.File; 027 import java.io.FileInputStream; 028 import java.io.FileOutputStream; 029 import java.io.IOException; 030 import java.io.InputStream; 031 import java.io.OutputStream; 032 import java.util.Enumeration; 033 import java.util.zip.ZipEntry; 034 import java.util.zip.ZipFile; 035 import java.util.zip.ZipOutputStream; 036 037 /** 038 * @since 1.10 039 */ 040 public final class ZipUtils { 041 042 private static final String ERROR_CREATING_DIRECTORY = "Error creating directory: "; 043 044 private ZipUtils() { 045 // only static methods 046 } 047 048 /** 049 * Unzip a file into a directory. The directory is created if it does not exist. 050 * 051 * @return the target directory 052 */ 053 public static File unzip(File zip, File toDir) throws IOException { 054 unzip(zip, toDir, new ZipEntryFilter() { 055 @Override 056 public boolean accept(ZipEntry entry) { 057 return true; 058 } 059 }); 060 return toDir; 061 } 062 063 public static File unzip(File zip, File toDir, ZipEntryFilter filter) throws IOException { 064 if (!toDir.exists()) { 065 FileUtils.forceMkdir(toDir); 066 } 067 068 ZipFile zipFile = new ZipFile(zip); 069 try { 070 Enumeration<? extends ZipEntry> entries = zipFile.entries(); 071 while (entries.hasMoreElements()) { 072 ZipEntry entry = entries.nextElement(); 073 if (filter.accept(entry)) { 074 File to = new File(toDir, entry.getName()); 075 if (entry.isDirectory()) { 076 if (!to.exists() && !to.mkdirs()) { 077 throw new IOException(ERROR_CREATING_DIRECTORY + to); 078 } 079 } else { 080 File parent = to.getParentFile(); 081 if (parent != null && !parent.exists() && !parent.mkdirs()) { 082 throw new IOException(ERROR_CREATING_DIRECTORY + parent); 083 } 084 085 copy(zipFile, entry, to); 086 } 087 } 088 } 089 return toDir; 090 091 } finally { 092 zipFile.close(); 093 } 094 } 095 096 private static void copy(ZipFile zipFile, ZipEntry entry, File to) throws IOException { 097 FileOutputStream fos = new FileOutputStream(to); 098 InputStream input = null; 099 try { 100 input = zipFile.getInputStream(entry); 101 IOUtils.copy(input, fos); 102 } finally { 103 IOUtils.closeQuietly(input); 104 IOUtils.closeQuietly(fos); 105 } 106 } 107 108 public static void zipDir(File dir, File zip) throws IOException { 109 OutputStream out = null; 110 ZipOutputStream zout = null; 111 try { 112 out = FileUtils.openOutputStream(zip); 113 zout = new ZipOutputStream(out); 114 zip(dir, zout); 115 116 } finally { 117 IOUtils.closeQuietly(zout); 118 IOUtils.closeQuietly(out); 119 } 120 } 121 122 private static void doZip(String entryName, InputStream in, ZipOutputStream out) throws IOException { 123 ZipEntry zentry = new ZipEntry(entryName); 124 out.putNextEntry(zentry); 125 IOUtils.copy(in, out); 126 out.closeEntry(); 127 } 128 129 private static void doZip(String entryName, File file, ZipOutputStream out) throws IOException { 130 if (file.isDirectory()) { 131 entryName += '/'; 132 ZipEntry zentry = new ZipEntry(entryName); 133 out.putNextEntry(zentry); 134 out.closeEntry(); 135 File[] files = file.listFiles(); 136 for (int i = 0, len = files.length; i < len; i++) { 137 doZip(entryName + files[i].getName(), files[i], out); 138 } 139 140 } else { 141 InputStream in = null; 142 try { 143 in = new BufferedInputStream(new FileInputStream(file)); 144 doZip(entryName, in, out); 145 } finally { 146 IOUtils.closeQuietly(in); 147 } 148 } 149 } 150 151 private static void zip(File file, ZipOutputStream out) throws IOException { 152 for (File child : file.listFiles()) { 153 String name = child.getName(); 154 doZip(name, child, out); 155 } 156 } 157 158 public interface ZipEntryFilter { 159 boolean accept(ZipEntry entry); 160 } 161 162 }