package com.thebrokenrail.freshcoffee.util; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UncheckedIOException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; public class ExtractUtil { private static String stripFirstComponent(String file) { String path = new File(file).getPath(); String[] parts = path.split(File.separator); List newParts = new ArrayList<>(Arrays.asList(parts).subList(1, parts.length)); return String.join(File.separator, newParts); } public static void extract(URL url, File dir) { Util.getLogger().info("Downloading/Extracting: " + url.toString()); try (InputStream stream = url.openConnection().getInputStream()) { if (url.getFile().endsWith(".tar.gz")) { extractTarGz(stream, dir); } else { extractZip(stream, dir); } } catch (IOException e) { throw new UncheckedIOException(e); } } private static void log(File file) { Util.getLogger().debug("Extracting: " + file.getAbsolutePath()); } private static void extractTarGz(InputStream stream, File dir) throws IOException { try (TarArchiveInputStream tar = new TarArchiveInputStream(new GzipCompressorInputStream(stream))) { byte[] buffer = new byte[1024]; ArchiveEntry entry = tar.getNextEntry(); while (entry != null) { String fileName = entry.getName(); File newFile = new File(dir, stripFirstComponent(fileName)); if (newFile.getParentFile() != null) { //noinspection ResultOfMethodCallIgnored newFile.getParentFile().mkdirs(); } log(newFile); if (!entry.isDirectory()) { FileOutputStream output = new FileOutputStream(newFile); int len; while ((len = tar.read(buffer)) > 0) { output.write(buffer, 0, len); } output.close(); //noinspection ResultOfMethodCallIgnored newFile.setExecutable(true); } else { //noinspection ResultOfMethodCallIgnored newFile.mkdir(); } entry = tar.getNextEntry(); } } } private static void extractZip(InputStream stream, File dir) throws IOException { try (ZipInputStream zip = new ZipInputStream(stream)) { byte[] buffer = new byte[1024]; ZipEntry entry = zip.getNextEntry(); while (entry != null) { String fileName = entry.getName(); File newFile = new File(dir, stripFirstComponent(fileName)); if (newFile.getParentFile() != null) { //noinspection ResultOfMethodCallIgnored newFile.getParentFile().mkdirs(); } log(newFile); if (!entry.isDirectory()) { FileOutputStream output = new FileOutputStream(newFile); int len; while ((len = zip.read(buffer)) > 0) { output.write(buffer, 0, len); } output.close(); //noinspection ResultOfMethodCallIgnored newFile.setExecutable(true); } else { //noinspection ResultOfMethodCallIgnored newFile.mkdir(); } entry = zip.getNextEntry(); } } } }