Example usage for java.util.jar Manifest write

List of usage examples for java.util.jar Manifest write

Introduction

In this page you can find the example usage for java.util.jar Manifest write.

Prototype

public void write(OutputStream out) throws IOException 

Source Link

Document

Writes the Manifest to the specified OutputStream.

Usage

From source file:org.eclipse.licensing.eclipse_licensing_plugin.InjectLicensingMojo.java

private void updateManifest() throws IOException {
    File manifestFile = new File(project.getBasedir(), "META-INF/MANIFEST.MF");
    Manifest manifest = new Manifest(new FileInputStream(manifestFile));
    String[] requiredBundles = manifest.getMainAttributes().getValue("Require-Bundle").split(",");
    List<String> requiredList = new ArrayList<String>(Arrays.asList(requiredBundles));
    requiredList.remove("org.eclipse.licensing.base");
    requiredList.add("org.apache.commons.codec");
    requiredList.add("org.eclipse.osgi");
    String newRequiredBundles = StringUtils.join(requiredList.toArray(), ",");
    manifest.getMainAttributes().putValue("Require-Bundle", newRequiredBundles);
    manifest.write(new FileOutputStream(manifestFile));
}

From source file:org.gradle.api.java.archives.internal.DefaultManifest.java

@Deprecated
@Override/*  w ww. ja  v a 2  s . c  o m*/
public DefaultManifest writeTo(Writer writer) {
    SingleMessageLogger.nagUserOfDeprecated("Manifest.writeTo(Writer)",
            "Please use Manifest.writeTo(Object) instead");
    try {
        Manifest javaManifest = generateJavaManifest(getEffectiveManifest());
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        javaManifest.write(buffer);
        String manifestContent = buffer.toString(DEFAULT_CONTENT_CHARSET);
        if (!DEFAULT_CONTENT_CHARSET.equals(contentCharset)) {
            // Convert the UTF-8 manifest bytes to the requested content charset
            manifestContent = new String(manifestContent.getBytes(contentCharset), contentCharset);
        }
        writer.write(manifestContent);
        writer.flush();
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
    return this;
}

From source file:org.gradle.api.java.archives.internal.DefaultManifest.java

static void writeTo(org.gradle.api.java.archives.Manifest manifest, OutputStream outputStream,
        String contentCharset) {/*  w w w  .j  a  va  2 s  .  com*/
    try {
        Manifest javaManifest = generateJavaManifest(manifest.getEffectiveManifest());
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        javaManifest.write(buffer);
        byte[] manifestBytes;
        if (DEFAULT_CONTENT_CHARSET.equals(contentCharset)) {
            manifestBytes = buffer.toByteArray();
        } else {
            // Convert the UTF-8 manifest bytes to the requested content charset
            manifestBytes = buffer.toString(DEFAULT_CONTENT_CHARSET).getBytes(contentCharset);
        }
        outputStream.write(manifestBytes);
    } catch (IOException e) {
        throw new UncheckedIOException(e);
    }
}

From source file:org.jahia.services.modulemanager.util.ModuleUtils.java

/**
 * Performs the transformation of the capability attributes in the MANIFEST.MF file of the supplied stream.
 *
 * @param sourceStream the source stream for the bundle, which manifest has to be adjusted w.r.t. module dependencies; the stream is
 *            closed after returning from this method
 * @return the transformed stream for the bundle with adjusted manifest
 * @throws IOException in case of I/O errors
 *///from   w  w  w . j  ava  2 s . c  om
public static InputStream addModuleDependencies(InputStream sourceStream) throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();

    try (ZipInputStream zis = new ZipInputStream(sourceStream);
            ZipOutputStream zos = new ZipOutputStream(out);) {
        ZipEntry zipEntry = zis.getNextEntry();
        while (zipEntry != null) {
            zos.putNextEntry(new ZipEntry(zipEntry.getName()));
            if (JarFile.MANIFEST_NAME.equals(zipEntry.getName())) {
                // we read the manifest from the source stream
                Manifest mf = new Manifest();
                mf.read(zis);

                addCapabilities(mf.getMainAttributes());

                // write the manifest entry into the target output stream
                mf.write(zos);
            } else {
                IOUtils.copy(zis, zos);
            }
            zis.closeEntry();
            zipEntry = zis.getNextEntry();
        }
    }

    return new ByteArrayInputStream(out.toByteArray());
}

From source file:org.jahia.utils.maven.plugin.osgi.CheckDependenciesMojo.java

private void updateBundle(Manifest manifest, List<ManifestValueClause> importPackageClauses, File artifactFile,
        String buildDirectory) {/*from  ww  w  . ja  va2 s . c o  m*/
    StringBuilder sb = new StringBuilder();
    String separator = "";
    for (ManifestValueClause importPackageClause : importPackageClauses) {
        sb.append(separator);
        sb.append(importPackageClause.toString());
        separator = ",";
    }
    manifest.getMainAttributes().putValue("Import-Package", sb.toString());
    File expandedJarDirectory = unpackBundle(artifactFile);
    getLog().info("Extract JAR " + artifactFile + " contents to directory " + expandedJarDirectory);
    if (expandedJarDirectory == null) {
        getLog().error("Error unpacking artifact " + artifactFile + " aborting bundle update");
        return;
    }
    File manifestFile = new File(expandedJarDirectory, "META-INF/MANIFEST.MF");
    if (manifestFile.exists()) {
        getLog().info("Overwriting existing META-INF/MANIFEST file");
    } else {
        getLog().warn("Missing META-INF/MANIFEST.MF file in bundle, how did that happen ?");
    }
    FileOutputStream manifestFileOutputStream = null;
    try {
        manifestFileOutputStream = new FileOutputStream(manifestFile);
        manifest.write(manifestFileOutputStream);
    } catch (FileNotFoundException e) {
        getLog().error("Error writing new META-INF/MANIFEST.MF file", e);
        return;
    } catch (IOException e) {
        getLog().error("Error writing new META-INF/MANIFEST.MF file", e);
        return;
    } finally {
        IOUtils.closeQuietly(manifestFileOutputStream);
    }
    packBundle(artifactFile, manifestFile, expandedJarDirectory);

    try {
        FileUtils.deleteDirectory(expandedJarDirectory);
        getLog().info("Deleted temporary JAR extraction directory " + expandedJarDirectory);
    } catch (IOException e) {
        getLog().error("Error purging temporary extracted JAR directory " + expandedJarDirectory, e);
    }

    Artifact mainArtifact = project.getArtifact();

    if ("bundle".equals(mainArtifact.getType())) {
        // workaround for MNG-1682: force maven to install artifact using the "jar" handler
        mainArtifact.setArtifactHandler(artifactHandlerManager.getArtifactHandler("jar"));
    }

    if (null == classifier || classifier.trim().length() == 0) {
        mainArtifact.setFile(artifactFile);
    } else {
        mavenProjectHelper.attachArtifact(project, artifactFile, classifier);
    }

}

From source file:org.jasig.portal.plugin.deployer.AbstractExtractingEarDeployer.java

/**
 * Reads the specified {@link JarEntry} from the {@link JarFile} assuming that the
 * entry represents another a JAR file. The files in the {@link JarEntry} will be
 * extracted using the contextDir as the base directory. 
 * /*www. j  av  a2  s .  co  m*/
 * @param earFile The JarEntry for the JAR to read from the archive.
 * @param earEntry The JarFile to get the {@link InputStream} for the file from.
 * @param contextDir The directory to extract the JAR to.
 * @throws IOException If the extracting of data from the JarEntry fails.
 */
protected void extractWar(JarFile earFile, final JarEntry earEntry, final File contextDir)
        throws MojoFailureException {
    if (this.getLogger().isInfoEnabled()) {
        this.getLogger().info("Extracting EAR entry '" + earFile.getName() + "!" + earEntry.getName() + "' to '"
                + contextDir + "'");
    }

    if (!contextDir.exists()) {
        if (this.getLogger().isDebugEnabled()) {
            this.getLogger().debug("Creating context directory entry '" + contextDir + "'");
        }

        try {
            FileUtils.forceMkdir(contextDir);
        } catch (IOException e) {
            throw new MojoFailureException("Failed to create '" + contextDir + "' to extract '"
                    + earEntry.getName() + "' out of '" + earFile.getName() + "' into", e);
        }
    }

    JarInputStream warInputStream = null;
    try {
        warInputStream = new JarInputStream(earFile.getInputStream(earEntry));

        // Write out the MANIFEST.MF file to the target directory
        Manifest manifest = warInputStream.getManifest();
        if (manifest != null) {
            FileOutputStream manifestFileOutputStream = null;
            try {
                final File manifestFile = new File(contextDir, MANIFEST_PATH);
                manifestFile.getParentFile().mkdirs();
                manifestFileOutputStream = new FileOutputStream(manifestFile);
                manifest.write(manifestFileOutputStream);
            } catch (Exception e) {
                this.getLogger().error("Failed to copy the MANIFEST.MF file for ear entry '"
                        + earEntry.getName() + "' out of '" + earFile.getName() + "'", e);
                throw new MojoFailureException("Failed to copy the MANIFEST.MF file for ear entry '"
                        + earEntry.getName() + "' out of '" + earFile.getName() + "'", e);
            } finally {
                try {
                    if (manifestFileOutputStream != null) {
                        manifestFileOutputStream.close();
                    }
                } catch (Exception e) {
                    this.getLogger().warn("Error closing the OutputStream for MANIFEST.MF in warEntry:  "
                            + earEntry.getName());
                }
            }
        }

        JarEntry warEntry;
        while ((warEntry = warInputStream.getNextJarEntry()) != null) {
            final File warEntryFile = new File(contextDir, warEntry.getName());

            if (warEntry.isDirectory()) {
                if (this.getLogger().isDebugEnabled()) {
                    this.getLogger().debug("Creating WAR directory entry '" + earEntry.getName() + "!"
                            + warEntry.getName() + "' as '" + warEntryFile + "'");
                }

                FileUtils.forceMkdir(warEntryFile);
            } else {
                if (this.getLogger().isDebugEnabled()) {
                    this.getLogger().debug("Extracting WAR entry '" + earEntry.getName() + "!"
                            + warEntry.getName() + "' to '" + warEntryFile + "'");
                }

                FileUtils.forceMkdir(warEntryFile.getParentFile());

                final FileOutputStream jarEntryFileOutputStream = new FileOutputStream(warEntryFile);
                try {
                    IOUtils.copy(warInputStream, jarEntryFileOutputStream);
                } finally {
                    IOUtils.closeQuietly(jarEntryFileOutputStream);
                }
            }
        }
    } catch (IOException e) {
        throw new MojoFailureException("Failed to extract EAR entry '" + earEntry.getName() + "' out of '"
                + earFile.getName() + "' to '" + contextDir + "'", e);
    } finally {
        IOUtils.closeQuietly(warInputStream);
    }
}

From source file:org.jboss.as.test.manualmode.layered.LayeredDistributionTestCase.java

private void buildProductModule(String layer) throws Exception {
    File layerDir = new File(layersDir, layer);
    File moduleDir = new File(layerDir, "org" + File.separator + "jboss" + File.separator + "as"
            + File.separator + "product" + File.separator + "test");
    Assert.assertTrue(moduleDir.mkdirs());
    File moduleXmlFile = new File(moduleDir, "module.xml");
    FileUtils.copyInputStreamToFile(/*www  . ja v  a 2s . com*/
            LayeredDistributionTestCase.class.getResourceAsStream("/layered/product-module.xml"),
            moduleXmlFile);

    File manifestDir = new File(moduleDir, "classes" + File.separator + "META-INF");
    Assert.assertTrue(manifestDir.mkdirs());

    File moduleManifestFile = new File(manifestDir, "MANIFEST.MF");
    Manifest m = new Manifest();
    m.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
    m.getMainAttributes().putValue("JBoss-Product-Release-Name", PRODUCT_NAME);
    m.getMainAttributes().putValue("JBoss-Product-Release-Version", PRODUCT_VERSION);
    OutputStream manifestStream = new BufferedOutputStream(new FileOutputStream(moduleManifestFile));
    m.write(manifestStream);
    manifestStream.flush();
    manifestStream.close();

    // set product.conf        
    File binDir = new File(AS_PATH, "bin");
    Assert.assertTrue(binDir.exists());
    File productConf = new File(binDir, "product.conf");
    if (productConf.exists())
        productConf.delete();
    FileUtils.writeStringToFile(productConf, "slot=test" + System.getProperty("line.separator"));

}

From source file:org.lamport.tla.toolbox.jcloud.PayloadHelper.java

public static Payload appendModel2Jar(final Path modelPath, String mainClass, Properties properties,
        IProgressMonitor monitor) throws IOException {

    /*/*  w  ww .  ja  v  a  2  s.  c  om*/
     * Get the standard tla2tools.jar from the classpath as a blueprint.
     * It's located in the org.lamport.tla.toolbox.jclouds bundle in the
     * files/ directory. It uses OSGi functionality to read files/tla2tools.jar
     * from the .jclouds bundle.
     * The copy of the blueprint will contain the spec & model and 
     * additional metadata (properties, amended manifest).
     */
    final Bundle bundle = FrameworkUtil.getBundle(PayloadHelper.class);
    final URL toolsURL = bundle.getEntry("files/tla2tools.jar");
    if (toolsURL == null) {
        throw new RuntimeException("No tlatools.jar and/or spec to deploy");
    }

    /* 
     * Copy the tla2tools.jar blueprint to a temporary location on
     * disk to append model files below.
     */
    final File tempFile = File.createTempFile("tla2tools", ".jar");
    tempFile.deleteOnExit();
    try (FileOutputStream out = new FileOutputStream(tempFile)) {
        IOUtils.copy(toolsURL.openStream(), out);
    }

    /*
     * Create a virtual filesystem in jar format.
     */
    final Map<String, String> env = new HashMap<>();
    env.put("create", "true");
    final URI uri = URI.create("jar:" + tempFile.toURI());

    try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {
        /*
         * Copy the spec and model into the jar's model/ folder.
         * Also copy any module override (.class file) into the jar.
         */
        try (DirectoryStream<Path> modelDirectoryStream = Files.newDirectoryStream(modelPath,
                "*.{cfg,tla,class}")) {
            for (final Path file : modelDirectoryStream) {
                final Path to = fs.getPath("/model/" + file.getFileName());
                Files.copy(file, to, StandardCopyOption.REPLACE_EXISTING);
            }
        }

        /*
         * Add given class as Main-Class statement to jar's manifest. This
         * causes Java to launch this class when no other Main class is 
         * given on the command line. Thus, it shortens the command line
         * for us.
         */
        final Path manifestPath = fs.getPath("/META-INF/", "MANIFEST.MF");
        final Manifest manifest = new Manifest(Files.newInputStream(manifestPath));
        manifest.getMainAttributes().put(Attributes.Name.MAIN_CLASS, mainClass);
        final PipedOutputStream ps = new PipedOutputStream();
        final PipedInputStream is = new PipedInputStream(ps);
        manifest.write(ps);
        ps.close();
        Files.copy(is, manifestPath, StandardCopyOption.REPLACE_EXISTING);

        /*
         * Add properties file to archive. The property file contains the
         * result email address... from where TLC eventually reads it.
         */

        // On Windows 7 and above the file has to be created in the system's
        // temp folder. Otherwise except file creation to fail with a
        // AccessDeniedException
        final File f = File.createTempFile("generated", "properties");
        OutputStream out = new FileOutputStream(f);
        // Append all entries in "properties" to the temp file f
        properties.store(out, "This is an optional header comment string");
        // Copy the temp file f into the jar with path /model/generated.properties.
        final Path to = fs.getPath("/model/generated.properties");
        Files.copy(f.toPath(), to, StandardCopyOption.REPLACE_EXISTING);
    } catch (final IOException e1) {
        throw new RuntimeException("No model directory found to deploy", e1);
    }

    /*
     * Compress archive with pack200 to achieve a much higher compression rate. We
     * are going to send the file on the wire after all:
     * 
     * effort: take more time choosing codings for better compression segment: use
     * largest-possible archive segments (>10% better compression) mod time: smear
     * modification times to a single value deflate: ignore all JAR deflation hints
     * in original archive
     */
    final Packer packer = Pack200.newPacker();
    final Map<String, String> p = packer.properties();
    p.put(Packer.EFFORT, "9");
    p.put(Packer.SEGMENT_LIMIT, "-1");
    p.put(Packer.MODIFICATION_TIME, Packer.LATEST);
    p.put(Packer.DEFLATE_HINT, Packer.FALSE);

    // Do not reorder which changes package names. Pkg name changes e.g. break
    // SimpleFilenameToStream.
    p.put(Packer.KEEP_FILE_ORDER, Packer.TRUE);

    // Throw an error if any of the above attributes is unrecognized.
    p.put(Packer.UNKNOWN_ATTRIBUTE, Packer.ERROR);

    final File packTempFile = File.createTempFile("tla2tools", ".pack.gz");
    try (final JarFile jarFile = new JarFile(tempFile);
            final GZIPOutputStream fos = new GZIPOutputStream(new FileOutputStream(packTempFile));) {
        packer.pack(jarFile, fos);
    } catch (IOException ioe) {
        throw new RuntimeException("Failed to pack200 the tla2tools.jar file", ioe);
    }

    /*
     * Convert the customized tla2tools.jar into a jClouds payload object. This is
     * the format it will be transfered on the wire. This is handled by jClouds
     * though.
     */
    Payload jarPayLoad = null;
    try {
        final InputStream openStream = new FileInputStream(packTempFile);
        jarPayLoad = Payloads.newInputStreamPayload(openStream);
        // manually set length of content to prevent a NPE bug
        jarPayLoad.getContentMetadata().setContentLength(Long.valueOf(openStream.available()));
    } catch (final IOException e1) {
        throw new RuntimeException("No tlatools.jar to deploy", e1);
    } finally {
        monitor.worked(5);
    }

    return jarPayLoad;
}

From source file:org.moe.cli.executor.AbstractLinkExecutor.java

@Override
public void execute() throws IOException, URISyntaxException, InterruptedException, CheckArchitectureException,
        UnsupportedTypeException {/* w  w  w.j  a  v a  2s  .  co  m*/

    //collect all header files
    List<String> headerList = new ArrayList<String>();
    if (headers != null) {
        for (String header : headers) {
            if (header != null && !header.isEmpty()) {
                File tmp = new File(header);
                if (tmp.isDirectory()) {
                    Collection<File> files = FileUtils.listFiles(tmp, new String[] { "h" }, true);
                    for (File file : files)
                        headerList.add(file.getAbsolutePath());
                } else {
                    headerList.add(header);
                }
            }
        }
    }

    List<String> frameworkList = new ArrayList<String>();
    Set<String> frameworksSearchPaths = new HashSet<String>();
    if (frameworks != null) {

        for (String framework : frameworks) {
            frameworkList.add(framework);
            File frFile = new File(framework);
            frameworksSearchPaths.add(frFile.getParent());
        }

    }

    // Initialize native libraries
    NatJGenNativeLoader.initNatives();

    // Read arguments
    MOEJavaProject project = new MOEJavaProject("", "/");

    boolean generated = true;
    File tmpDir = NatJFileUtils.getNewTempDirectory();
    if (javaSource == null) {

        //generate bindings for all frameworks
        String natJGenBody = NatjGenFrameworkConfig.generate(packageName, frameworksSearchPaths,
                tmpDir.getPath(), headerList);

        //generate bindings
        generated = generate(project, natJGenBody);
    } else {

        Set<URI> links = new HashSet<URI>();
        for (String jsource : javaSource) {
            links.add(new URI(jsource));
        }
        GrabUtils.downloadToFolder(links, tmpDir);
    }

    if (generated) {
        //try to compile generated jars
        File destinationJavacDir = new File(tmpDir, "result");
        destinationJavacDir.mkdir();

        String indePath = System.getenv("MOE_HOME");
        if (indePath != null && !indePath.isEmpty()) {
            String coreJar = indePath + File.separator + "sdk" + File.separator + "moe-core.jar";
            String iosJar = indePath + File.separator + "sdk" + File.separator + "moe-ios.jar";

            String compileList = createCompileFileList(tmpDir, javaSource != null ? null : packageName);

            String classPathArg = String.format("%s:%s", coreJar, iosJar);
            ProcessBuilder processBuilder = new ProcessBuilder("javac", "@" + compileList, "-cp", classPathArg,
                    "-d", destinationJavacDir.getPath());
            Process process = processBuilder.start();
            process.waitFor();

            if (process.exitValue() == 0 || headerList.size() == 0) {
                //try to create lib subdirectory
                File libTemp = new File(destinationJavacDir, "lib");
                if (!(libTemp.mkdir())) {
                    throw new IOException("Could not create temp directory: " + libTemp.getAbsolutePath());
                }

                //try to create bundle subdirectory
                File bundleTemp = new File(destinationJavacDir, "bundle");
                if (!(bundleTemp.mkdir())) {
                    throw new IOException("Could not create temp directory: " + bundleTemp.getAbsolutePath());
                }

                copyLibrary(libTemp, frameworkList);

                if (bundle != null) {
                    copyBundle(bundleTemp, bundle);
                }

                Map<String, String> flags = getManifestProperties(frameworkList);

                //create manifest file
                Manifest manifest = new Manifest();
                manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");

                //Logic from CocoaPods; for more information visit https://github.com/CocoaPods/CocoaPods/issues/3537
                String moe_type = flags.get(MOE_TYPE);
                if (moe_type != null && moe_type.contains("static")) {
                    if (ldFlags != null && !ldFlags.isEmpty()) {
                        if (ldFlags.endsWith(";"))
                            ldFlags += "-ObjC;";
                        else
                            ldFlags += ";-ObjC;";
                    } else {
                        ldFlags = "-ObjC;";
                    }
                }

                if (ldFlags != null && !ldFlags.isEmpty()) {
                    flags.put("MOE_CUSTOM_LINKER_FLAGS", ldFlags);
                }

                for (Map.Entry<String, String> entry : flags.entrySet()) {
                    manifest.getMainAttributes().put(new Attributes.Name(entry.getKey()), entry.getValue());
                }

                //try to create manifest subdirectory
                File manifestTemp = new File(destinationJavacDir, "META-INF");
                if (!(manifestTemp.mkdir())) {
                    throw new IOException("Could not create temp directory: " + bundleTemp.getAbsolutePath());
                }

                String manifestFileName = "MANIFEST.MF";
                File manifestFile = new File(manifestTemp, manifestFileName);
                FileOutputStream manOut = new FileOutputStream(manifestFile);
                manifest.write(manOut);
                manOut.close();

                //try to pack custom content into jar
                File jarFile = new File(outFile);

                FileOutputStream jarFos = null;
                JarArchiveOutputStream target = null;
                try {
                    jarFos = new FileOutputStream(jarFile);
                    target = new JarArchiveOutputStream(jarFos);

                    for (File file : destinationJavacDir.listFiles()) {
                        ArchiveUtils.addFileToJar(destinationJavacDir, file, target);
                    }
                    target.close();

                } finally {
                    if (jarFos != null) {
                        jarFos.close();
                    }

                    if (target != null) {
                        target.close();
                    }
                }
            } else {
                throw new IOException("An error occured during process of bindings compilation");
            }
        } else {
            throw new IOException("Could not find system variable - MOE_HOME");
        }
    } else {
        throw new IOException("An error occured during process of bindings generation");
    }

}

From source file:org.ngrinder.common.util.CompressionUtil.java

/**
 * Unpack the given jar file./*w ww.j  av  a 2 s. c o  m*/
 * 
 * @param jarFile
 *            file to be uncompressed
 * @param destDir
 *            destination directory
 * @throws IOException
 *             occurs when IO has a problem.
 */
public static void unjar(File jarFile, String destDir) throws IOException {
    File dest = new File(destDir);
    if (!dest.exists()) {
        dest.mkdirs();
    }
    if (!dest.isDirectory()) {
        LOGGER.error("Destination must be a directory.");
        throw new IOException("Destination must be a directory.");
    }
    JarInputStream jin = new JarInputStream(new FileInputStream(jarFile));
    byte[] buffer = new byte[1024];

    ZipEntry entry = jin.getNextEntry();
    while (entry != null) {
        String fileName = entry.getName();
        if (fileName.charAt(fileName.length() - 1) == '/') {
            fileName = fileName.substring(0, fileName.length() - 1);
        }
        if (fileName.charAt(0) == '/') {
            fileName = fileName.substring(1);
        }
        if (File.separatorChar != '/') {
            fileName = fileName.replace('/', File.separatorChar);
        }
        File file = new File(dest, fileName);
        if (entry.isDirectory()) {
            // make sure the directory exists
            file.mkdirs();
            jin.closeEntry();
        } else {
            // make sure the directory exists
            File parent = file.getParentFile();
            if (parent != null && !parent.exists()) {
                parent.mkdirs();
            }

            // dump the file
            OutputStream out = new FileOutputStream(file);
            int len = 0;
            while ((len = jin.read(buffer, 0, buffer.length)) != -1) {
                out.write(buffer, 0, len);
            }
            out.flush();
            IOUtils.closeQuietly(out);
            jin.closeEntry();
            file.setLastModified(entry.getTime());
        }
        entry = jin.getNextEntry();
    }
    Manifest mf = jin.getManifest();
    if (mf != null) {
        File file = new File(dest, "META-INF/MANIFEST.MF");
        File parent = file.getParentFile();
        if (!parent.exists()) {
            parent.mkdirs();
        }
        OutputStream out = new FileOutputStream(file);
        mf.write(out);
        out.flush();
        IOUtils.closeQuietly(out);
    }
    IOUtils.closeQuietly(jin);
}