Index: lutinutil/src/java/org/codelutin/util/ZipUtil.java diff -u lutinutil/src/java/org/codelutin/util/ZipUtil.java:1.5 lutinutil/src/java/org/codelutin/util/ZipUtil.java:1.6 --- lutinutil/src/java/org/codelutin/util/ZipUtil.java:1.5 Wed Apr 25 13:42:43 2007 +++ lutinutil/src/java/org/codelutin/util/ZipUtil.java Mon Nov 12 22:50:34 2007 @@ -23,10 +23,10 @@ * Created: 24 août 2006 10:13:35 * * @author poussin - * @version $Revision: 1.5 $ + * @version $Revision: 1.6 $ * - * Last update: $Date: 2007-04-25 13:42:43 $ - * by : $Author: bpoussin $ + * Last update: $Date: 2007-11-12 22:50:34 $ + * by : $Author: tchemit $ */ package org.codelutin.util; @@ -42,9 +42,11 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Enumeration; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; +import java.util.zip.ZipFile; import org.apache.commons.logging.LogFactory; @@ -62,6 +64,17 @@ /** Taille du buffer pour les lectures/écritures */ private static final int BUFFER_SIZE = 8 * 1024; + /** le séparateur de fichier en local */ + private static final String LOCAL_SEP = File.separator; + + private static final String LOCAL_SEP_PATTERN = "\\".equals(LOCAL_SEP) ? + LOCAL_SEP + LOCAL_SEP : LOCAL_SEP; + + /** le séparateur zip */ + private static final String ZIP_SEP = "/"; + + private static final String ZIP_SEP_PATTERN = "/"; + static private FileFilter ALL_FILE_FILTER = new FileFilter() { public boolean accept(File pathname) { return true; @@ -73,7 +86,7 @@ * uncompress zipped file in targetDir * * @param file - * @param regionDirectory + * @param targetDir * @return return last entry name * @throws IOException */ @@ -90,7 +103,7 @@ * each directory ended with / * * @param file - * @param regionDirectory + * @param targetDir * @param renameFrom pattern to permit rename file before uncompress it * @param renameTo new name for file if renameFrom is applicable to it * you can use $1, $2, ... if you have '(' ')' in renameFrom @@ -222,7 +235,124 @@ } return result; } - + + /** + * Scan a zipFile, and fill two lists of relative paths corresponding of + * zip entries. + * First list contains all entries to be added while a uncompress operation + * on the destination directory targetDir. + * Second list contains all entries to be overwritten while a uncompress + * operation on the destination directory targetDir. + *
+ * If targetDir is null we don't fill + * existingFiles list. + * + * @param zipFile location of the zip to scanZip + * @param targetDir location of destination for a uncompress operation. + * If null we don't test to + * find overwritten files. + * @param newFiles list of files to be added while a uncompress + * @param existingFiles list of files to be overwritten while a uncompress + * if the targetDir, + * (only use if targetDir is not + * null) + * @param excludeFilter used to exclude some files + * @throws IOException if any exception while dealing with zipfile + */ + public static void scan(File zipFile, File targetDir, List newFiles, + List existingFiles, FileFilter excludeFilter) + throws IOException { + ZipFile zip = null; + try { + zip = new ZipFile(zipFile); + boolean findExisting = targetDir != null && targetDir.exists(); + boolean filter = findExisting && excludeFilter != null; + Enumeration entries = zip.entries(); + while (entries.hasMoreElements()) { + String name = convertToLocalEntryName( + entries.nextElement().getName()); + if (findExisting || filter) { + File file = new File(targetDir, name); + if (filter && excludeFilter.accept(file)) continue; + if (file.exists()) { + existingFiles.add(name); + continue; + } + } + newFiles.add(name); + } + } finally { + if (zip != null) zip.close(); + } + } + + /** + * uncompress zipped file in targetDir. + *

+ * If toTreate if not null nor empty, we use it to filter + * entries to uncompress : it contains a list of relative local path of + * files to uncompress. + * Otherwise just delegate to {@link ZipUtil#uncompress(File,File)}. + * + * @param file location of zip file + * @param targetDir destination directory + * @param toTreate list of relative local path of entries to treate + * @return return last entry name + * @throws IOException if nay exception while operation + */ + public static String uncompress(File file, File targetDir, + List toTreate) throws IOException { + String result = ""; + ZipInputStream in = new ZipInputStream(new FileInputStream(file)); + ZipEntry entry; + if (toTreate == null || toTreate.isEmpty()) + return ZipUtil.uncompress(file, targetDir); + + while ((entry = in.getNextEntry()) != null) { + String name = entry.getName(); + result = convertToLocalEntryName(name); + + log.debug("open [" + name + "] : " + result); + if (!toTreate.contains(result)) continue; + + + log.debug("copy [" + name + "] : " + result); + File target = new File(targetDir, name); + if (entry.isDirectory()) { + target.mkdirs(); + } else { + target.getParentFile().mkdirs(); + OutputStream out = + new BufferedOutputStream(new FileOutputStream(target)); + byte[] buffer = new byte[BUFFER_SIZE]; + int len; + while ((len = in.read(buffer, 0, BUFFER_SIZE)) != -1) { + out.write(buffer, 0, len); + } + out.close(); + } + } + in.close(); + return result; + } + + public static String convertToZipEntryName(String txt, boolean isDir) { + String s = txt.replaceAll(LOCAL_SEP_PATTERN, ZIP_SEP); + while (s.startsWith(ZIP_SEP)) { + s = s.substring(1); + } + return s + (isDir ? ZIP_SEP : ""); + } + + public static String convertToLocalEntryName(String txt) { + String s = txt.replaceAll(ZIP_SEP_PATTERN, LOCAL_SEP_PATTERN); + if (s.endsWith(ZIP_SEP)) { + s = s.substring(0, s.length() - 1); + } + return s; + } + + }