/** * 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(); } } }