View Javadoc
1   package org.apache.maven.plugins.assembly.repository;
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.io.File;
23  import java.io.IOException;
24  import java.util.ArrayList;
25  import java.util.Collection;
26  import java.util.HashMap;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.Set;
30  
31  import org.apache.maven.artifact.Artifact;
32  import org.apache.maven.artifact.resolver.filter.AndArtifactFilter;
33  import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
34  import org.apache.maven.model.Dependency;
35  import org.apache.maven.plugins.assembly.repository.model.GroupVersionAlignment;
36  import org.apache.maven.plugins.assembly.repository.model.RepositoryInfo;
37  import org.apache.maven.project.MavenProject;
38  import org.apache.maven.project.ProjectBuildingRequest;
39  import org.apache.maven.shared.artifact.TransferUtils;
40  import org.apache.maven.shared.artifact.filter.PatternExcludesArtifactFilter;
41  import org.apache.maven.shared.artifact.filter.PatternIncludesArtifactFilter;
42  import org.apache.maven.shared.artifact.filter.ScopeArtifactFilter;
43  import org.apache.maven.shared.artifact.resolve.ArtifactResolver;
44  import org.apache.maven.shared.artifact.resolve.ArtifactResolverException;
45  import org.apache.maven.shared.artifact.resolve.ArtifactResult;
46  import org.apache.maven.shared.dependencies.resolve.DependencyResolver;
47  import org.apache.maven.shared.dependencies.resolve.DependencyResolverException;
48  import org.apache.maven.shared.repository.RepositoryManager;
49  import org.apache.maven.shared.utils.io.FileUtils;
50  import org.codehaus.plexus.component.annotations.Component;
51  import org.codehaus.plexus.component.annotations.Requirement;
52  import org.codehaus.plexus.logging.AbstractLogEnabled;
53  import org.codehaus.plexus.logging.Logger;
54  
55  /**
56   * @author Jason van Zyl
57   */
58  
59  // todo will need to pop the processed project cache using reflection
60  @Component( role = RepositoryAssembler.class )
61  public class DefaultRepositoryAssembler
62      extends AbstractLogEnabled
63      implements RepositoryAssembler
64  {
65      @Requirement
66      protected ArtifactResolver artifactResolver;
67  
68      @Requirement
69      private DependencyResolver dependencyResolver;
70  
71      @Requirement
72      private RepositoryManager repositoryManager;
73  
74      public void buildRemoteRepository( File repositoryDirectory, RepositoryInfo repository,
75                                         RepositoryBuilderConfigSource configSource )
76                                             throws RepositoryAssemblyException
77      {
78          MavenProject project = configSource.getProject();
79          ProjectBuildingRequest buildingRequest = configSource.getProjectBuildingRequest();
80  
81          Iterable<ArtifactResult> result = null;
82  
83          Collection<Dependency> dependencies = project.getDependencies();
84  
85          if ( dependencies == null )
86          {
87              Logger logger = getLogger();
88  
89              if ( logger.isDebugEnabled() )
90              {
91                  logger.debug( "dependency-artifact set for project: " + project.getId()
92                      + " is null. Skipping repository processing." );
93              }
94  
95              return;
96          }
97  
98          Collection<Dependency> managedDependencies = null;
99          if ( project.getDependencyManagement() != null )
100         {
101             managedDependencies = project.getDependencyManagement().getDependencies();
102         }
103 
104         // Older Aether versions use an cache which can't be cleared. So can't delete repoDir and use it again.
105         // Instead create a temporary repository, delete it at end (should be in a finally-block)
106 
107         File tempRepo = new File( repositoryDirectory.getParentFile(), repositoryDirectory.getName() + "_tmp" );
108 
109         buildingRequest = repositoryManager.setLocalRepositoryBasedir( buildingRequest, tempRepo );
110 
111         try
112         {
113             result = dependencyResolver.resolveDependencies( buildingRequest, dependencies, managedDependencies, null );
114         }
115         catch ( DependencyResolverException e )
116         {
117             throw new RepositoryAssemblyException( "Error resolving artifacts: " + e.getMessage(), e );
118         }
119 
120         ArtifactFilter filter = buildRepositoryFilter( repository, project );
121 
122         buildingRequest = repositoryManager.setLocalRepositoryBasedir( buildingRequest, repositoryDirectory );
123 
124         Map<String, GroupVersionAlignment> groupVersionAlignments =
125             createGroupVersionAlignments( repository.getGroupVersionAlignments() );
126 
127         assembleRepositoryArtifacts( buildingRequest, result, filter, groupVersionAlignments );
128 
129         if ( repository.isIncludeMetadata() )
130         {
131 //            assembleRepositoryMetadata( result, filter, centralRepository, targetRepository );
132         }
133 
134         try
135         {
136             FileUtils.deleteDirectory( tempRepo );
137         }
138         catch ( IOException e )
139         {
140             // noop
141         }
142     }
143 
144     private ArtifactFilter buildRepositoryFilter( RepositoryInfo repository, MavenProject project )
145     {
146         AndArtifactFilter filter = new AndArtifactFilter();
147 
148         ArtifactFilter scopeFilter = new ScopeArtifactFilter( repository.getScope() );
149         filter.add( scopeFilter );
150 
151         // ----------------------------------------------------------------------------
152         // Includes
153         //
154         // We'll take everything if no includes are specified to try and make
155         // this
156         // process more maintainable. Don't want to have to update the assembly
157         // descriptor everytime the POM is updated.
158         // ----------------------------------------------------------------------------
159 
160         List<String> includes = repository.getIncludes();
161 
162         if ( ( includes == null ) || includes.isEmpty() )
163         {
164             List<String> patterns = new ArrayList<String>();
165 
166             Set<Artifact> projectArtifacts = project.getDependencyArtifacts();
167 
168             if ( projectArtifacts != null )
169             {
170                 for ( Artifact artifact : projectArtifacts )
171                 {
172                     patterns.add( artifact.getDependencyConflictId() );
173                 }
174             }
175 
176             PatternIncludesArtifactFilter includeFilter = new PatternIncludesArtifactFilter( patterns, true );
177 
178             filter.add( includeFilter );
179         }
180         else
181         {
182             filter.add( new PatternIncludesArtifactFilter( repository.getIncludes(), true ) );
183         }
184 
185         // ----------------------------------------------------------------------------
186         // Excludes
187         //
188         // We still want to make it easy to exclude a few things even if we
189         // slurp
190         // up everything.
191         // ----------------------------------------------------------------------------
192 
193         List<String> excludes = repository.getExcludes();
194 
195         if ( ( excludes != null ) && !excludes.isEmpty() )
196         {
197             filter.add( new PatternExcludesArtifactFilter( repository.getExcludes(), true ) );
198         }
199 
200         return filter;
201     }
202 
203     private void assembleRepositoryArtifacts( ProjectBuildingRequest buildingRequest, Iterable<ArtifactResult> result,
204                                               ArtifactFilter filter,
205                                               Map<String, GroupVersionAlignment> groupVersionAlignments )
206                                                   throws RepositoryAssemblyException
207     {
208         try
209         {
210             for ( ArtifactResult ar : result )
211             {
212                 Artifact a = ar.getArtifact();
213 
214                 if ( filter.include( a ) )
215                 {
216                     getLogger().debug( "Re-resolving: " + a + " for repository assembly." );
217 
218                     setAlignment( a, groupVersionAlignments );
219 
220                     artifactResolver.resolveArtifact( buildingRequest, TransferUtils.toArtifactCoordinate( a ) );
221 
222                     a.setVersion( a.getBaseVersion() );
223 
224                     File targetFile = new File( repositoryManager.getLocalRepositoryBasedir( buildingRequest ),
225                                                 repositoryManager.getPathForLocalArtifact( buildingRequest, a ) );
226                     
227                     FileUtils.copyFile( a.getFile(), targetFile );
228 
229 //                    writeChecksums( targetFile );
230                 }
231             }
232         }
233         catch ( ArtifactResolverException e )
234         {
235             throw new RepositoryAssemblyException( "Error resolving artifacts: " + e.getMessage(), e );
236         }
237         catch ( IOException e )
238         {
239             throw new RepositoryAssemblyException( "Error writing artifact metdata.", e );
240         }
241     }
242 
243     // CHECKSTYLE_OFF: LineLength
244     protected Map<String, GroupVersionAlignment> createGroupVersionAlignments( List<GroupVersionAlignment> versionAlignments )
245     // CHECKSTYLE_ON: LineLength
246     {
247         Map<String, GroupVersionAlignment> groupVersionAlignments = new HashMap<String, GroupVersionAlignment>();
248 
249         if ( versionAlignments != null )
250         {
251             for ( GroupVersionAlignment alignment : versionAlignments )
252             {
253                 groupVersionAlignments.put( alignment.getId(), alignment );
254             }
255         }
256 
257         return groupVersionAlignments;
258     }
259 
260     private void setAlignment( Artifact artifact, Map<String, GroupVersionAlignment> groupVersionAlignments )
261     {
262         GroupVersionAlignment alignment = groupVersionAlignments.get( artifact.getGroupId() );
263 
264         if ( alignment != null )
265         {
266             if ( !alignment.getExcludes().contains( artifact.getArtifactId() ) )
267             {
268                 artifact.setVersion( alignment.getVersion() );
269             }
270         }
271     }
272 }