View Javadoc

1   package org.apache.maven.plugin.internal;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.List;
23  
24  import org.apache.maven.ArtifactFilterManager;
25  import org.apache.maven.RepositoryUtils;
26  import org.apache.maven.model.Dependency;
27  import org.apache.maven.model.Plugin;
28  import org.apache.maven.plugin.PluginResolutionException;
29  import org.codehaus.plexus.component.annotations.Component;
30  import org.codehaus.plexus.component.annotations.Requirement;
31  import org.codehaus.plexus.logging.Logger;
32  import org.sonatype.aether.RepositorySystem;
33  import org.sonatype.aether.RepositorySystemSession;
34  import org.sonatype.aether.artifact.Artifact;
35  import org.sonatype.aether.collection.CollectRequest;
36  import org.sonatype.aether.collection.DependencyCollectionException;
37  import org.sonatype.aether.collection.DependencyGraphTransformer;
38  import org.sonatype.aether.collection.DependencySelector;
39  import org.sonatype.aether.graph.DependencyFilter;
40  import org.sonatype.aether.graph.DependencyNode;
41  import org.sonatype.aether.graph.DependencyVisitor;
42  import org.sonatype.aether.repository.RemoteRepository;
43  import org.sonatype.aether.resolution.ArtifactRequest;
44  import org.sonatype.aether.resolution.ArtifactResolutionException;
45  import org.sonatype.aether.util.DefaultRepositorySystemSession;
46  import org.sonatype.aether.util.artifact.DefaultArtifact;
47  import org.sonatype.aether.util.artifact.JavaScopes;
48  import org.sonatype.aether.util.filter.AndDependencyFilter;
49  import org.sonatype.aether.util.filter.ExclusionsDependencyFilter;
50  import org.sonatype.aether.util.filter.ScopeDependencyFilter;
51  import org.sonatype.aether.util.graph.selector.AndDependencySelector;
52  import org.sonatype.aether.util.graph.transformer.ChainedDependencyGraphTransformer;
53  
54  /**
55   * Assists in resolving the dependencies of a plugin. <strong>Warning:</strong> This is an internal utility class that
56   * is only public for technical reasons, it is not part of the public API. In particular, this class can be changed or
57   * deleted without prior notice.
58   * 
59   * @since 3.0
60   * @author Benjamin Bentmann
61   */
62  @Component( role = PluginDependenciesResolver.class )
63  public class DefaultPluginDependenciesResolver
64      implements PluginDependenciesResolver
65  {
66  
67      private static final String REPOSITORY_CONTEXT = "plugin";
68  
69      @Requirement
70      private Logger logger;
71  
72      @Requirement
73      private ArtifactFilterManager artifactFilterManager;
74  
75      @Requirement
76      private RepositorySystem repoSystem;
77  
78      private Artifact toArtifact( Plugin plugin, RepositorySystemSession session )
79      {
80          return new DefaultArtifact( plugin.getGroupId(), plugin.getArtifactId(), null, "jar", plugin.getVersion(),
81                                      session.getArtifactTypeRegistry().get( "maven-plugin" ) );
82      }
83  
84      public Artifact resolve( Plugin plugin, List<RemoteRepository> repositories, RepositorySystemSession session )
85          throws PluginResolutionException
86      {
87          Artifact pluginArtifact = toArtifact( plugin, session );
88  
89          try
90          {
91              ArtifactRequest request = new ArtifactRequest( pluginArtifact, repositories, REPOSITORY_CONTEXT );
92              pluginArtifact = repoSystem.resolveArtifact( session, request ).getArtifact();
93          }
94          catch ( ArtifactResolutionException e )
95          {
96              throw new PluginResolutionException( plugin, e );
97          }
98  
99          return pluginArtifact;
100     }
101 
102     public DependencyNode resolve( Plugin plugin, Artifact pluginArtifact, DependencyFilter dependencyFilter,
103                                    List<RemoteRepository> repositories, RepositorySystemSession session )
104         throws PluginResolutionException
105     {
106         if ( pluginArtifact == null )
107         {
108             pluginArtifact = toArtifact( plugin, session );
109         }
110 
111         DependencyFilter collectionFilter = new ScopeDependencyFilter( "provided", "test" );
112 
113         DependencyFilter resolutionFilter =
114             new ExclusionsDependencyFilter( artifactFilterManager.getCoreArtifactExcludes() );
115         resolutionFilter = AndDependencyFilter.newInstance( resolutionFilter, dependencyFilter );
116         resolutionFilter = new AndDependencyFilter( collectionFilter, resolutionFilter );
117 
118         DependencyNode node;
119 
120         try
121         {
122             DependencySelector selector =
123                 AndDependencySelector.newInstance( session.getDependencySelector(), new WagonExcluder() );
124 
125             DependencyGraphTransformer transformer =
126                 ChainedDependencyGraphTransformer.newInstance( session.getDependencyGraphTransformer(),
127                                                                new PlexusUtilsInjector() );
128 
129             DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession( session );
130             pluginSession.setDependencySelector( selector );
131             pluginSession.setDependencyGraphTransformer( transformer );
132 
133             CollectRequest request = new CollectRequest();
134             request.setRequestContext( REPOSITORY_CONTEXT );
135             request.setRepositories( repositories );
136             request.setRoot( new org.sonatype.aether.graph.Dependency( pluginArtifact, null ) );
137             for ( Dependency dependency : plugin.getDependencies() )
138             {
139                 org.sonatype.aether.graph.Dependency pluginDep =
140                     RepositoryUtils.toDependency( dependency, session.getArtifactTypeRegistry() );
141                 if ( !JavaScopes.SYSTEM.equals( pluginDep.getScope() ) )
142                 {
143                     pluginDep = pluginDep.setScope( JavaScopes.RUNTIME );
144                 }
145                 request.addDependency( pluginDep );
146             }
147 
148             node = repoSystem.collectDependencies( pluginSession, request ).getRoot();
149 
150             if ( logger.isDebugEnabled() )
151             {
152                 node.accept( new GraphLogger() );
153             }
154 
155             repoSystem.resolveDependencies( session, node, resolutionFilter );
156         }
157         catch ( DependencyCollectionException e )
158         {
159             throw new PluginResolutionException( plugin, e );
160         }
161         catch ( ArtifactResolutionException e )
162         {
163             throw new PluginResolutionException( plugin, e );
164         }
165 
166         return node;
167     }
168 
169     class GraphLogger
170         implements DependencyVisitor
171     {
172 
173         private String indent = "";
174 
175         public boolean visitEnter( DependencyNode node )
176         {
177             StringBuilder buffer = new StringBuilder( 128 );
178             buffer.append( indent );
179             org.sonatype.aether.graph.Dependency dep = node.getDependency();
180             if ( dep != null )
181             {
182                 org.sonatype.aether.artifact.Artifact art = dep.getArtifact();
183 
184                 buffer.append( art );
185                 buffer.append( ':' ).append( dep.getScope() );
186 
187                 if ( node.getPremanagedScope() != null && !node.getPremanagedScope().equals( dep.getScope() ) )
188                 {
189                     buffer.append( " (scope managed from " ).append( node.getPremanagedScope() ).append( ")" );
190                 }
191 
192                 if ( node.getPremanagedVersion() != null && !node.getPremanagedVersion().equals( art.getVersion() ) )
193                 {
194                     buffer.append( " (version managed from " ).append( node.getPremanagedVersion() ).append( ")" );
195                 }
196             }
197 
198             logger.debug( buffer.toString() );
199             indent += "   ";
200             return true;
201         }
202 
203         public boolean visitLeave( DependencyNode node )
204         {
205             indent = indent.substring( 0, indent.length() - 3 );
206             return true;
207         }
208 
209     }
210 
211 }