org.overlord.sramp.atom.archive.expand.ZipToSrampArchive.java Source code

Java tutorial

Introduction

Here is the source code for org.overlord.sramp.atom.archive.expand.ZipToSrampArchive.java

Source

/*
 * Copyright 2012 JBoss Inc
 *
 * 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 org.overlord.sramp.atom.archive.expand;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.oasis_open.docs.s_ramp.ns.s_ramp_v1.BaseArtifactType;
import org.overlord.sramp.atom.archive.ArchiveUtils;
import org.overlord.sramp.atom.archive.SrampArchive;

/**
 * Class that converts a JAR into an S-RAMP archive.
 *
 * This class performs the following tasks:
 *
 * <ul>
 *   <li>Crack open the JAR (or EAR, WAR, etc)</li>
 *   <li>Locate and index all S-RAMP artifacts</li>
 *   <li>Generate meta-data for all located artifacts</li>
 *   <li>Discover and record relationships between artifacts</li>
 *   <li>Create a new S-RAMP archive that includes the located artifacts</li>
 * </ul>
 *
 * @author eric.wittmann@redhat.com
 */
public abstract class ZipToSrampArchive {

    private static final ArtifactFilter DEFAULT_ARTIFACT_FILTER = new DefaultArtifactFilter();
    private static final MetaDataFactory DEFAULT_META_DATA_FACTORY = new DefaultMetaDataFactory();

    private File originalJar;
    private boolean shouldDeleteOriginalJar;
    private File jarWorkDir;

    /* Customizable handlers for various phases of the create. */

    private ArtifactFilter artifactFilter = DEFAULT_ARTIFACT_FILTER;
    private MetaDataFactory metaDataFactory = DEFAULT_META_DATA_FACTORY;
    private List<MetaDataProvider> metaDataProviders = new ArrayList<MetaDataProvider>();
    private ZipToSrampArchiveContext context;

    /**
     * Constructor.
     * @param jar
     * @throws ZipToSrampArchiveException
     */
    public ZipToSrampArchive(File jar) throws ZipToSrampArchiveException {
        this.originalJar = jar;
        this.shouldDeleteOriginalJar = false;
        this.jarWorkDir = null;

        try {
            jarWorkDir = createJarWorkDir();
            ArchiveUtils.unpackToWorkDir(this.originalJar, this.jarWorkDir);
            context = new ZipToSrampArchiveContext(this.jarWorkDir);
        } catch (IOException e) {
            if (this.jarWorkDir != null) {
                try {
                    FileUtils.deleteDirectory(this.jarWorkDir);
                } catch (IOException e1) {
                }
            }
            throw new ZipToSrampArchiveException(e);
        }
    }

    /**
     * Constructor from JAR input stream.  Note, this will consume and close the given {@link InputStream}.
     * @param jarStream
     * @throws ZipToSrampArchiveException
     */
    public ZipToSrampArchive(InputStream jarStream) throws ZipToSrampArchiveException {
        this.originalJar = null;
        this.shouldDeleteOriginalJar = true;
        this.jarWorkDir = null;

        try {
            this.originalJar = File.createTempFile("j2sramp", ".jar"); //$NON-NLS-1$ //$NON-NLS-2$
            copyJarStream(jarStream, this.originalJar);
            jarWorkDir = createJarWorkDir();
            ArchiveUtils.unpackToWorkDir(this.originalJar, this.jarWorkDir);
            context = new ZipToSrampArchiveContext(this.jarWorkDir);
        } catch (IOException e) {
            if (this.jarWorkDir != null) {
                try {
                    FileUtils.deleteDirectory(this.jarWorkDir);
                } catch (IOException e1) {
                }
            }
            if (this.originalJar != null && this.originalJar.exists()) {
                this.originalJar.delete();
            }
            throw new ZipToSrampArchiveException(e);
        }
    }

    /**
     * Sets a context parameter.
     * @param name
     * @param value
     */
    public void setContextParam(String name, Object value) {
        this.context.put(name, value);
    }

    /**
     * Copies the JAR content from the input stream to the given output file.
     * @param jarStream
     * @param jarOutputFile
     * @throws IOException
     */
    private static void copyJarStream(InputStream jarStream, File jarOutputFile) throws IOException {
        OutputStream oStream = null;
        try {
            oStream = FileUtils.openOutputStream(jarOutputFile);
            IOUtils.copy(jarStream, oStream);
        } finally {
            IOUtils.closeQuietly(jarStream);
            IOUtils.closeQuietly(oStream);
        }
    }

    /**
     * Create the working directory for the JAR.
     * @throws IOException
     */
    private static File createJarWorkDir() throws IOException {
        File tempFile = File.createTempFile("j2sramp", ".work"); //$NON-NLS-1$ //$NON-NLS-2$
        tempFile.delete();
        tempFile.mkdir();
        return tempFile;
    }

    /**
     * Creates an S-RAMP archive from this JAR.
     * @return an S-RAMP archive
     * @throws ZipToSrampArchiveException
     */
    public SrampArchive createSrampArchive() throws ZipToSrampArchiveException {
        this.artifactFilter.setContext(this.context);
        this.metaDataFactory.setContext(this.context);
        DiscoveredArtifacts discoveredArtifacts = discoverArtifacts();
        discoveredArtifacts.index(jarWorkDir);
        generateMetaData(discoveredArtifacts);
        try {
            SrampArchive archive = new SrampArchive();
            for (DiscoveredArtifact artifact : discoveredArtifacts) {
                String path = artifact.getArchivePath();
                archive.addEntry(path, artifact.getMetaData(), artifact.getContent());
            }
            return archive;
        } catch (Exception e) {
            throw new ZipToSrampArchiveException(e);
        }
    }

    /**
     * Generates the meta data for all of the artifacts found during discovery.
     * @param discoveredArtifacts
     */
    private void generateMetaData(DiscoveredArtifacts discoveredArtifacts) {
        for (DiscoveredArtifact artifact : discoveredArtifacts) {
            BaseArtifactType metaData = this.metaDataFactory.createMetaData(artifact);
            for (MetaDataProvider metaDataProvider : this.metaDataProviders) {
                metaDataProvider.provideMetaData(metaData);
            }
            artifact.setMetaData(metaData);
        }
    }

    /**
     * Iterates through all of the entries in the JAR and determines which of them will
     * be included in the S-RAMP archive.  Returns the collection of artifacts that should be
     * included.
     */
    private DiscoveredArtifacts discoverArtifacts() {
        DiscoveredArtifacts artifacts = new DiscoveredArtifacts();
        Collection<File> files = FileUtils.listFiles(jarWorkDir, null, true);
        for (File file : files) {
            CandidateArtifact candidate = new CandidateArtifact(file, jarWorkDir);
            if (this.artifactFilter.accepts(candidate)) {
                artifacts.add(file);
            }
        }

        return artifacts;
    }

    /**
     * This object should be closed once we're done with it.  This allows us to clean up
     * some resources.
     * @throws IOException
     */
    public void close() throws IOException {
        FileUtils.deleteDirectory(jarWorkDir);
        if (shouldDeleteOriginalJar) {
            this.originalJar.delete();
        }
    }

    /**
     * @param artifactFilter the artifactFilter to set
     */
    public void setArtifactFilter(ArtifactFilter artifactFilter) {
        this.artifactFilter = artifactFilter;
    }

    /**
     * @return the configured artifact filter
     */
    public ArtifactFilter getArtifactFilter() {
        return this.artifactFilter;
    }

    /**
     * @param metaDataFactory the metaDataFactory to set
     */
    public void setMetaDataFactory(MetaDataFactory metaDataFactory) {
        this.metaDataFactory = metaDataFactory;
    }

    /**
     * @param metaDataProvider
     */
    public void addMetaDataProvider(MetaDataProvider metaDataProvider) {
        this.metaDataProviders.add(metaDataProvider);
    }

    /**
     * @return the configured meta-data factory
     */
    public MetaDataFactory getMetaDataFactory() {
        return this.metaDataFactory;
    }

    /**
     * @param j2sramp
     */
    public static void closeQuietly(ZipToSrampArchive j2sramp) {
        try {
            if (j2sramp != null)
                j2sramp.close();
        } catch (IOException e) {
        }
    }

}