Package com.chaschev.install.jcabi

Source Code of com.chaschev.install.jcabi.Aether

/**
* Copyright (c) 2012-2013, JCabi.com
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met: 1) Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer. 2) Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution. 3) Neither the name of the jcabi.com nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.chaschev.install.jcabi;

import com.chaschev.chutils.util.Exceptions;
import com.jcabi.aspects.Loggable;
import com.jcabi.log.Logger;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.apache.maven.project.MavenProject;
import org.apache.maven.repository.internal.MavenRepositorySystemSession;
import org.sonatype.aether.RepositorySystem;
import org.sonatype.aether.RepositorySystemSession;
import org.sonatype.aether.artifact.Artifact;
import org.sonatype.aether.collection.CollectRequest;
import org.sonatype.aether.graph.Dependency;
import org.sonatype.aether.graph.DependencyFilter;
import org.sonatype.aether.repository.Authentication;
import org.sonatype.aether.repository.LocalRepository;
import org.sonatype.aether.repository.RemoteRepository;
import org.sonatype.aether.resolution.*;
import org.sonatype.aether.util.filter.DependencyFilterUtils;

import javax.annotation.Nonnull;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

/**
* Resolver of dependencies for one artifact.
* <p/>
* <p>You need the following dependencies to have in classpath in order to
* to work with this class:
* <p/>
* <pre>
* org.sonatype.aether:aether-api:1.13.1
* org.apache.maven:maven-core:3.0.3
* </pre>
*
* @author Yegor Bugayenko (yegor@tpc2.com)
* @version $Id$
* @checkstyle ClassDataAbstractionCoupling (500 lines)
* @todo #143 This class should be @Immutable, but RemoteRepository is
* not immutable. Let's create a new class to encapsulate all necessary
* properties from RemoteRepository.
* @see <a href="http://sonatype.github.com/sonatype-aether/apidocs/overview-tree.html">Aether 1.13.1 JavaDoc</a>
* @see com.jcabi.aether.Classpath
* @since 0.1.6
*/
@ToString
@EqualsAndHashCode(of = {"remotes", "localRepo"})
@Loggable(Loggable.DEBUG)
public final class Aether {

    /**
     * Remote project repositories.
     */
    private final transient RemoteRepository[] remotes;

    /**
     * Location of local repository.
     */
    private final transient File localRepo;

    /**
     * Repository system.
     */
    private final transient RepositorySystem system =
        new RepositorySystemBuilder().build();

    /**
     * Public ctor, requires information about all remote repositories and one
     * local.
     *
     * @param prj  The Maven project
     * @param repo Local repository location (directory path)
     */
    public Aether(@Nonnull final MavenProject prj, @Nonnull final File repo) {
        this(prj.getRemoteProjectRepositories(), repo);
    }

    /**
     * Public ctor, requires information about all remote repositories and one
     * local.
     *
     * @param repos Collection of remote repositories
     * @param repo  Local repository location (directory path)
     * @since 0.8
     */
    public Aether(@Nonnull final Collection<RemoteRepository> repos,
                  @Nonnull final File repo) {
        this.remotes = repos.toArray(new RemoteRepository[]{});
        this.localRepo = repo;
    }

    /**
     * List of transitive dependencies of the artifact.
     *
     *
     * @param root  The artifact to work with
     * @param scope The scope to work with ("runtime", "test", etc.)
     * @return The list of dependencies
     * @throws org.sonatype.aether.resolution.DependencyResolutionException
     *          If can't fetch it
     * @todo #51 This "filter IF NOT NULL" validation is a workaround,
     * since I don't
     * know what the actual problem is. Looks like sometimes (for some unknown
     * reason) #classpathFilter() returns NULL. When exactly this may happen
     * I have no idea. That's why this workaround. Sometime later we should
     * do a proper testing and reproduce this defect in a test.
     */
    public DependencyResult resolve(@Nonnull final Artifact root,
                                    @Nonnull final String scope) throws DependencyResolutionException {
        final DependencyFilter filter =
            DependencyFilterUtils.classpathFilter(scope);

        if (filter == null) {
            throw new IllegalStateException(
                String.format("failed to create a filter for '%s'", scope)
            );
        }

        return this.resolve(root, scope, filter);
    }

    /**
     * List of transitive dependencies of the artifact.
     *
     * @param root   The artifact to work with
     * @param scope  The scope to work with ("runtime", "test", etc.)
     * @param filter The dependency filter to work with
     * @return The list of dependencies
     * @throws org.sonatype.aether.resolution.DependencyResolutionException
     *          If can't fetch it
     */
    public DependencyResult resolve(
        @Nonnull final Artifact root,
        @Nonnull final String scope, @Nonnull final DependencyFilter filter) throws DependencyResolutionException {
        final Dependency rdep = new Dependency(root, scope);
        final CollectRequest crq = this.request(rdep);

        return this.fetch(
            this.session(),
            new DependencyRequest(crq, filter)
        );
    }

    /**
     * Fetch dependencies.
     *
     * @param session The session
     * @param dreq    Dependency request
     * @return The list of dependencies
     * @throws org.sonatype.aether.resolution.DependencyResolutionException
     *          If can't fetch it
     * @todo #51 This catch of NPE is a temporary measure. I don't know why
     * Aether throws NPE in case of non-resolvable artifact. This is the best
     * I can do at the moment in order to protect clients of the class.
     */
    @SuppressWarnings("PMD.AvoidCatchingGenericException")
    private DependencyResult fetch(
        final RepositorySystemSession session,
        final DependencyRequest dreq) throws DependencyResolutionException {
        synchronized (this.localRepo) {
            return this.system
                .resolveDependencies(session, dreq);
        }
    }

    /**
     * Create collect request.
     *
     * @param root The root to start with
     * @return The request
     */
    private CollectRequest request(final Dependency root) {
        final CollectRequest request = new CollectRequest();
        request.setRoot(root);
        for (RemoteRepository repo : this.remotes) {
            if (!repo.getProtocol().matches("https?|file|s3")) {
                Logger.warn(
                    this,
                    "%s ignored (only S3, HTTP/S, and FILE are supported)",
                    repo
                );
                continue;
            }
            request.addRepository(repo);
        }
        return request;
    }

    /**
     * Convert a list of repositories into a list of strings.
     *
     * @param repos The list of them
     * @return The list of texts
     */
    private static Collection<String> reps(
        final Collection<RemoteRepository> repos) {
        final Collection<String> texts = new ArrayList<String>(repos.size());
        final StringBuilder text = new StringBuilder();
        for (RemoteRepository repo : repos) {
            final Authentication auth = repo.getAuthentication();
            text.setLength(0);
            text.append(repo.toString());
            if (auth == null) {
                text.append(" without authentication");
            } else {
                text.append(" with ").append(auth.toString());
            }
            texts.add(text.toString());
        }
        return texts;
    }

    /**
     * Create RepositorySystemSession.
     *
     * @return The session
     */
    private RepositorySystemSession session() {
        final LocalRepository local = new LocalRepository(this.localRepo);
        final MavenRepositorySystemSession session =
            new MavenRepositorySystemSession();
        session.setLocalRepositoryManager(
            this.system.newLocalRepositoryManager(local)
        );
        session.setTransferListener(new LogTransferListener());
        return session;
    }

    public VersionRangeResult getVersions(Artifact artifact) {
        try {
            VersionRangeRequest rangeRequest = new VersionRangeRequest();
            rangeRequest.setArtifact(artifact);

            for (RemoteRepository remote : remotes) {
                rangeRequest.addRepository(remote);

            }

            return system.resolveVersionRange(session(), rangeRequest);
        } catch (VersionRangeResolutionException e) {
            throw Exceptions.runtime(e);
        }
    }


}
TOP

Related Classes of com.chaschev.install.jcabi.Aether

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.