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

org.ow2.util.maven.jbuilding.AbstractResolverMojo Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2007-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.jbuilding;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.DefaultRepositoryRequest;
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.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.repository.RepositorySystem;

/**
 * Resolve the artifacts.
 * @author Guillaume Sauthier
 */
public abstract class AbstractResolverMojo extends AbstractMojo {

    /**
     * @since 2.0.0
     */
    @Parameter
    private DeploymentPlan[] deploymentPlans = new DeploymentPlan[0];

    /**
     * List of deployment plans for current profile.
     * @since 2.0.0
     */
    @Parameter
    private List profile;

    /**
     * @since 2.0.0
     */
    @Parameter
    private ArtifactItem[] artifactItems = new ArtifactItem[0];

    /**
     * Deployment plan inclusion map.
     */
    protected Map deploymentPlanIncludes = null;

    /**
     * Artifact items map.
     */
    protected Map artifactItemMap = null;

    /**
     * Deployment plan map.
     */
    protected Map deploymentPlanMap = null;

    public static final int CLIENT_SIDE = 0;
    public static final int SERVER_SIDE = 1;

    public static final int BOTH_MODE = 0;
    public static final int INSTALL_MODE = 1;
    public static final int START_MODE = 2;

    public static final String AUTO_DEPLOY_ARTIFACT_ITEMS = "AUTO_DEPLOY_ARTIFACT_ITEMS";
    public static final String DEPLOYMENT_PLANS_ARTIFACT_ITEMS = "DEPLOYMENT_PLANS_ARTIFACT_ITEMS";
    public static final String ALL_ARTIFACT_ITEMS = "ALL_ARTIFACT_ITEMS";

    @Component
    protected MavenProject project;

    @Component
    protected MavenSession mavenSession;

    @Component
    protected RepositorySystem repositorySystem;

    @Parameter(defaultValue="${project.remoteArtifactRepositories}", readonly=true, required=true)
    protected List remoteRepositories;


    public AbstractResolverMojo()  {
        deploymentPlanIncludes = new HashMap();
        artifactItemMap = new HashMap();
        deploymentPlanMap = new HashMap();
    }

    /**
     * Resolve/Download all declared artifacts.
     * @param side "client" or "server"
     * @param mode "install", "start" or "both"
     * @param artifactItemType artifact item type
     * @param managedVersion If set to true, latest managed versions of each artifact will be resolved
     * @return a {@link Map} of {@link Collection}s of {@link Artifact}s.
     * @throws MojoExecutionException If resolution fails.
     */
    public Map> resolveArtifacts(final int side, final int mode, final String artifactItemType,
                                                              final boolean managedVersion)
            throws MojoExecutionException {
        Map> map = new HashMap>();
        Collection artifacts = null;

        if (ALL_ARTIFACT_ITEMS.equals(artifactItemType) || AUTO_DEPLOY_ARTIFACT_ITEMS.equals(artifactItemType)) {
            artifacts = resolveArtifacts(side, mode, artifactItems, managedVersion);
            map.put(AUTO_DEPLOY_ARTIFACT_ITEMS, artifacts);
        }

        if (ALL_ARTIFACT_ITEMS.equals(artifactItemType) || DEPLOYMENT_PLANS_ARTIFACT_ITEMS.equals(artifactItemType)) {
            // Clear deployment plan inclusion map
            deploymentPlanIncludes.clear();

            for (DeploymentPlan deploymentPlan: deploymentPlans) {
                String deploymentPlanName = deploymentPlan.getName();

                // Only copy in repository deployment plan artifacts defined in the current profile
                if (ALL_ARTIFACT_ITEMS.equals(artifactItemType) && !this.isIncluded(deploymentPlan, profile)) {
                    continue;
                }

                // Generate deployment plans for application only if defined in the current profile
                if (DEPLOYMENT_PLANS_ARTIFACT_ITEMS.equals(artifactItemType)
                        && deploymentPlan.getDirectory() != null
                        && !this.isIncluded(deploymentPlan, profile)) {
                    continue;
                }

                deploymentPlanMap.put(deploymentPlanName, deploymentPlan);

                ArtifactItem[] items = deploymentPlan.getArtifactItems();

                artifacts = resolveArtifacts(side, mode, items, managedVersion);
                map.put(deploymentPlanName, artifacts);

                String[] includes = deploymentPlan.getIncludes();
                deploymentPlanIncludes.put(deploymentPlanName, includes);
            }
        }

        return map;
    }


    /**
     * Resolve/Download all declared Bundles/Artifacts.
     * @param side "client" or "server"
     * @param mode "install", "start" or "both"
     * @param items a set of artifact items to resolve
     * @param managedVersion If set to true, latest managed versions of each artifact will be resolved
     * @return a {@link Collection} of {@link Artifact}s.
     * @throws MojoExecutionException If resolution fails.
     */
    private Collection resolveArtifacts(final int side, final int mode, final ArtifactItem[] items,
                                                  final boolean managedVersion)
            throws MojoExecutionException {
        // First create artifacts from the ArtifactItems
        Map artifacts = new LinkedHashMap();

        if (items != null) {
            for (int j = 0; j < items.length; j++) {
                ArtifactItem artifactItem = items[j];
                if (!(mode == INSTALL_MODE && !artifactItem.isStart())
                        && !(mode == START_MODE && artifactItem.isStart())
                        && !(mode == BOTH_MODE)) {
                    continue;
                }
                if ("client".equalsIgnoreCase(artifactItem.getSide()) && side == SERVER_SIDE) {
                    continue;
                }
                if ("server".equalsIgnoreCase(artifactItem.getSide()) && side == CLIENT_SIDE) {
                    continue;
                }
                Artifact artifact = createArtifact(artifactItem.getGroupId(),
                                                   artifactItem.getArtifactId(),
                                                   artifactItem.getVersion(),
                                                   artifactItem.getType(),
                                                   artifactItem.getClassifier());
                artifact.setBaseVersion(artifactItem.getVersion());

                // Store the artifact with its conflictId in a Map
                artifacts.put(artifact.getDependencyConflictId(), artifact);
                artifactItemMap.put(artifact.getDependencyConflictId(), artifactItem);
            }

            printArtifacts("Created ...", artifacts.values());


            // Manually resolve artifacts using dependencyManagement
            Set> artifactsSet = artifacts.entrySet();

            for (Map.Entry artifactEntry : artifactsSet) {
                String key = artifactEntry.getKey();
                Artifact artifact = artifactEntry.getValue();

                //get the latest version (maybe with timestamp if artifact version is null or managedVersion mode set to true)
                if (artifact.getVersion() == null || Artifact.LATEST_VERSION.equals(artifact.getVersion()) || managedVersion) {

                    Map managedVersions = project.getManagedVersionMap();

                    Artifact resolved  = null;
                    if (managedVersions != null) {
                        resolved = (Artifact) managedVersions.get(key);
                    }

                    if (resolved != null) {
                        // Got a managed version of the artifact
                        artifacts.put(key, resolved);
                    } else if (Artifact.LATEST_VERSION.equals(artifact.getVersion())) {
                        // We don't have a managed version of this artifact
                        // If the version is still latest, assume this is a JOnAS
                        // artifact
                        // and use the JOnAS version
                        artifacts.get(key).setVersion(project.getVersion());
                    } // else, let use the provided version
                }
            }

            // Now we can do something from that
            // Resolve (download) the required artifacts
            List resolved = new ArrayList();
            for (Artifact artifact : artifacts.values()) {
                try {
                    resolved.add(resolveArtifact(artifact));
                } catch (Exception e) {
                    throw new MojoExecutionException("Cannot resolve/download the Bundle " + artifact, e);
                }
            }

            printArtifacts("Resolved ...", resolved);
        }

        return artifacts.values();
    }

    /**
     * Construct a new "jar" artifact.
     * @param groupId Group ID
     * @param artifactId Artifact ID
     * @param version Artifact's version
     * @param classifier Artifact's classifier (may be null)
     * @return a new artifact
     */
    protected Artifact createArtifact(final String groupId,
                                    final String artifactId,
                                    final String version,
                                    final String type,
                                    final String classifier) {
        return repositorySystem.createArtifactWithClassifier(groupId, artifactId, version, type, classifier);
    }

    /**
     * Resolve the given artifact (triggering its download if needed).
     * @param artifact the given artifact to resolve
     * @throws Exception if there is failure when resolving
     */
    protected Artifact resolveArtifact(final Artifact artifact) throws Exception {
        DefaultRepositoryRequest repositoryRequest = new DefaultRepositoryRequest(DefaultRepositoryRequest.getRepositoryRequest(mavenSession, project));
        repositoryRequest.setRemoteRepositories(remoteRepositories);
        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();
    }

    /**
     * Debug artifact Map.
     * @param banner Header
     * @param artifacts Map of artifacts to print.
     */
    private void printArtifacts(final String banner, final Collection artifacts) {
        getLog().debug(banner);
        for (Artifact artifact : artifacts) {
            getLog().debug(artifact.toString());
        }
    }

    /**
     * Check if a {@link DeploymentPlan} is included in a {@link List} of {@link DeploymentPlan}s by navigating through transitive
     * inclusions.
     *
     * @param deploymentPlan The {@link DeploymentPlan} to check
     * @param includedPlans A list of strings representing {@link DeploymentPlan} names
     * @return true if deploymentPlan is part of includedPlans or included in corresponding {@link DeploymentPlan}s
     */
    private boolean isIncluded(DeploymentPlan deploymentPlan, List includedPlans) {
        if (includedPlans.contains(deploymentPlan.getName())) {
            return true;
        }
        for (String includedPlanName : includedPlans) {
            DeploymentPlan includedPlan = this.getDeploymentPlanByName(includedPlanName);
            if (includedPlan != null && includedPlan.getIncludes() != null) {
                if (isIncluded(deploymentPlan, Arrays.asList(includedPlan.getIncludes()))) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Retrieve a {@link DeploymentPlan} given its name.
     *
     * @param deploymentPlanName the given {@link DeploymentPlan} name
     * @return the retrieved {@link DeploymentPlan} if there is a {@link DeploymentPlan} matching deploymentPlanName in plugin configuration, 'null' otherwise.
     */
    private DeploymentPlan getDeploymentPlanByName(String deploymentPlanName) {
        for (DeploymentPlan plan : deploymentPlans) {
            if (plan.getName().equals(deploymentPlanName)) {
                return plan;
            }
        }
        return null;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy