org.ebayopensource.turmeric.eclipse.mavenapi.impl.AbstractMavenApi.java Source code

Java tutorial

Introduction

Here is the source code for org.ebayopensource.turmeric.eclipse.mavenapi.impl.AbstractMavenApi.java

Source

/*******************************************************************************
 * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved.
 * 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
 *******************************************************************************/
package org.ebayopensource.turmeric.eclipse.mavenapi.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactScopeEnum;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.RepositoryPolicy;
import org.apache.maven.project.MavenProject;
import org.apache.maven.repository.RepositorySystem;
import org.apache.maven.repository.metadata.ArtifactMetadata;
import org.apache.maven.repository.metadata.MetadataResolutionRequest;
import org.apache.maven.repository.metadata.MetadataResolutionResult;
import org.apache.maven.repository.metadata.MetadataTreeNode;
import org.apache.maven.settings.Mirror;
import org.apache.maven.settings.Profile;
import org.apache.maven.settings.Settings;
import org.apache.maven.settings.SettingsUtils;
import org.codehaus.plexus.PlexusContainer;
import org.ebayopensource.turmeric.eclipse.mavenapi.exception.MavenEclipseApiException;
import org.ebayopensource.turmeric.eclipse.mavenapi.internal.collections.ListUtil;
import org.ebayopensource.turmeric.eclipse.mavenapi.internal.resources.Messages;
import org.ebayopensource.turmeric.eclipse.mavenapi.internal.util.MavenApiUtil;
import org.ebayopensource.turmeric.eclipse.mavenapi.intf.IMavenEclipseApi;
import org.maven.ide.eclipse.MavenPlugin;
import org.maven.ide.eclipse.internal.embedder.MavenImpl;

/**
 * The Class AbstractMavenApi.
 *
 * @author <a href="oleg@codehaus.org">Oleg Gusakov</a>
 */
public abstract class AbstractMavenApi implements IMavenEclipseApi {

    /** The Constant PACKAGING_TYPE_MAVENPLUGIN. */
    public static final String PACKAGING_TYPE_MAVENPLUGIN = "maven-plugin";

    /** The Constant PACKAGING_TYPE_POM. */
    public static final String PACKAGING_TYPE_POM = "pom";

    /**
     * _get known repositories.
     *
     * @param embedder the maven implementation to use
     * @param packagingType the packaging type to filter by
     * @return A list of known repositories filtered by packaging type
     * @throws MavenEclipseApiException the maven eclipse api exception
     */
    protected List<ArtifactRepository> _getKnownRepositories(MavenImpl embedder, String packagingType)
            throws MavenEclipseApiException {
        if (embedder == null)
            throw new MavenEclipseApiException();

        try {
            Settings settings = embedder.getSettings();
            if (settings == null) {
                throw new MavenEclipseApiException(Messages.ERROR_NULL_SETTINGS);
            }
            return _getKnownRepositories(embedder.getPlexusContainer(), settings, packagingType);
        } catch (Exception anyEx) {
            anyEx.printStackTrace();
            throw new MavenEclipseApiException(anyEx);
        }
    }

    /**
     * Return the Maven remote repositories defined in the Maven settings.xml
     * file. The returned list of repositories depend on the pacakgeType.
     * 
     * For <code>maven-plugin</code> package type, it will return
     * pluginRepositories, and all other types will return Mirrors and
     * Repositories.
     *
     * @param plexus the plexus
     * @param settings the settings.xml file to use
     * @param packagingType the pom packaging type to return.
     * @return the remote repositories defined in the Maven settings.xml file.
     * @throws MavenEclipseApiException the maven eclipse api exception
     */
    protected List<ArtifactRepository> _getKnownRepositories(PlexusContainer plexus, Settings settings,
            String packagingType) throws MavenEclipseApiException {
        final boolean needPluginRepo = PACKAGING_TYPE_MAVENPLUGIN.equalsIgnoreCase(packagingType);
        if (settings == null) {
            throw new MavenEclipseApiException(Messages.ERROR_NULL_SETTINGS);
        }

        List<String> activeProfiles = (List<String>) settings.getActiveProfiles();
        if (activeProfiles == null || activeProfiles.size() < 1) {
            throw new MavenEclipseApiException(Messages.ERROR_NO_ACTIVE_PROFILES);
        }

        List<ArtifactRepository> repositories = new ArrayList<ArtifactRepository>(8);
        try {
            // MavenTools mtools = (MavenTools) plexus
            // .lookup(org.apache.maven.MavenTools.class);
            RepositorySystem rs = plexus.lookup(RepositorySystem.class);
            if (needPluginRepo == false) {
                for (Mirror mirror : (List<Mirror>) settings.getMirrors()) {
                    final org.apache.maven.model.Repository repo = new org.apache.maven.model.Repository();
                    repo.setId(mirror.getId());
                    // repo.setModelEncoding(mirror.getModelEncoding());
                    repo.setUrl(mirror.getUrl());
                    final RepositoryPolicy snapshotPolicty = new RepositoryPolicy();
                    snapshotPolicty.setEnabled(false);
                    // snapshotPolicty.setModelEncoding(mirror.getModelEncoding());
                    repo.setSnapshots(snapshotPolicty);
                    final RepositoryPolicy releasedPolicty = new RepositoryPolicy();
                    releasedPolicty.setEnabled(true);
                    // releasedPolicty.setModelEncoding(mirror.getModelEncoding());
                    repo.setReleases(releasedPolicty);
                    // repositories.add(mtools.buildArtifactRepository(repo));
                    repositories.add(rs.buildArtifactRepository(repo));
                }
            }

            List<Profile> profiles = (List<Profile>) settings.getProfiles();
            for (Profile p : profiles) {
                if (activeProfiles.contains(p.getId())) {
                    org.apache.maven.model.Profile mp = SettingsUtils.convertFromSettingsProfile(p);
                    if (needPluginRepo == true) {
                        // requires plugin repositories
                        final List<org.apache.maven.model.Repository> pluginRepos = mp.getPluginRepositories();
                        // repositories
                        // .addAll((List<ArtifactRepository>) mtools
                        // .buildArtifactRepositories(pluginRepos));
                        for (org.apache.maven.model.Repository repo : pluginRepos) {
                            repositories.add(rs.buildArtifactRepository(repo));
                        }
                    } else {
                        final List<org.apache.maven.model.Repository> repos = mp.getRepositories();
                        // repositories
                        // .addAll((List<ArtifactRepository>) mtools
                        // .buildArtifactRepositories(repos));
                        for (org.apache.maven.model.Repository repo : repos) {
                            repositories.add(rs.buildArtifactRepository(repo));
                        }
                    }
                }
            }
            return repositories;

        } catch (Exception anyEx) {
            anyEx.printStackTrace();
            throw new MavenEclipseApiException(anyEx);
        }
    }

    /**
     * Resolve an artifact using a particular maven implementation and repository.
     *
     * @param embedder the embedded version of maven to use
     * @param repoSystem the repository to resolve against
     * @param md the artifact metadata to search
     * @return the resolved artifact
     * @throws MavenEclipseApiException the maven eclipse api exception
     */
    public Artifact resolveArtifact(MavenImpl embedder, RepositorySystem repoSystem, ArtifactMetadata md)
            throws MavenEclipseApiException {
        if (embedder == null)
            throw new MavenEclipseApiException();

        try {
            List<ArtifactRepository> repos = _getKnownRepositories(embedder, md.getType());
            if (repos == null || repos.size() < 1) {
                throw new MavenEclipseApiException(Messages.ERROR_NO_REPOSITORIES);
            }

            Artifact artifact = null;

            if (md.getClassifier() == null)
                artifact = repoSystem.createArtifact(md.getGroupId(), md.getArtifactId(), md.getVersion(),
                        md.getScope(), md.getType());
            else
                artifact = repoSystem.createArtifactWithClassifier(md.getGroupId(), md.getArtifactId(),
                        md.getVersion(), md.getType(), md.getClassifier());

            if (artifact == null) {
                throw new MavenEclipseApiException(Messages.ERROR_NULL_ARTIFACT);
            }

            // embedder.resolve(artifact, repos, embedder.getLocalRepository());
            MavenApiUtil.resolveArtifact(repoSystem, artifact, embedder.getLocalRepository(), repos);

            return artifact;
        } catch (Exception e) {
            e.printStackTrace();
            throw new MavenEclipseApiException(e);
        }
    }

    private static void resolveArtifactAsClasspath(final MetadataTreeNode treeNode, final ArtifactScopeEnum scope,
            final Map<String, ArtifactMetadata> metadatas) {
        final ArtifactMetadata md = treeNode.getMd();
        if (metadatas.containsKey(md.toString()) == false && scope.equals(md.getScopeAsEnum())
                && md.getGroupId() != null) {
            metadatas.put(md.toString(), md);
            if (treeNode.getChildren() != null) {
                for (final MetadataTreeNode child : treeNode.getChildren()) {
                    resolveArtifactAsClasspath(child, scope, metadatas);
                }
            }
        }
    }

    private void resolveArtifactDependencies(MavenImpl embedder, RepositorySystem repoSystem, Artifact artifact,
            Set<Artifact> result) throws MavenEclipseApiException {
        try {
            MavenProject mProject = resolveArtifactAsProject(artifact);
            for (Dependency dep : mProject.getDependencies()) {
                ArtifactScopeEnum scope = ArtifactScopeEnum.valueOf(dep.getScope());
                if (ArtifactScopeEnum.test.equals(scope) == false) {
                    Artifact art = resolveArtifact(embedder, repoSystem,
                            new EclipseArtifactMetadata(dep.getGroupId(), dep.getArtifactId(), dep.getVersion(),
                                    dep.getType(), scope, dep.getClassifier()));
                    if (result.contains(art) == false) {
                        result.add(art);
                        resolveArtifactDependencies(embedder, repoSystem, art, result);
                    }
                }
            }
        } catch (Exception e) {
            //ignore this one
        }
    }

    /**
     * Returns a list of Artifacts.
     *
     * @param embedder the maven implementation to use.
     * @param md the artifact meta data.
     * @return A list of Artifacts that were resolved.
     * @throws MavenEclipseApiException the maven eclipse api exception
     */
    public List<Artifact> resolveArtifactAsClasspath(MavenImpl embedder, ArtifactMetadata md)
            throws MavenEclipseApiException {
        List<Artifact> result = new ArrayList<Artifact>();
        try {
            if (embedder == null)
                throw new MavenEclipseApiException("null embedder supplied");

            if (md == null)
                throw new MavenEclipseApiException("null metadata object supplied");
            //FIXME below is a temp fix for the NPE from M2Eclipse, lets do this flow approach for now
            RepositorySystem repoSystem = MavenApiHelper.getRepositorySystem();
            Set<Artifact> data = new HashSet<Artifact>();
            Artifact artifact = resolveArtifact(embedder, repoSystem, md);
            data.add(artifact);
            resolveArtifactDependencies(embedder, repoSystem, artifact, data);
            result.addAll(ListUtil.array(data));
        } catch (Exception e) {
            e.printStackTrace();
            throw new MavenEclipseApiException(e);
        }
        return result;

    }

    /**
     * Resolves the artifact Metadata from the repository.
     *
     * @param embedder the maven implementation to use
     * @param md the artifact metadata
     * @return the MetadataResolutionResult
     * @throws MavenEclipseApiException the maven eclipse api exception
     */
    protected MetadataResolutionResult resolveArtifactMetadata(MavenImpl embedder, ArtifactMetadata md)
            throws MavenEclipseApiException {
        if (embedder == null)
            throw new MavenEclipseApiException("null embedder supplied");

        if (md == null)
            throw new MavenEclipseApiException("null metadata object supplied");

        try {
            List<ArtifactRepository> repos = _getKnownRepositories(embedder, md.getType());
            if (repos == null || repos.size() < 1) {
                throw new MavenEclipseApiException(Messages.ERROR_NO_REPOSITORIES);
            }

            //PlexusContainer plexus = embedder.getPlexusContainer();
            ArtifactRepository localRepository = MavenPlugin.getDefault().getMaven().getLocalRepository();
            List<ArtifactRepository> remoteRepositories = _getKnownRepositories(embedder, md.getType());

            MetadataResolutionRequest req = new MetadataResolutionRequest(md, localRepository, remoteRepositories);
            MetadataResolutionResult res = MavenApiUtil.resolveMetadata(MavenApiHelper.getRepositorySystem(), req);

            return res;

        } catch (Exception e) {
            e.printStackTrace();
            throw new MavenEclipseApiException(e);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Model parsePom(final File file) throws MavenEclipseApiException {
        try {
            return MavenPlugin.getDefault().getMaven().readModel(file);
        } catch (Exception ex) {
            throw new MavenEclipseApiException(ex);
        }
    }

}