/******************************************************************************* * Copyright 2014 Rafael Garcia Moreno. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package com.bladecoder.engineeditor.common; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.zip.Deflater; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; public class ZipUtils { // 4MB buffer private static final byte[] BUFFER = new byte[4096 * 1024]; // copy input to output stream private static void copy(InputStream input, OutputStream output) throws IOException { int bytesRead; while ((bytesRead = input.read(BUFFER)) != -1) { output.write(BUFFER, 0, bytesRead); } } public static void mergeZIPs(String f[], String dest) throws Exception { // Needed to avoid appending repeated entries. HashMap<String, String> destEntries = new HashMap<String, String>(); // read the org zips ZipFile fZip[] = new ZipFile[f.length]; for (int i = 0; i < fZip.length; i++) fZip[i] = new ZipFile(f[i]); // write the dest zip ZipOutputStream destZip = new ZipOutputStream(new FileOutputStream(dest)); // copy contents from f zip to the dest zip for (ZipFile z : fZip) { Enumeration<? extends ZipEntry> entries = z.entries(); while (entries.hasMoreElements()) { ZipEntry e = entries.nextElement(); String name = e.getName(); if (destEntries.get(name) == null) { destEntries.put(name, name); EditorLogger.debug("copy: " + e.getName()); destZip.putNextEntry(e); EditorLogger.debug("putnextEntry done"); if (!e.isDirectory()) { copy(z.getInputStream(e), destZip); } destZip.closeEntry(); } } } EditorLogger.debug("appending done "); // close for (ZipFile z : fZip) { z.close(); } destZip.close(); } public static void packZip(List<File> sources, File output) throws IOException { EditorLogger.debug("Packaging to " + output.getName()); ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(output)); zipOut.setLevel(Deflater.DEFAULT_COMPRESSION); for (File source : sources) { if (source.isDirectory()) { zipDir(zipOut, "", source); } else { zipFile(zipOut, "", source); } } zipOut.flush(); zipOut.close(); EditorLogger.debug("Done"); } private static String buildPath(String path, String file) { if (path == null || path.isEmpty()) { return file; } else { return path + "/" + file; } } private static void zipDir(ZipOutputStream zos, String path, File dir) throws IOException { if (!dir.canRead()) { EditorLogger.error("Cannot read " + dir.getCanonicalPath() + " (maybe because of permissions)"); return; } File[] files = dir.listFiles(); path = buildPath(path, dir.getName()); EditorLogger.debug("Adding Directory " + path); for (File source : files) { if (source.isDirectory()) { zipDir(zos, path, source); } else { zipFile(zos, path, source); } } EditorLogger.debug("Leaving Directory " + path); } private static void zipFile(ZipOutputStream zos, String path, File file) throws IOException { if (!file.canRead()) { EditorLogger.error("Cannot read " + file.getCanonicalPath() + " (maybe because of permissions)"); return; } EditorLogger.debug("Compressing " + file.getName()); zos.putNextEntry(new ZipEntry(buildPath(path, file.getName()))); FileInputStream fis = new FileInputStream(file); byte[] buffer = new byte[4092]; int byteCount = 0; while ((byteCount = fis.read(buffer)) != -1) { zos.write(buffer, 0, byteCount); } fis.close(); zos.closeEntry(); } }