Mega Code Archive

 
Categories / Java / File Input Output
 

Writes all files of the given directory to the specified jar-file

//package com.qlogic.commons.utils.io; 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.util.Enumeration; import java.util.HashMap; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; import java.util.zip.CRC32; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; public final class JarUtil {   private final static boolean IS_WINDOWS = (File.separatorChar == '\\');   /**    * Writes all files of the given directory to the specified jar-file.    *     * @param sourceDir    *            The directory containing the "source" files.    * @param target    *            The jar file which should be created    * @param compress    *            True when the jar file should be compressed    * @throws FileNotFoundException    *             when a file could not be found    * @throws IOException    *             when a file could not be read or the jar file could not be    *             written to.    */   public static void jar(File sourceDir, File target, boolean compress)       throws IOException {     jar(sourceDir, target, compress);   }   /**    * Writes all given files to the specified jar-file.    *     * @param files    *            all files that should be added to the JAR file    * @param sourceDir    *            The parent directory containing the given files.    * @param target    *            The jar file which should be created    * @param compress    *            True when the jar file should be compressed    * @throws FileNotFoundException    *             when a file could not be found    * @throws IOException    *             when a file could not be read or the jar file could not be    *             written to.    */   public static void jar(File sourceDir, OutputStream target,       boolean compress) throws IOException {     File[] files = sourceDir.listFiles ();     // creates target-jar-file:     JarOutputStream out = new JarOutputStream(target);     if (compress) {       out.setLevel(ZipOutputStream.DEFLATED);     } else {       out.setLevel(ZipOutputStream.STORED);     }     // create a CRC32 object:     CRC32 crc = new CRC32();     byte[] buffer = new byte[1024 * 1024];     // add all files:     int sourceDirLength = sourceDir.getAbsolutePath().length() + 1;     for (File file : files) {       addFile(file, out, crc, sourceDirLength, buffer);     }     out.close();   }   /**    * Adds one file to the given jar file. If the specified file is a    * directory, all included files will be added.    *     * @param file    *            The file which should be added    * @param out    *            The jar file to which the given jar file should be added    * @param crc    *            A helper class for the CRC32 calculation    * @param sourceDirLength    *            The number of chars which can be skipped from the file's path    * @param buffer    *            A buffer for reading the files.    * @throws FileNotFoundException    *             when the file was not found    * @throws IOException    *             when the file could not be read or not be added    */   private static void addFile(File file, JarOutputStream out, CRC32 crc,       int sourceDirLength, byte[] buffer) throws FileNotFoundException,       IOException {     if (file.isDirectory()) {       File[] fileNames = file.listFiles();       for (int i = 0; i < fileNames.length; i++) {         addFile(fileNames[i], out, crc, sourceDirLength, buffer);       }     } else {       String entryName = file.getAbsolutePath().substring(sourceDirLength);       if (IS_WINDOWS) {         entryName = entryName.replace('\\', '/');       }       JarEntry entry = new JarEntry(entryName);       // read file:       FileInputStream in = new FileInputStream(file);       add(entry, in, out, crc, buffer);     }   }   /**    * @param entry    * @param in    * @param out    * @param crc    * @param buffer    * @throws IOException    */   private static void add(JarEntry entry, InputStream in,       JarOutputStream out, CRC32 crc, byte[] buffer) throws IOException {     out.putNextEntry(entry);     int read;     long size = 0;     while ((read = in.read(buffer)) != -1) {       crc.update(buffer, 0, read);       out.write(buffer, 0, read);       size += read;     }     entry.setCrc(crc.getValue());     entry.setSize(size);     in.close();     out.closeEntry();     crc.reset();   }   /**    * Adds the given file to the specified JAR file.    *     * @param file    *            the file that should be added    * @param jarFile    *            The JAR to which the file should be added    * @param parentDir    *            the parent directory of the file, this is used to calculate    *            the path witin the JAR file. When null is given, the file will    *            be added into the root of the JAR.    * @param compress    *            True when the jar file should be compressed    * @throws FileNotFoundException    *             when the jarFile does not exist    * @throws IOException    *             when a file could not be written or the jar-file could not    *             read.    */   public static void addToJar(File file, File jarFile, File parentDir,       boolean compress) throws FileNotFoundException, IOException {     File tmpJarFile = File.createTempFile("tmp", ".jar", jarFile         .getParentFile());     JarOutputStream out = new JarOutputStream(new FileOutputStream(         tmpJarFile));     if (compress) {       out.setLevel(ZipOutputStream.DEFLATED);     } else {       out.setLevel(ZipOutputStream.STORED);     }     // copy contents of old jar to new jar:     JarFile inputFile = new JarFile(jarFile);     JarInputStream in = new JarInputStream(new FileInputStream(jarFile));     CRC32 crc = new CRC32();     byte[] buffer = new byte[512 * 1024];     JarEntry entry = (JarEntry) in.getNextEntry();     while (entry != null) {       InputStream entryIn = inputFile.getInputStream(entry);       add(entry, entryIn, out, crc, buffer);       entryIn.close();       entry = (JarEntry) in.getNextEntry();     }     in.close();     inputFile.close();     int sourceDirLength;     if (parentDir == null) {       sourceDirLength = file.getAbsolutePath().lastIndexOf(           File.separatorChar) + 1;     } else {       sourceDirLength = file.getAbsolutePath().lastIndexOf(           File.separatorChar)           + 1 - parentDir.getAbsolutePath().length();     }     addFile(file, out, crc, sourceDirLength, buffer);     out.close();     // remove old jar file and rename temp file to old one:     if (jarFile.delete()) {       if (!tmpJarFile.renameTo(jarFile)) {         throw new IOException(             "Unable to rename temporary JAR file to ["                 + jarFile.getAbsolutePath() + "].");       }     } else {       throw new IOException("Unable to delete old JAR file ["           + jarFile.getAbsolutePath() + "].");     }   }   /**    * Extracts the given jar-file to the specified directory. The target    * directory will be cleaned before the jar-file will be extracted.    *     * @param jarFile    *            The jar file which should be unpacked    * @param targetDir    *            The directory to which the jar-content should be extracted.    * @throws FileNotFoundException    *             when the jarFile does not exist    * @throws IOException    *             when a file could not be written or the jar-file could not    *             read.    */   public static void unjar(File jarFile, File targetDir)       throws FileNotFoundException, IOException {     // clear target directory:     if (targetDir.exists()) {       targetDir.delete();     }     // create new target directory:     targetDir.mkdirs();     // read jar-file:     String targetPath = targetDir.getAbsolutePath() + File.separatorChar;     byte[] buffer = new byte[1024 * 1024];     JarFile input = new JarFile(jarFile, false, ZipFile.OPEN_READ);     Enumeration<JarEntry> enumeration = input.entries();     for (; enumeration.hasMoreElements();) {       JarEntry entry = enumeration.nextElement();       if (!entry.isDirectory()) {         // do not copy anything from the package cache:         if (entry.getName().indexOf("package cache") == -1) {           String path = targetPath + entry.getName();           File file = new File(path);           if (!file.getParentFile().exists()) {             file.getParentFile().mkdirs();           }           FileOutputStream out = new FileOutputStream(file);           InputStream in = input.getInputStream(entry);           int read;           while ((read = in.read(buffer)) != -1) {             out.write(buffer, 0, read);           }           in.close();           out.close();         }       }     }   }   /**    * Extracts the given resource from a jar-file to the specified directory.    *     * @param jarFile    *            The jar file which should be unpacked    * @param resource    *            The name of a resource in the jar    * @param targetDir    *            The directory to which the jar-content should be extracted.    * @throws FileNotFoundException    *             when the jarFile does not exist    * @throws IOException    *             when a file could not be written or the jar-file could not    *             read.    */   public static void unjar(File jarFile, String resource, File targetDir)       throws FileNotFoundException, IOException {     // clear target directory:     if (targetDir.exists()) {       targetDir.delete();     }     // create new target directory:     targetDir.mkdirs();     // read jar-file:     String targetPath = targetDir.getAbsolutePath() + File.separatorChar;     byte[] buffer = new byte[1024 * 1024];     JarFile input = new JarFile(jarFile, false, ZipFile.OPEN_READ);     Enumeration<JarEntry> enumeration = input.entries();     for (; enumeration.hasMoreElements();) {       JarEntry entry = enumeration.nextElement();       if (!entry.isDirectory()) {         // do not copy anything from the package cache:         if (entry.getName().equals(resource)) {           String path = targetPath + entry.getName();           File file = new File(path);           if (!file.getParentFile().exists()) {             file.getParentFile().mkdirs();           }           FileOutputStream out = new FileOutputStream(file);           InputStream in = input.getInputStream(entry);           int read;           while ((read = in.read(buffer)) != -1) {             out.write(buffer, 0, read);           }           in.close();           out.close();         }       }     }   }   /**    * Reads the package-names from the given jar-file.    *     * @param jarFile    *            the jar file    * @return an array with all found package-names    * @throws IOException    *             when the jar-file could not be read    */   public static String[] getPackageNames(File jarFile) throws IOException {     HashMap<String, String> packageNames = new HashMap<String, String> ();     JarFile input = new JarFile(jarFile, false, ZipFile.OPEN_READ);     Enumeration<JarEntry> enumeration = input.entries();     for (; enumeration.hasMoreElements();) {       JarEntry entry = enumeration.nextElement();       String name = entry.getName();       if (name.endsWith(".class")) {         int endPos = name.lastIndexOf('/');         boolean isWindows = false;         if (endPos == -1) {           endPos = name.lastIndexOf('\\');           isWindows = true;         }         name = name.substring(0, endPos);         name = name.replace('/', '.');         if (isWindows) {           name = name.replace('\\', '.');         }         packageNames.put(name, name);       }     }     return (String[]) packageNames.values().toArray(         new String[packageNames.size()]);   } }