Package org.andromda.maven.plugin.modelarchiver

Source Code of org.andromda.maven.plugin.modelarchiver.XmiZipArchiverMojo

package org.andromda.maven.plugin.modelarchiver;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.archiver.MavenArchiveConfiguration;
import org.apache.maven.archiver.MavenArchiver;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.UnArchiver;
import org.codehaus.plexus.archiver.jar.JarArchiver;
import org.codehaus.plexus.archiver.manager.ArchiverManager;
import org.codehaus.plexus.util.FileUtils;


/**
* Builds archived model xml.zip files.
*
* @author Chad Brandon
* @goal xml.zip
* @phase package
* @requiresProject
* @description builds a versioned xml.zip
*/
public class XmiZipArchiverMojo
    extends AbstractMojo
{
    /**
     * Single directory that contains the model
     *
     * @parameter expression="${basedir}/src/main/uml"
     * @required
     */
    private File modelSourceDirectory;

    /**
     * Directory that resources are copied to during the build.
     *
     * @parameter expression="${project.build.directory}"
     * @required
     */
    private String workDirectory;

    /**
     * The directory for the generated xml.zip.
     *
     * @parameter expression="${project.build.outputDirectory}"
     * @required
     */
    private String outputDirectory;

    /**
     * The name of the xml.zip file to generate.
     *
     * @parameter alias="modelName" expression="${project.build.finalName}"
     * @required
     * @readonly
     */
    private String finalName;

    /**
     * The maven project.
     *
     * @parameter expression="${project}"
     * @required
     * @readonly
     * @description "the maven project to use"
     */
    private MavenProject project;

    /**
     * Artifact factory, needed to download source jars for inclusion in
     * classpath.
     *
     * @component role="org.apache.maven.artifact.factory.ArtifactFactory"
     * @required
     * @readonly
     */
    private ArtifactFactory artifactFactory;

    /**
     * To look up Archiver/UnArchiver implementations
     *
     * @parameter expression="${component.org.codehaus.plexus.archiver.manager.ArchiverManager}"
     * @required
     */
    protected ArchiverManager archiverManager;

    /**
     * The model Jar archiver.
     *
     * @parameter expression="${component.org.codehaus.plexus.archiver.Archiver#jar}"
     * @required
     */
    private JarArchiver modelJarArchiver;

    /**
     * The extensions to search for when doing replacement of embedded model HREF references
     * within the archived model file from non-versioned to versioned references.
     *
     * @parameter expression=".xml,.xml.zip,.xmi"
     * @required
     */
    protected String replacementExtensions;

    /**
     * Whether or not to do replacement of embedded model HREF reference extensions.
     *
     * @parameter expression=true
     * @required
     */
    protected boolean replaceExtensions;

    /**
     * The maven project's helper.
     *
     * @parameter expression="${component.org.apache.maven.project.MavenProjectHelper}"
     * @required
     * @readonly
     */
    private MavenProjectHelper projectHelper;

    /**
     * Whether or not the model should have a jar created with it as well.
     *
     * @parameter
     */
    private boolean generateJar;
    private static final String[] JAR_INCLUDES = new String[] {"**/*"};
    private static final String[] JAR_EXCLUDES = new String[] {"**/package.html"};
    private final Collection modelArchiveExcludes =
        new ArrayList(Arrays.asList(new String[] {"*.xml.zip, **/*.java", "*reports*/**", "tests*/**"}));

    /**
     * The pattern of the archived model files that should be extracted
     * before being re-created as versioned model archives.
     *
     * @parameter expression=".*(\\.xml\\.zip)"
     * @required
     * @readonly
     */
    private String modelArchivePattern;

    /**
     * The pattern of the non-archived model file(s) that should be archived.
     *
     * @parameter expression=".*(\\.xml|\\.xmi)"
     * @required
     * @readonly
     */
    private String modelFilePattern;

    /**
     * The maven archiver to use.
     *
     * @parameter
     */
    private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();

    /**
     * @parameter expression="${localRepository}"
     * @required
     * @readonly
     */
    protected ArtifactRepository localRepository;

    public void execute()
        throws MojoExecutionException
    {
        getLog().debug(" ======= XmlZipArchiverMojo settings =======");
        getLog().debug("modelSourceDirectory[" + modelSourceDirectory + "]");
        getLog().debug("workDirectory[" + workDirectory + "]");
        getLog().debug("outputDirectory[" + outputDirectory + "]");
        getLog().debug("finalName[" + finalName + "]");
        getLog().debug("replaceExtensions[" + replaceExtensions + "]");

        try
        {
            // - the directory which to extract the model file
            final File modelExtractDirectory = new File(this.workDirectory, "models/xmi");
            modelExtractDirectory.mkdirs();
            final File buildDirectory = new File(this.workDirectory);

            final File modelSourceDir = modelSourceDirectory;
            final String[] replacementExtensions =
                this.replacementExtensions != null ? this.replacementExtensions.split(",\\s*") : new String[0];
            if (modelSourceDir.exists())
            {
                getLog().info("Copy xml.zip resources to " + buildDirectory.getAbsolutePath());
                final File[] modelFiles = modelSourceDir.listFiles();
                for (int ctr = 0; ctr < modelFiles.length; ctr++)
                {
                    final File file = modelFiles[ctr];
                    if (file.isFile() && file.toString().matches(this.modelArchivePattern))
                    {
                        // - extract model file
                        this.unpack(
                            file,
                            modelExtractDirectory);
                        final File[] extractedModelFiles = modelExtractDirectory.listFiles();
                        for (int ctr2 = 0; ctr2 < extractedModelFiles.length; ctr2++)
                        {
                            final File extractedFile = extractedModelFiles[ctr2];
                            final String extractedFilePath = extractedFile.toString();
                            if (extractedFile.isFile() && extractedFilePath.matches(this.modelFilePattern))
                            {
                                final File newFile =
                                    new File(modelExtractDirectory,
                                        this.finalName + '.' + FileUtils.getExtension(extractedFile.toString()));

                                // - exclude the file that we extracted
                                if (!newFile.equals(extractedFile))
                                {
                                    final String shortPath = extractedFilePath.replaceAll(
                                            ".*\\\\|/",
                                            "");
                                    this.modelArchiveExcludes.add(shortPath);
                                }
                                extractedFile.renameTo(newFile);
                                String contents = IOUtils.toString(new FileReader(newFile));
                                if (replaceExtensions)
                                {
                                    for (int ctr3 = 0; ctr3 < replacementExtensions.length; ctr3++)
                                    {
                                        final String version = escapePattern(this.project.getVersion());
                                        final String extension = escapePattern(replacementExtensions[ctr3]);
                                        final String extensionPattern = "((\\-" + version + ")?)" + extension;
                                        final String newExtension = "\\-" + version + extension;
                                        contents =
                                            contents.replaceAll(
                                                extensionPattern,
                                                newExtension);
                                    }
                                }
                                final FileWriter fileWriter = new FileWriter(newFile);
                                fileWriter.write(contents);
                                fileWriter.flush();
                                final File xmlZipFile = new File(buildDirectory, this.finalName + ".xml.zip");
                                this.writeModelArchive(
                                    xmlZipFile,
                                    newFile.toString());
                            }
                        }
                    }
                }
            }

            final File xmlZipFile = new File(buildDirectory, this.finalName + ".xml.zip");
            final Artifact artifact = this.project.getArtifact();
            artifact.setFile(xmlZipFile);
            if (this.generateJar)
            {
                final File workDirectory = new File(this.workDirectory);
                this.getLog().info("Building model jar " + finalName);

                final Artifact jarArtifact =
                    artifactFactory.createArtifact(
                        project.getGroupId(),
                        project.getArtifactId(),
                        project.getVersion(),
                        null,
                        ATTACHED_ARTIFACT_TYPE);

                File modelJar = new File(workDirectory, finalName + "." + ATTACHED_ARTIFACT_TYPE);

                final MavenArchiver modelJarArchiver = new MavenArchiver();

                modelJarArchiver.setArchiver(this.modelJarArchiver);
                modelJarArchiver.setOutputFile(modelJar);
                modelJarArchiver.getArchiver().addDirectory(
                    new File(this.outputDirectory),
                    JAR_INCLUDES,
                    JAR_EXCLUDES);

                // - create archive
                modelJarArchiver.createArchive(
                    project,
                    archive);

                // - set the artifact file as the modelJar so that we can install the model jar
                jarArtifact.setFile(modelJar);
                this.installModelJar(
                    jarArtifact,
                    modelJar);
                projectHelper.attachArtifact(
                    project,
                    ATTACHED_ARTIFACT_TYPE,
                    null,
                    modelJar);
            }
        }
        catch (final Throwable throwable)
        {
            throw new MojoExecutionException("Error assembling model", throwable);
        }
    }

    /**
     * The type of the attached artifact.
     */
    private static final String ATTACHED_ARTIFACT_TYPE = "jar";

    /**
     * Installs the model jar for this xml.zip artifact into the local repository.
     *
     * @param artifact the artifact to install.
     * @param source the source of the artifact.
     * @throws IOException
     */
    private void installModelJar(
        final Artifact artifact,
        final File source)
        throws IOException
    {
        // - change the extension to the correct 'jar' extension
        final String localPath = this.localRepository.pathOf(artifact).replaceAll(
                "\\.xml\\.zip",
                "\\.jar");
        final File destination = new File(
                this.localRepository.getBasedir(),
                localPath);
        this.getLog().info("Installing " + source.getPath() + " to " + destination);

        FileUtils.copyFile(
            source,
            destination);
    }

    /**
     * Escapes the pattern so that the reserved regular expression
     * characters are used literally.
     * @param pattern the pattern to replace.
     * @return the resulting pattern.
     */
    private static String escapePattern(String pattern)
    {
        pattern =
            StringUtils.replace(
                pattern,
                ".",
                "\\.");
        pattern =
            StringUtils.replace(
                pattern,
                "-",
                "\\-");
        return pattern;
    }

    /**
     * Unpacks the archive file.
     *
     * @param file File to be unpacked.
     * @param location Location where to put the unpacked files.
     */
    protected void unpack(
        final File file,
        final File location)
        throws MojoExecutionException
    {
        final String archiveExt = FileUtils.getExtension(file.getAbsolutePath()).toLowerCase();
        try
        {
            final UnArchiver unArchiver;
            unArchiver = this.archiverManager.getUnArchiver(archiveExt);
            unArchiver.setSourceFile(file);
            unArchiver.setDestDirectory(location);
            unArchiver.extract();
        }
        catch (Throwable throwable)
        {
            if (throwable instanceof IOException || throwable instanceof ArchiverException)
            {
                throw new MojoExecutionException("Error unpacking file: " + file + "to: " + location, throwable);
            }
        }
    }

    /**
     * The regular expression pattern used to remove the beginning of the path from the file (and leave the name).
     */
    private static final String PATH_REMOVE_PATTERN = ".*(\\\\|/)";

    /**
     * Writes the given given <code>model</code> archive file and includes
     * the file given by the <code>path</code>
     *
     * @param modelArchive the model archive.
     * @param path the path of the model to write.
     * @throws IOException
     */
    private void writeModelArchive(
        final File modelArchive,
        final String path)
        throws IOException
    {
        // - retrieve the name of the file given by the path.
        final String name = path.replaceAll(
                PATH_REMOVE_PATTERN,
                "");
        final ZipOutputStream zipOutputStream = new ZipOutputStream(new java.io.FileOutputStream(modelArchive));
        final ZipEntry zipEntry = new ZipEntry(name);
        zipEntry.setMethod(ZipEntry.DEFLATED);
        zipOutputStream.putNextEntry(zipEntry);
        final java.io.FileInputStream inputStream = new java.io.FileInputStream(path);
        final byte[] buffer = new byte[1024];
        int n = 0;
        while ((n =
                inputStream.read(
                    buffer,
                    0,
                    buffer.length)) > 0)
        {
            zipOutputStream.write(
                buffer,
                0,
                n);
        }
        inputStream.close();
        zipOutputStream.closeEntry();
        zipOutputStream.close();
    }
}
TOP

Related Classes of org.andromda.maven.plugin.modelarchiver.XmiZipArchiverMojo

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.