All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.util.maven.deploymentplan.LegacyRepositoryProvisioningMojo Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2011-2012 Bull S.A.S.
 *
 * 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.ow2.util.maven.deploymentplan;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.DefaultRepositoryRequest;
import org.apache.maven.artifact.repository.RepositoryRequest;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.repository.RepositorySystem;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;

/**
 * A {@code LegacyRepositoryProvisioningMojo} is responsible to build a maven-like directory
 * structure from legacy deployment-plans (not based on a pom.xml, but available in a maven repository).
 *
 * @author Guillaume Sauthier
 * @since 2.0.0
 */
@Mojo(name = "legacy-provision-repository",
      defaultPhase = LifecyclePhase.GENERATE_RESOURCES)
public class LegacyRepositoryProvisioningMojo extends AbstractMojo {

    /**
     * Simplistic parsing helper to determine if we're in a {@literal } element or not.
     */
    private enum Mode {
        IN, OUT
    }

    @Component
    private MavenProject project;

    @Component
    private MavenSession mavenSession;

    @Component
    private RepositorySystem repositorySystem;

    @Component(hint = "default")
    private ArtifactRepositoryLayout layout;

    /**
     * The directory where plans will be placed (using a maven repository layout).
     * @since 2.0.0
     */
    @Parameter(alias = "repositoryDirectory",
               defaultValue = "${project.build.directory}/repository")
    private File repository;

    /**
     * The list of {@link DeploymentPlan} to be provisionned.
     * @since 2.0.0
     */
    @Parameter(alias = "deployment-plans")
    private DeploymentPlan[] deploymentPlans;

    /**
     * The list of module relative paths pointing to deployment plans to be provisionned.
     * @since 2.0.0
     */
    @Parameter
    private File[] files;

    /**
     * Allow timestamp in SNAPSHOT version if set to true
     * @since 2.0.0
     */
    @Parameter(defaultValue = "false")
    private boolean allowTimestamp = false;

    public void execute() throws MojoExecutionException, MojoFailureException {

        // Quick exit
        if (deploymentPlans == null && files == null) {
            return;
        }

        // Iterates over each plan
        if (deploymentPlans != null) {
            for (DeploymentPlan plan : deploymentPlans) {
                resolveDeploymentPlan(plan);
            }
        }
        if (files != null) {
            for (File file : files) {
                resolveDeploymentPlan(file);
            }
        }
    }

    private void resolveDeploymentPlan(DeploymentPlan plan) throws MojoExecutionException, MojoFailureException {
        // Resolve the plan artifact
        // -----------------------------------------------

        Artifact planArtifact = repositorySystem.createArtifact(plan.getGroupId(),
                plan.getArtifactId(),
                plan.getVersion(),
                null,
                "deployment-plan");

        Artifact resolved = resolveArtifact(planArtifact);
        copyResolvedArtifact(resolved);

        // Extract maven deployment info from the plan
        // ----------------------------------------------------------
        resolveDeploymentPlan(resolved.getFile());
    }

    private Artifact resolveArtifact(Artifact artifact) throws MojoExecutionException {

        RepositoryRequest repositoryRequest = DefaultRepositoryRequest.getRepositoryRequest(mavenSession, project);
        ArtifactResolutionRequest request = new ArtifactResolutionRequest(repositoryRequest);
        request.setArtifact(artifact);

        // Resolve
        ArtifactResolutionResult result = repositorySystem.resolve(request);
        if (!result.isSuccess()) {
            for (Exception e : result.getExceptions()) {
                getLog().error(e);
            }

            throw new MojoExecutionException("Couldn't resolve artifact " + artifact);
        }
        return result.getArtifacts().iterator().next();
    }

    private void resolveDeploymentPlan(File file) throws MojoExecutionException, MojoFailureException {

        List toBeResolved = extractArtifactsFromLegacyPlan(file);

        // Iterates on the collected artifacts
        for (Artifact dependency : toBeResolved) {

            if ("deployment-plan".equals(dependency.getType())) {

                // Special recursive handling for deployment plan
                DeploymentPlan subPlan = new DeploymentPlan();
                subPlan.setGroupId(dependency.getGroupId());
                subPlan.setArtifactId(dependency.getArtifactId());
                subPlan.setVersion(dependency.getVersion());

                // recurse
                resolveDeploymentPlan(subPlan);
            } else {

                // Simple dependency
                Artifact resolved = resolveArtifact(dependency);
                copyResolvedArtifact(resolved);
            }
        }
    }

    /**
     * Build a list of maven Artifact from maven dependencies described in the loaded deployment plan.
     * @param resource the deployment plan
     * @return the list of found maven artifacts
     * @throws MojoExecutionException if plan cannot be read
     */
    private List extractArtifactsFromLegacyPlan(final File resource) throws MojoExecutionException {

        // Prepare the XML parsing
        XMLInputFactory factory = XMLInputFactory.newInstance();
        XMLStreamReader reader = null;
        Reader stream = null;
        List toBeResolved = new ArrayList();
        Mode mode = Mode.OUT;

        try {

            // Contains parsed values
            String groupId = null;
            String artifactId = null;
            String version = null;
            String type = null;
            String classifier = null;

            // Get the XML reader
            stream = getXmlReader(resource);
            reader = factory.createXMLStreamReader(stream);

            // Parse the XML, StAX style
            while (reader.hasNext()) {
                reader.next();
                switch (reader.getEventType()) {

                    // Handle the beginning of an element
                    case XMLStreamReader.START_ELEMENT:

                        // Given our current parsing state ...
                        switch (mode) {
                            // We were not in a  element
                            case OUT:

                                // If this is a  element ...
                                if (isDeployment(reader)) {
                                    // ... move our state to mark that fact
                                    mode = Mode.IN;
                                }
                                break;

                            // We were in a  element
                            case IN:

                                // Acts differently given the current element's name
                                String name = reader.getLocalName();
                                if ("groupId".equals(name)) {
                                    groupId = reader.getElementText();
                                }
                                if ("artifactId".equals(name)) {
                                    artifactId = reader.getElementText();
                                }
                                if ("version".equals(name)) {
                                    version = reader.getElementText();
                                }
                                if ("type".equals(name)) {
                                    type = reader.getElementText();
                                }
                                if ("classifier".equals(name)) {
                                    classifier = reader.getElementText();
                                }
                                break;
                        }
                        break;

                    // Handle the end of an element
                    case XMLStreamReader.END_ELEMENT:

                        // Is this the closing tag  ?
                        if (isDeployment(reader)) {

                            // Move our state to "outside"
                            mode = Mode.OUT;

                            // Validate gathered values
                            if (groupId == null || artifactId == null || version == null) {
                                // If one is missing, this is probably not a maven dependency,
                                // so we can safely continue with the next event
                                continue;
                            }

                            // Create the artifact
                            Artifact artifact = repositorySystem.createArtifactWithClassifier(groupId, artifactId, version, type, classifier);
                            toBeResolved.add(artifact);

                            // Reset the counters
                            groupId = null;
                            artifactId = null;
                            version = null;
                            type = null;
                            classifier = null;
                        }
                        break;
                }
            }


        } catch (XMLStreamException e) {
            throw new MojoExecutionException(e.getMessage());
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (XMLStreamException e) {
                // Ignored
            }
            IOUtil.close(stream);
        }

        return toBeResolved;
    }

    /**
     * Return a Reader for the given File
     * @param resource file to be read
     * @return a Reader for the given File
     * @throws MojoExecutionException when the file is not found
     */
    private Reader getXmlReader(File resource) throws MojoExecutionException {
        try {
            return new FileReader(resource);
        } catch (FileNotFoundException e) {
            throw new MojoExecutionException(e.getMessage());
        }
    }

    /**
     * Copy the given artifact from the local repository (because it has been resolved) into the destination repository.
     * Thiscopy maintains the maven2 layout.
     * @param artifact artifact to be copied
     * @throws MojoFailureException if the copy cannot finish
     */
    private void copyResolvedArtifact(Artifact artifact) throws MojoFailureException {
        String path = layout.pathOf(artifact);
        File source = artifact.getFile();
        File destination;

        String targetPath = path;
        if (!allowTimestamp) {
            targetPath = path.replace(artifact.getVersion(), artifact.getBaseVersion());
        }
        destination = new File(repository, targetPath);

        getLog().debug("Copy artifact: " + source + " to " + destination);
        try {
            FileUtils.copyFileIfModified(source, destination);
        } catch (IOException e) {
            throw new MojoFailureException(e.getMessage());
        }
    }

    private boolean isDeployment(XMLStreamReader reader) {
        // Only consumes  elements
        return "deployment".equals(reader.getLocalName());

    }

    /**
     * @return true if timestamp are allowed in SNAPSHOT version
     */
    public boolean isAllowTimestamp() {
        return this.allowTimestamp;
    }

    /**
     * @param allowTimestamp Allow timestamp in SNAPSHOT version if set to true
     */
    public void setAllowTimestamp(final boolean allowTimestamp) {
        this.allowTimestamp = allowTimestamp;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy