org.codehaus.mojo.pomtools.helpers.MetadataHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.codehaus.mojo.pomtools.helpers.MetadataHelper.java

Source

package org.codehaus.mojo.pomtools.helpers;

/*
 * Copyright 2005-2006 The Apache Software Foundation.
 *
 * 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.
 */

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.InvalidArtifactRTException;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;
import org.apache.maven.artifact.repository.metadata.Metadata;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager;
import org.apache.maven.artifact.repository.metadata.RepositoryMetadataResolutionException;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.artifact.resolver.ResolutionNode;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.execution.MavenSession;
import org.codehaus.mojo.pomtools.PomToolsPluginContext;
import org.codehaus.mojo.pomtools.PomToolsException;
import org.codehaus.mojo.pomtools.PomToolsRTException;
import org.codehaus.mojo.pomtools.PomToolsVersionException;
import org.codehaus.mojo.pomtools.wrapper.ObjectWrapper;
import org.codehaus.mojo.pomtools.wrapper.custom.ModelVersionRange;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.artifact.InvalidDependencyVersionException;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.util.StringUtils;

/** Wrapper library for Maven Artifact and Metadata routines.
 * 
 * @author <a href="mailto:dhawkins@codehaus.org">David Hawkins</a> * @version $Id$
 */
public class MetadataHelper {
    private final RepositoryMetadataManager repositoryMetadataManager;

    private final ArtifactFactory artifactFactory;

    private final List remoteRepositories;

    private final ArtifactRepository localRepository;

    private final ArtifactMetadataSource metadataSource;

    private final ArtifactResolver artifactResolver;

    public MetadataHelper(MavenSession session, List remoteArtifactRepositories, ArtifactRepository localRepository)
            throws PomToolsRTException {
        PlexusContainer container = session.getContainer();

        try {
            this.repositoryMetadataManager = (RepositoryMetadataManager) container
                    .lookup(RepositoryMetadataManager.class.getName());

            this.artifactFactory = (ArtifactFactory) container.lookup(ArtifactFactory.ROLE);

            this.metadataSource = (ArtifactMetadataSource) container.lookup(ArtifactMetadataSource.ROLE);

            this.artifactResolver = (ArtifactResolver) container.lookup(ArtifactResolver.ROLE);
        } catch (ComponentLookupException e) {
            throw new PomToolsRTException(e);
        }

        this.remoteRepositories = remoteArtifactRepositories;
        this.localRepository = localRepository;
    }

    /** Simple wrapper for 
     * {@link ArtifactFactory#createArtifact(java.lang.String, java.lang.String, java.lang.String, 
     * java.lang.String, java.lang.String)}
     * 
     */
    public Artifact createArtifact(String groupId, String artifactId, String version, String scope, String type) {
        return artifactFactory.createArtifact(groupId, artifactId,
                StringUtils.defaultString(version, Artifact.LATEST_VERSION), scope,
                StringUtils.defaultString(type, "jar"));
    }

    public Artifact createArtifact(ObjectWrapper obj) {
        if (obj.getFields().get("scope") != null) {
            return createArtifact((String) obj.getFieldValue("groupId"), (String) obj.getFieldValue("artifactId"),
                    (String) obj.getFieldValue("version"), (String) obj.getFieldValue("scope"),
                    (String) obj.getFieldValue("type"));
        } else {
            return createArtifact((String) obj.getFieldValue("groupId"), (String) obj.getFieldValue("artifactId"),
                    (String) obj.getFieldValue("version"), null, null);
        }
    }

    public RepositoryMetadata getMetadata(ObjectWrapper obj) throws ArtifactMetadataRetrievalException {
        return getMetadata(createArtifact(obj));
    }

    public RepositoryMetadata getMetadata(Artifact artifact) throws ArtifactMetadataRetrievalException {
        RepositoryMetadata metadata = new ArtifactRepositoryMetadata(artifact);
        try {
            repositoryMetadataManager.resolve(metadata, remoteRepositories, localRepository);

            return metadata;
        } catch (RepositoryMetadataResolutionException e) {
            throw new ArtifactMetadataRetrievalException("An error occured while resolving repository metadata", e);
        }
    }

    /** Returns whether the groupId and artifactId appear to be valid.
     * This differs from {@link #isValidDependencyArtifact(Artifact)} in that the version 
     * can be null or even invalid and still get a positive result
     * 
     * @param artifact
     * @return
     */
    public boolean isValidGroupIdArtifactId(Artifact artifact) {
        if (isValidDependencyArtifact(artifact)) {
            return true;
        }

        try {
            RepositoryMetadata metadata = getMetadata(artifact);

            return metadata.getMetadata().getVersioning() != null;
        } catch (ArtifactMetadataRetrievalException e) {
            return false;
        }

    }

    /** Determines whether the artifact exists ( in that we are able to locate metadata for the groupId and artifactId)
     * and that the version or version range specified refers to a version specified in the repository metadata.  
     * 
     * @param artifact
     * @return
     */
    public boolean isValidDependencyArtifact(Artifact artifact) {
        try {
            ModelVersionRange versionRange = ModelVersionRange
                    .createFromVersionSpec(artifact.getVersionRange().toString());

            Metadata metadata = getMetadata(artifact).getMetadata();

            if (metadata.getVersioning() != null) {
                List availableVersions = metadataSource.retrieveAvailableVersions(artifact, localRepository,
                        remoteRepositories);

                for (Iterator iter = availableVersions.iterator(); iter.hasNext();) {
                    ArtifactVersion version = (ArtifactVersion) iter.next();

                    if (versionRange.containsVersion(version)) {
                        return true;
                    }
                }
            }

            return (metadata.getVersion() != null && versionRange.containsVersion(metadata.getVersion()));
        } catch (InvalidArtifactRTException e) {
            return false;
        } catch (ArtifactMetadataRetrievalException e) {
            return false;
        } catch (InvalidVersionSpecificationException e) {
            return false;
        }
    }

    /** Resolves all transitive dependencies for the current project and returns a list
     * of {@link TransitiveDependencyInfo} objects.  Each object represents a distinct 
     * groupId:artifactId:type dependency.  The {@link TransitiveDependencyInfo#getResolutionNodes()}
     * represent all of the possible ResolutionNodes which resolve to this groupId:artifactId.
     * 
     * @return
     * @throws PomToolsException
     */
    public List getTransitiveDependencies() throws PomToolsException, ProjectBuildingException {
        // Certain things like groupId or versions for dependencies may be declared in a parent
        // pom so we need to have maven fully resolve the model before walking the tree.
        MavenProject project = PomToolsPluginContext.getInstance().getActiveProject().getTemporaryResolvedProject();

        try {
            project.setDependencyArtifacts(project.createArtifacts(artifactFactory, null, null));
        } catch (InvalidDependencyVersionException e) {
            throw new PomToolsVersionException(
                    "Unable to build project due to an invalid dependency version: " + e.getMessage(), e);
        }

        Artifact projectArtifact = project.getArtifact();

        Set artifacts = project.getDependencyArtifacts();

        try {
            List dependencies = new ArrayList();

            ArtifactResolutionResult result;
            result = artifactResolver.resolveTransitively(artifacts, projectArtifact, Collections.EMPTY_MAP,
                    localRepository, remoteRepositories, metadataSource, projectArtifact.getDependencyFilter());

            Map dependencyMap = new HashMap();
            Set seen = new HashSet();

            // First build our map of distinct groupId:artifactIds
            for (Iterator iter = result.getArtifactResolutionNodes().iterator(); iter.hasNext();) {
                ResolutionNode node = (ResolutionNode) iter.next();

                TransitiveDependencyInfo info = new TransitiveDependencyInfo(node);

                dependencyMap.put(info.getKey(), info);

                dependencies.add(info);
            }

            // Now populate the map with all children
            recurseNode(dependencyMap, seen, result.getArtifactResolutionNodes().iterator(), 0);

            return dependencies;
        } catch (ArtifactNotFoundException e) {
            throw new PomToolsException(e);
        } catch (ArtifactResolutionException e) {
            throw new PomToolsException(e);
        }

    }

    protected void recurseNode(Map dependencyMap, Set seen, Iterator nodeIter, int depth) throws PomToolsException {
        while (nodeIter.hasNext()) {
            ResolutionNode node = (ResolutionNode) nodeIter.next();

            if (!seen.contains(node)) {
                seen.add(node);

                TransitiveDependencyInfo info = (TransitiveDependencyInfo) dependencyMap.get(node.getKey());

                // if we couldn't find the info in the map, then its not a dependency that we should 
                // care about because it wasn't returned to the top level dependency resolution.
                if (info != null) {
                    info.addResolutionNode(node);

                    if (node.isResolved()) {
                        recurseNode(dependencyMap, seen, node.getChildrenIterator(), depth + 1);
                    }
                }
            }
        }
    }

    public ArtifactRepository getLocalRepository() {
        return localRepository;
    }

    public List getRemoteRepositories() {
        return remoteRepositories;
    }
}