Package org.jboss.arquillian.container.common

Source Code of org.jboss.arquillian.container.common.FixedExplodedExporter

package org.jboss.arquillian.container.common;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.jboss.shrinkwrap.api.Archive;
import org.jboss.shrinkwrap.api.ArchivePath;
import org.jboss.shrinkwrap.api.ArchivePaths;
import org.jboss.shrinkwrap.api.Node;
import org.jboss.shrinkwrap.api.asset.ArchiveAsset;

/**
* This is a rip-off from ExplodedExporterDelegate. ;-)
*/
class FixedExplodedExporter {
    private static final Logger log = Logger.getLogger(FixedExplodedExporter.class.getName());

    private Archive archive;
    private File outputDirectory;
    private boolean explodeWars = true;

    FixedExplodedExporter(Archive archive, File root) {
        this.archive = archive;
        this.outputDirectory = initializeOutputDirectory(root, archive.getName());
    }

    void setExplodeWars(boolean explodeWars) {
        this.explodeWars = explodeWars;
    }

    File export() {
        doExport();
        return outputDirectory;
    }

    protected void doExport() {
        if (log.isLoggable(Level.FINE)) {
            log.fine("Exporting archive - " + archive.getName());
        }

        processArchive("", archive);
    }

    protected void processArchive(String relativePath, Archive archive) {
        // Obtain the root
        final Node rootNode = archive.get(ArchivePaths.root());

        // Recursively process the root children
        for (Node child : rootNode.getChildren()) {
            processNode(relativePath, child);
        }
    }

    protected boolean isWar(Node node) {
        return (node.getPath().get().endsWith(".war"));
    }

    /**
     * Recursive call to process all the node hierarchy
     *
     * @param node the node
     */
    protected void processNode(final String relativePath, final Node node) {
        final boolean isDirectory = (node.getAsset() == null);
        final boolean explodeWar = explodeWars && isWar(node);

        final ArchivePath path = node.getPath();
        processNode(relativePath, path, node, isDirectory || explodeWar);

        if (explodeWar) {
            ArchiveAsset war = (ArchiveAsset) node.getAsset();
            processArchive(relativePath + path.get(), war.getArchive());
        } else {
            Set<Node> children = node.getChildren();
            for (Node child : children) {
                processNode(relativePath, child);
            }
        }
    }

    protected void processNode(String relativePath, ArchivePath path, Node node, boolean isDirectory) {
        // Get path to file
        final String assetFilePath = path.get();

        // Create a file for the asset
        final File assetFile = new File(outputDirectory, relativePath + assetFilePath);

        // Get the assets parent parent directory and make sure it exists
        final File assetParent = assetFile.getParentFile();
        if (!assetParent.exists()) {
            if (!assetParent.mkdirs()) {
                throw new IllegalArgumentException("Failed to write asset.  Unable to create parent directory.");
            }
        }

        // Handle directory and inner .war assets separately
        try {
            if (isDirectory) {
                // If doesn't already exist
                if (!assetFile.exists()) {
                    // Attempt a create
                    if (!assetFile.mkdirs()) {
                        // Some error in writing
                        throw new IllegalArgumentException("Failed to write directory: " + assetFile.getAbsolutePath());
                    }
                }
            }
            // Only handle non-directory assets, otherwise the path is handled above
            else {
                try {
                    if (log.isLoggable(Level.FINE)) {
                        log.fine("Writing asset " + path.get() + " to " + assetFile.getAbsolutePath());
                    }
                    // Get the asset streams
                    final InputStream assetInputStream = node.getAsset().openStream();
                    final FileOutputStream assetFileOutputStream = new FileOutputStream(assetFile);
                    final BufferedOutputStream assetBufferedOutputStream = new BufferedOutputStream(assetFileOutputStream, 8192);
                    // Write contents
                    copyWithClose(assetInputStream, assetBufferedOutputStream);
                } catch (final Exception e) {
                    // Provide a more detailed exception than the outer block
                    throw new IllegalArgumentException("Failed to write asset " + path + " to " + assetFile, e);
                }
            }
        } catch (final RuntimeException e) {
            throw e;
        } catch (final Exception e) {
            throw new IllegalArgumentException("Unexpected error encountered in export of " + node, e);
        }
    }

    private File initializeOutputDirectory(File baseDirectory, String directoryName) {
        // Create output directory
        final File outputDirectory = new File(baseDirectory, directoryName);

        boolean mkdirs = outputDirectory.mkdirs();
        boolean exists = outputDirectory.exists();
        if (!mkdirs && !exists) {
            throw new IllegalArgumentException(String.format("Unable to create archive output directory - %s [%s, %s]", outputDirectory, mkdirs, exists));
        }

        if (outputDirectory.isFile()) {
            throw new IllegalArgumentException(String.format("Unable to export exploded directory to %s, it points to an existing file", outputDirectory.getAbsolutePath()));
        }

        return outputDirectory;
    }

    private static void copy(InputStream input, OutputStream output) throws IOException {
        final byte[] buffer = new byte[4096];
        int read;
        while ((read = input.read(buffer)) != -1) {
            output.write(buffer, 0, read);
        }
        output.flush();
    }

    private static void copyWithClose(InputStream input, OutputStream output) throws IOException {
        try {
            copy(input, output);
        } finally {
            try {
                input.close();
            } catch (final IOException ignore) {
                if (log.isLoggable(Level.FINER)) {
                    log.finer("Could not close stream due to: " + ignore.getMessage() + "; ignoring");
                }
            }
            try {
                output.close();
            } catch (final IOException ignore) {
                if (log.isLoggable(Level.FINER)) {
                    log.finer("Could not close stream due to: " + ignore.getMessage() + "; ignoring");
                }
            }
        }
    }
}
TOP

Related Classes of org.jboss.arquillian.container.common.FixedExplodedExporter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.