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 */ 020package org.sonar.api.utils; 021 022import org.apache.commons.io.FileUtils; 023import org.apache.commons.io.IOUtils; 024 025import java.io.*; 026import java.util.Enumeration; 027import java.util.zip.ZipEntry; 028import java.util.zip.ZipFile; 029import java.util.zip.ZipOutputStream; 030 031/** 032 * @since 1.10 033 */ 034public 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 * @deprecated since 3.4 use by {@link org.sonar.api.resources.ProjectFileSystem#getSonarWorkingDirectory} or {@link org.sonar.api.platform.ServerFileSystem#getTempDir} 046 */ 047 @Deprecated 048 public static File unzipToTempDir(File zip) throws IOException { 049 File toDir = TempFileUtils.createTempDirectory(); 050 unzip (zip, toDir); 051 return toDir; 052 } 053 054 /** 055 * Unzip a file into a directory. The directory is created if it does not exist. 056 * @return the target directory 057 */ 058 public static File unzip(File zip, File toDir) throws IOException { 059 unzip(zip, toDir, new ZipEntryFilter() { 060 public boolean accept(ZipEntry entry) { 061 return true; 062 } 063 }); 064 return toDir; 065 } 066 067 public static File unzip(File zip, File toDir, ZipEntryFilter filter) throws IOException { 068 if (!toDir.exists()) { 069 FileUtils.forceMkdir(toDir); 070 } 071 072 ZipFile zipFile = new ZipFile(zip); 073 try { 074 Enumeration<? extends ZipEntry> entries = zipFile.entries(); 075 while (entries.hasMoreElements()) { 076 ZipEntry entry = entries.nextElement(); 077 if (filter.accept(entry)) { 078 File to = new File(toDir, entry.getName()); 079 if (entry.isDirectory()) { 080 if (!to.exists() && !to.mkdirs()) { 081 throw new IOException("Error creating directory: " + to); 082 } 083 } else { 084 File parent = to.getParentFile(); 085 if (parent != null && !parent.exists() && !parent.mkdirs()) { 086 throw new IOException("Error creating directory: " + parent); 087 } 088 089 FileOutputStream fos = new FileOutputStream(to); 090 InputStream input = null; 091 try { 092 input = zipFile.getInputStream(entry); 093 IOUtils.copy(input, fos); 094 } finally { 095 IOUtils.closeQuietly(input); 096 IOUtils.closeQuietly(fos); 097 } 098 } 099 } 100 } 101 return toDir; 102 103 } finally { 104 zipFile.close(); 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, null); 115 116 } finally { 117 IOUtils.closeQuietly(zout); 118 IOUtils.closeQuietly(out); 119 } 120 } 121 122 123 private static void _zip(String entryName, InputStream in, ZipOutputStream out) throws IOException { 124 ZipEntry zentry = new ZipEntry(entryName); 125 out.putNextEntry(zentry); 126 IOUtils.copy(in, out); 127 out.closeEntry(); 128 } 129 130 private static void _zip(String entryName, File file, ZipOutputStream out) throws IOException { 131 if (file.isDirectory()) { 132 entryName += '/'; 133 ZipEntry zentry = new ZipEntry(entryName); 134 out.putNextEntry(zentry); 135 out.closeEntry(); 136 File[] files = file.listFiles(); 137 for (int i = 0, len = files.length; i < len; i++) { 138 _zip(entryName + files[i].getName(), files[i], out); 139 } 140 141 } else { 142 InputStream in = null; 143 try { 144 in = new BufferedInputStream(new FileInputStream(file)); 145 _zip(entryName, in, out); 146 } finally { 147 IOUtils.closeQuietly(in); 148 } 149 } 150 } 151 152 private static void zip(File file, ZipOutputStream out, String prefix) throws IOException { 153 if (prefix != null) { 154 int len = prefix.length(); 155 if (len == 0) { 156 prefix = null; 157 } else if (prefix.charAt(len - 1) != '/') { 158 prefix += '/'; 159 } 160 } 161 for (File child : file.listFiles()) { 162 String name = prefix != null ? prefix + child.getName() : child.getName(); 163 _zip(name, child, out); 164 } 165 } 166 167 public interface ZipEntryFilter { 168 boolean accept(ZipEntry entry); 169 } 170 171} 172