/* * Copyright (C) 2014 Brockmann Consult GmbH (info@brockmann-consult.de) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) * any later version. * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see http://www.gnu.org/licenses/ */ package com.bc.ceres.core.runtime.internal; import com.bc.ceres.core.CanceledException; import com.bc.ceres.core.ProgressMonitor; import com.bc.ceres.core.SubProgressMonitor; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLConnection; import java.net.URLDecoder; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.logging.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; public class IOHelper { public static String getBaseName(File archiveFile) { String dirName = archiveFile.getName(); int pos = dirName.lastIndexOf((int) '.'); if (pos > 1) { dirName = dirName.substring(0, pos); } return dirName; } public static String getFileName(URL url) throws UnsupportedEncodingException { return new File(URLDecoder.decode(url.getFile(), "UTF-8")).getName(); } public static void copy(File source, File target, ProgressMonitor pm) throws IOException, CanceledException { try (InputStream inputStream = new BufferedInputStream(new FileInputStream(source)); OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(target))) { String taskName = MessageFormat.format("Copying {0}", source.getName()); int fileSize = (int) Math.max(source.length(), (long) Integer.MAX_VALUE); copy(inputStream, outputStream, taskName, fileSize, pm); } } public static void copy(InputStream inputStream, OutputStream outputStream, String taskName, int fileSize, ProgressMonitor pm) throws IOException, CanceledException { pm.beginTask(taskName, fileSize); try { byte[] buffer = new byte[64 * 1024]; while (true) { checkIOTaskCanceled(pm); int n = inputStream.read(buffer); if (n > 0) { outputStream.write(buffer, 0, n); pm.worked(n); } else if (n < buffer.length) { break; } } } finally { pm.done(); } } private static void checkIOTaskCanceled(ProgressMonitor pm) throws CanceledException { if (pm.isCanceled()) { throw new CanceledException(); } } public static void createDirectory(File dir) throws IOException { if (dir.exists()) { return; } if (!dir.mkdir()) { throw new IOException(MessageFormat.format("Failed to create directory ''{0}''", dir)); } } public static void copy(URLConnection source, File target, ProgressMonitor pm) throws IOException, CanceledException { InputStream inputStream = source.getInputStream(); try { OutputStream outputStream = new FileOutputStream(target); try { String taskName = MessageFormat.format("Downloading {0}", target.getName()); int contentLength = source.getContentLength(); copy(inputStream, outputStream, taskName, contentLength, pm); } finally { outputStream.close(); } } finally { inputStream.close(); } } public static void copy(ZipFile zipFile, ZipEntry source, File target, ProgressMonitor pm) throws IOException, CanceledException { InputStream inputStream = zipFile.getInputStream(source); try { OutputStream outputStream = new FileOutputStream(target); try { String taskName = MessageFormat.format("Unpacking {0}", source.getName()); int fileSize = (int) source.getSize(); copy(inputStream, outputStream, taskName, fileSize, pm); } finally { outputStream.close(); } } finally { inputStream.close(); } } public static List<String> unpack(File sourceZipFile, File targetDir, boolean isNative, ProgressMonitor pm) throws IOException, CanceledException { if (!targetDir.exists()) { targetDir.mkdirs(); } Logger logger = Logger.getLogger(System.getProperty("ceres.context", "ceres")); final Platform platform = isNative ? Platform.getCurrentPlatform() : null; if (platform != null) { logger.info(MessageFormat.format("Archive [{0}]: Detected platform {1}{2}", sourceZipFile, platform.getId(), platform.getBitCount())); } ZipFile zipFile = new ZipFile(sourceZipFile); pm.beginTask(MessageFormat.format("Unpacking {0} to {1}", sourceZipFile.getName(), targetDir.getName()), zipFile.size()); try { ArrayList<String> entries = new ArrayList<String>(zipFile.size()); Enumeration<? extends ZipEntry> enumeration = zipFile.entries(); while (enumeration.hasMoreElements()) { checkIOTaskCanceled(pm); final ZipEntry zipEntry = enumeration.nextElement(); final String entryName = zipEntry.getName(); final File targetFile; if (platform != null && Platform.isAnyPlatformDir(entryName)) { if (platform.isPlatformDir(entryName)) { targetFile = new File(targetDir, platform.truncatePlatformDir(entryName)); logger.info(MessageFormat.format("Archive [{0}]: Unpacking platform dependent entry [{1}]", sourceZipFile, entryName)); } else { targetFile = null; logger.fine(MessageFormat.format("Archive [{0}]: Ignoring platform dependent entry [{1}]", sourceZipFile, entryName)); } } else { targetFile = new File(targetDir, entryName); } if (targetFile != null) { pm.setSubTaskName(entryName); File parentDir = targetFile.getParentFile(); if (parentDir != null) { parentDir.mkdirs(); } if (zipEntry.isDirectory()) { targetFile.mkdir(); pm.worked(1); } else { copy(zipFile, zipEntry, targetFile, SubProgressMonitor.create(pm, 1)); } entries.add(entryName); } } return entries; } finally { pm.done(); zipFile.close(); } } public static List<String> pack(File sourceDir, File targetZipFile, ProgressMonitor pm) throws IOException, CanceledException { if (!sourceDir.exists()) { throw new FileNotFoundException(sourceDir.getPath()); } DirScanner dirScanner = new DirScanner(sourceDir, true, true); String[] entryNames = dirScanner.scan(); ZipOutputStream zipOutputStream = new ZipOutputStream( new BufferedOutputStream(new FileOutputStream(targetZipFile))); zipOutputStream.setMethod(ZipEntry.DEFLATED); pm.beginTask(MessageFormat.format("Packing {0} into {1}", sourceDir.getName(), targetZipFile.getName()), entryNames.length); ArrayList<String> entries = new ArrayList<String>(entryNames.length); try { for (String entryName : entryNames) { checkIOTaskCanceled(pm); ZipEntry zipEntry = new ZipEntry(entryName.replace('\\', '/')); pm.setSubTaskName(entryName); File sourceFile = new File(sourceDir, entryName); try (InputStream inputStream = new BufferedInputStream(new FileInputStream(sourceFile))) { zipOutputStream.putNextEntry(zipEntry); copy(inputStream, zipOutputStream, entryName, (int) sourceFile.length(), SubProgressMonitor.create(pm, 1)); zipOutputStream.closeEntry(); entries.add(entryName); } } return entries; } finally { pm.done(); zipOutputStream.close(); } } }