/*
 * JBoss, Home of Professional Open Source
 * Copyright 2013, Red Hat Middleware LLC, and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * 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.jboss.shrinkwrap.resolver.impl.maven.bootstrap;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.maven.settings.Settings;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.collection.CollectRequest;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.graph.DependencyNode;
import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.resolution.DependencyRequest;
import org.eclipse.aether.resolution.DependencyResolutionException;
import org.eclipse.aether.resolution.DependencyResult;
import org.eclipse.aether.resolution.VersionRangeRequest;
import org.eclipse.aether.resolution.VersionRangeResolutionException;
import org.eclipse.aether.resolution.VersionRangeResult;
import org.jboss.shrinkwrap.resolver.api.maven.MavenWorkingSession;
import org.jboss.shrinkwrap.resolver.api.maven.coordinate.MavenDependency;
import org.jboss.shrinkwrap.resolver.api.maven.filter.MavenResolutionFilter;
import org.jboss.shrinkwrap.resolver.impl.maven.convert.MavenConverter;

Abstraction of the repository system for purposes of dependency resolution used by Maven
Author:Karel Piwko, Michal Matloka
/** * Abstraction of the repository system for purposes of dependency resolution used by Maven * * @author <a href="mailto:kpiwko@redhat.com">Karel Piwko</a> * @author <a href="mailto:mmatloka@gmail.com">Michal Matloka</a> */
public class MavenRepositorySystem { private final RepositorySystem system;
Creates a Maven repository system
/** * Creates a Maven repository system */
public MavenRepositorySystem() { this.system = getRepositorySystem(); }
Spawns a working session from the repository system. This is used to as environment for execution of Maven commands
Params:
  • settings – A configuration of current session
  • legacyLocalRepository – Whether to ignore origin of artifacts in local repository; defaults to false
Returns:A working session spawned from the repository system.
/** * Spawns a working session from the repository system. This is used to as environment for execution of Maven * commands * * @param settings * A configuration of current session * @param legacyLocalRepository * Whether to ignore origin of artifacts in local repository; defaults to false * @return A working session spawned from the repository system. */
public DefaultRepositorySystemSession getSession(final Settings settings, boolean legacyLocalRepository) { DefaultRepositorySystemSession session = new DefaultRepositorySystemSession(); MavenManagerBuilder builder = new MavenManagerBuilder(system, settings); session.setLocalRepositoryManager(builder.localRepositoryManager(session, legacyLocalRepository)); session.setWorkspaceReader(builder.workspaceReader()); session.setTransferListener(builder.transferListerer()); session.setRepositoryListener(builder.repositoryListener()); session.setOffline(settings.isOffline()); session.setMirrorSelector(builder.mirrorSelector()); session.setProxySelector(builder.proxySelector()); session.setDependencyManager(builder.dependencyManager()); session.setArtifactDescriptorPolicy(builder.artifactRepositoryPolicy()); session.setDependencyTraverser(builder.dependencyTraverser()); session.setDependencyGraphTransformer(builder.dependencyGraphTransformer()); // set artifact stereotypes session.setArtifactTypeRegistry(builder.artifactTypeRegistry()); // set system properties for interpolation session.setSystemProperties(SecurityActions.getProperties()); session.setConfigProperties(SecurityActions.getProperties()); return session; }
Resolves artifact dependencies. The ArtifactResult contains a reference to a file in Maven local repository.
Params:
  • repoSession – The current Maven session
  • swrSession – SWR Aether session abstraction
  • request – The request to be computed
  • filters – The filters of dependency results
Throws:
Returns:A collection of artifacts which have built dependency tree from request
/** * Resolves artifact dependencies. * * The {@link ArtifactResult} contains a reference to a file in Maven local repository. * * @param repoSession The current Maven session * @param swrSession SWR Aether session abstraction * @param request The request to be computed * @param filters The filters of dependency results * @return A collection of artifacts which have built dependency tree from {@code request} * @throws DependencyResolutionException If a dependency could not be computed or collected */
public Collection<ArtifactResult> resolveDependencies(final RepositorySystemSession repoSession, final MavenWorkingSession swrSession, final CollectRequest request, final MavenResolutionFilter[] filters) throws DependencyResolutionException { final DependencyRequest depRequest = new DependencyRequest(request, new MavenResolutionFilterWrap(filters, Collections.unmodifiableList(new ArrayList<MavenDependency>(swrSession.getDependenciesForResolution())))); DependencyResult result = system.resolveDependencies(repoSession, depRequest); return result.getArtifactResults(); }
Resolves an artifact
Params:
  • session – The current Maven session
  • request – The request to be computed
Throws:
Returns:The artifact
/** * Resolves an artifact * * @param session The current Maven session * @param request The request to be computed * @return The artifact * @throws ArtifactResolutionException If the artifact could not be fetched */
public ArtifactResult resolveArtifact(final RepositorySystemSession session, final ArtifactRequest request) throws ArtifactResolutionException { return system.resolveArtifact(session, request); }
Resolves versions range
Params:
  • session – The current Maven session
  • request – The request to be computed
Throws:
Returns:version range result
/** * Resolves versions range * * @param session The current Maven session * @param request The request to be computed * @return version range result * @throws VersionRangeResolutionException * If the requested range could not be parsed. Note that an empty range does not raise an exception. * */
public VersionRangeResult resolveVersionRange(final RepositorySystemSession session, final VersionRangeRequest request) throws VersionRangeResolutionException { return system.resolveVersionRange(session, request); }
Finds a current implementation of repository system. A RepositorySystem is an entry point to dependency resolution
Throws:
Returns:A repository system
/** * Finds a current implementation of repository system. A {@link RepositorySystem} is an entry point to dependency * resolution * * @return A repository system * @throws UnsupportedOperationException if {@link RepositorySystem} was not bootstrapped correctly */
private RepositorySystem getRepositorySystem() throws UnsupportedOperationException { final ShrinkWrapResolverServiceLocator locator = new ShrinkWrapResolverServiceLocator(); // if running from inside plugin, we required Maven 3.1.0 or newer // that happens because Maven handles Aether dependencies in plugins a special way so we can't provide our own // implementation, it is simply removed from classpath and not available at all // // locator will throw an exception if repository system cannot be set up return locator.getService(RepositorySystem.class); } } class MavenResolutionFilterWrap implements org.eclipse.aether.graph.DependencyFilter { private static final Logger log = Logger.getLogger(MavenResolutionFilterWrap.class.getName()); private final MavenResolutionFilter[] filters; private final List<MavenDependency> dependenciesForResolution; MavenResolutionFilterWrap(final MavenResolutionFilter[] filters, final List<MavenDependency> dependenciesForResolution) { assert filters != null : "filters must be specified, even if empty"; assert dependenciesForResolution != null : "declaredDependencies must be specified"; this.dependenciesForResolution = dependenciesForResolution; this.filters = filters; }
{@inheritDoc}
See Also:
/** * {@inheritDoc} * * @see org.eclipse.aether.graph.DependencyFilter#accept(org.eclipse.aether.graph.DependencyNode, java.util.List) */
@Override public boolean accept(final DependencyNode node, List<DependencyNode> parents) { Dependency dependency = node.getDependency(); if (dependency == null) { return false; } List<MavenDependency> ancestors = new ArrayList<MavenDependency>(); for (DependencyNode parent : parents) { Dependency parentDependency = parent.getDependency(); if (parentDependency != null) { ancestors.add(MavenConverter.fromDependency(parentDependency)); } } if (log.isLoggable(Level.FINER)) { log.log(Level.FINER, "Filtering {0} using {1} filters", new Object[] { dependency, filters.length }); } for (final MavenResolutionFilter filter : filters) { if (!filter.accepts(MavenConverter.fromDependency(dependency), dependenciesForResolution, ancestors)) { if (log.isLoggable(Level.FINER)) { log.log(Level.FINER, "Dependency {0} rejected by {1}", new Object[] { dependency, filter }); } return false; } } // All filters passed if (log.isLoggable(Level.FINER)) { log.log(Level.FINER, "Dependency {0} was accepted.", dependency); } return true; } }