/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.it;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Path;
import java.util.Enumeration;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.io.IOUtils;
/**
* Extracts a zip file with preserving the unix file permissions.
*
* @author Andreas Dangel
*/
public class ZipFileExtractor {
// unix file permission for executable flag by owner
private static final int OWNER_EXECUTABLE = 0x40;
private ZipFileExtractor() {
// Helper class
}
/**
* Extracts the given zip file into the tempDir.
* @param zipPath the zip file to extract
* @param tempDir the target directory
* @throws Exception if any error happens during extraction
*/
public static void extractZipFile(Path zipPath, Path tempDir) throws Exception {
ZipFile zip = new ZipFile(zipPath.toFile());
try {
Enumeration<ZipArchiveEntry> entries = zip.getEntries();
while (entries.hasMoreElements()) {
ZipArchiveEntry entry = entries.nextElement();
File file = tempDir.resolve(entry.getName()).toFile();
if (entry.isDirectory()) {
assertTrue(file.mkdirs());
} else {
try (InputStream data = zip.getInputStream(entry);
OutputStream fileOut = new FileOutputStream(file);) {
IOUtils.copy(data, fileOut);
}
if ((entry.getUnixMode() & OWNER_EXECUTABLE) == OWNER_EXECUTABLE) {
file.setExecutable(true);
}
}
}
} finally {
zip.close();
}
}
}