View Javadoc

1   package org.apache.maven.report.projectinfo.dependencies;
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 org.apache.maven.artifact.Artifact;
23  import org.apache.maven.artifact.ArtifactUtils;
24  import org.apache.maven.artifact.factory.ArtifactFactory;
25  import org.apache.maven.artifact.manager.WagonConfigurationException;
26  import org.apache.maven.artifact.manager.WagonManager;
27  import org.apache.maven.artifact.metadata.ArtifactMetadata;
28  import org.apache.maven.artifact.repository.ArtifactRepository;
29  import org.apache.maven.artifact.repository.metadata.Metadata;
30  import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager;
31  import org.apache.maven.artifact.repository.metadata.RepositoryMetadataResolutionException;
32  import org.apache.maven.artifact.repository.metadata.SnapshotArtifactRepositoryMetadata;
33  import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
34  import org.apache.maven.artifact.resolver.ArtifactResolutionException;
35  import org.apache.maven.artifact.resolver.ArtifactResolver;
36  import org.apache.maven.plugin.logging.Log;
37  import org.apache.maven.project.MavenProject;
38  import org.apache.maven.project.MavenProjectBuilder;
39  import org.apache.maven.project.ProjectBuildingException;
40  import org.apache.maven.settings.Proxy;
41  import org.apache.maven.settings.Settings;
42  import org.apache.maven.wagon.ConnectionException;
43  import org.apache.maven.wagon.TransferFailedException;
44  import org.apache.maven.wagon.UnsupportedProtocolException;
45  import org.apache.maven.wagon.Wagon;
46  import org.apache.maven.wagon.authentication.AuthenticationException;
47  import org.apache.maven.wagon.authentication.AuthenticationInfo;
48  import org.apache.maven.wagon.authorization.AuthorizationException;
49  import org.apache.maven.wagon.observers.Debug;
50  import org.apache.maven.wagon.proxy.ProxyInfo;
51  import org.apache.maven.wagon.repository.Repository;
52  import org.codehaus.plexus.logging.Logger;
53  import org.codehaus.plexus.logging.LoggerManager;
54  import org.codehaus.plexus.util.StringUtils;
55  
56  import java.util.ArrayList;
57  import java.util.Iterator;
58  import java.util.List;
59  
60  /**
61   * Utilities methods to play with repository
62   *
63   * @version $Id: RepositoryUtils.java 794049 2009-07-14 20:10:35Z dennisl $
64   * @since 2.1
65   */
66  public class RepositoryUtils
67  {
68      private final Log log;
69  
70      private final LoggerManager loggerManager;
71  
72      private final WagonManager wagonManager;
73  
74      private final Settings settings;
75  
76      private final MavenProjectBuilder mavenProjectBuilder;
77  
78      private final ArtifactFactory factory;
79  
80      private final List remoteRepositories;
81  
82      private final List pluginRepositories;
83  
84      private final ArtifactResolver resolver;
85  
86      private final ArtifactRepository localRepository;
87  
88      private final RepositoryMetadataManager repositoryMetadataManager;
89  
90      /**
91       * @param log
92       * @param loggerManager
93       * @param wagonManager
94       * @param settings
95       * @param mavenProjectBuilder
96       * @param factory
97       * @param resolver
98       * @param remoteRepositories
99       * @param pluginRepositories
100      * @param localRepository
101      * @param repositoryMetadataManager
102      */
103     public RepositoryUtils( Log log, LoggerManager loggerManager, WagonManager wagonManager, Settings settings,
104                             MavenProjectBuilder mavenProjectBuilder, ArtifactFactory factory,
105                             ArtifactResolver resolver, List remoteRepositories, List pluginRepositories,
106                             ArtifactRepository localRepository, RepositoryMetadataManager repositoryMetadataManager )
107     {
108         this.log = log;
109         this.loggerManager = loggerManager;
110         this.wagonManager = wagonManager;
111         this.settings = settings;
112         this.mavenProjectBuilder = mavenProjectBuilder;
113         this.factory = factory;
114         this.resolver = resolver;
115         this.remoteRepositories = remoteRepositories;
116         this.pluginRepositories = pluginRepositories;
117         this.localRepository = localRepository;
118         this.repositoryMetadataManager = repositoryMetadataManager;
119     }
120 
121     /**
122      * @return localrepo
123      */
124     public ArtifactRepository getLocalRepository()
125     {
126         return localRepository;
127     }
128 
129     /**
130      * @return remote artifact repo
131      */
132     public List getRemoteArtifactRepositories()
133     {
134         return remoteRepositories;
135     }
136 
137     /**
138      * @return plugin artifact repo
139      */
140     public List getPluginArtifactRepositories()
141     {
142         return pluginRepositories;
143     }
144 
145     /**
146      * @param artifact not null
147      * @throws ArtifactResolutionException if any
148      * @throws ArtifactNotFoundException if any
149      * @see ArtifactResolver#resolve(Artifact, List, ArtifactRepository)
150      */
151     public void resolve( Artifact artifact )
152         throws ArtifactResolutionException, ArtifactNotFoundException
153     {
154         List repos = new ArrayList();
155         repos.addAll( pluginRepositories );
156         repos.addAll( remoteRepositories );
157 
158         resolver.resolve( artifact, repos, localRepository );
159     }
160 
161     /**
162      * @param repo not null
163      * @param artifact not null
164      * @return <code>true</code> if the artifact exists in the given repo, <code>false</code> otherwise or if
165      * the repo is blacklisted.
166      */
167     public boolean dependencyExistsInRepo( ArtifactRepository repo, Artifact artifact )
168     {
169         if ( repo.isBlacklisted() )
170         {
171             if ( log.isDebugEnabled() )
172             {
173                 log.debug( "The repo '" + repo.getId() + "' is black listed - Ignored it" );
174             }
175             return false;
176         }
177 
178         String id = repo.getId();
179         Repository repository = new Repository( id, repo.getUrl() );
180 
181         Wagon wagon;
182         try
183         {
184             wagon = wagonManager.getWagon( repository );
185         }
186         catch ( UnsupportedProtocolException e )
187         {
188             log.error( "Unsupported protocol: '" + repo.getProtocol() + "'", e );
189             return false;
190         }
191         catch ( WagonConfigurationException e )
192         {
193             log.error( "Unsupported protocol: '" + repo.getProtocol() + "'", e );
194             return false;
195         }
196 
197         if ( log.isDebugEnabled() )
198         {
199             Debug debug = new Debug();
200 
201             wagon.addSessionListener( debug );
202             wagon.addTransferListener( debug );
203         }
204 
205         try
206         {
207             AuthenticationInfo auth = wagonManager.getAuthenticationInfo( repo.getId() );
208 
209             ProxyInfo proxyInfo = getProxyInfo();
210             if ( proxyInfo != null )
211             {
212                 wagon.connect( repository, auth, proxyInfo );
213             }
214             else
215             {
216                 wagon.connect( repository, auth );
217             }
218 
219             return wagon.resourceExists( StringUtils.replace( getDependencyUrlFromRepository( artifact, repo ),
220                                                               repo.getUrl(), "" ) );
221         }
222         catch ( ConnectionException e )
223         {
224             if ( log.isDebugEnabled() )
225             {
226                 log.error( "Unable to connect to: " + repo.getUrl(), e );
227             }
228             else
229             {
230                 log.error( "Unable to connect to: " + repo.getUrl() );
231             }
232             return false;
233         }
234         catch ( AuthenticationException e )
235         {
236             if ( log.isDebugEnabled() )
237             {
238                 log.error( "Unable to connect to: " + repo.getUrl(), e );
239             }
240             else
241             {
242                 log.error( "Unable to connect to: " + repo.getUrl() );
243             }
244             return false;
245         }
246         catch ( TransferFailedException e )
247         {
248             if ( log.isDebugEnabled() )
249             {
250                 log.error( "Unable to determine if resource " + artifact + " exists in " + repo.getUrl(), e );
251             }
252             else
253             {
254                 log.error( "Unable to determine if resource " + artifact + " exists in " + repo.getUrl() );
255             }
256             return false;
257         }
258         catch ( AuthorizationException e )
259         {
260             if ( log.isDebugEnabled() )
261             {
262                 log.error( "Unable to connect to: " + repo.getUrl(), e );
263             }
264             else
265             {
266                 log.error( "Unable to connect to: " + repo.getUrl() );
267             }
268             return false;
269         }
270         catch ( AbstractMethodError e )
271         {
272             log.error( "Wagon " + wagon.getClass().getName() + " does not support the resourceExists method" );
273             return false;
274         }
275         finally
276         {
277             try
278             {
279                 wagon.disconnect();
280             }
281             catch ( ConnectionException e )
282             {
283                 if ( log.isDebugEnabled() )
284                 {
285                     log.error( "Error disconnecting wagon - ignored", e );
286                 }
287                 else
288                 {
289                     log.error( "Error disconnecting wagon - ignored" );
290                 }
291             }
292         }
293     }
294 
295     /**
296      * Get the <code>Maven project</code> from the repository depending the <code>Artifact</code> given.
297      *
298      * @param artifact an artifact
299      * @return the Maven project for the given artifact
300      * @throws ProjectBuildingException if any
301      */
302     public MavenProject getMavenProjectFromRepository( Artifact artifact )
303         throws ProjectBuildingException
304     {
305         Artifact projectArtifact = artifact;
306 
307         boolean allowStubModel = false;
308         if ( !"pom".equals( artifact.getType() ) )
309         {
310             projectArtifact = factory.createProjectArtifact( artifact.getGroupId(), artifact.getArtifactId(),
311                                                              artifact.getVersion(), artifact.getScope() );
312             allowStubModel = true;
313         }
314 
315         // TODO: we should use the MavenMetadataSource instead
316         return mavenProjectBuilder.buildFromRepository( projectArtifact, remoteRepositories, localRepository,
317                                                         allowStubModel );
318     }
319 
320     /**
321      * @param artifact not null
322      * @param repo not null
323      * @return the artifact url in the given repo for the given artifact. If it is a snapshot artifact, the version
324      * will be the timestamp and the build number from the metadata. Could return null if the repo is blacklisted.
325      */
326     public String getDependencyUrlFromRepository( Artifact artifact, ArtifactRepository repo )
327     {
328         if ( repo.isBlacklisted() )
329         {
330             return null;
331         }
332 
333         Artifact copyArtifact = ArtifactUtils.copyArtifact( artifact );
334         // Try to get the last artifact repo name depending the snapshot version
335         if ( ( artifact.isSnapshot() && repo.getSnapshots().isEnabled() ) )
336         {
337             if ( artifact.getBaseVersion().equals( artifact.getVersion() ) )
338             {
339                 // Try to resolve it if not already done
340                 if ( artifact.getMetadataList() == null || artifact.getMetadataList().isEmpty() )
341                 {
342                     try
343                     {
344                         resolve( artifact );
345                     }
346                     catch ( ArtifactResolutionException e )
347                     {
348                         log.error( "Artifact: " + artifact.getId() + " could not be resolved." );
349                     }
350                     catch ( ArtifactNotFoundException e )
351                     {
352                         log.error( "Artifact: " + artifact.getId() + " was not found." );
353                     }
354                 }
355 
356                 for ( Iterator it = artifact.getMetadataList().iterator(); it.hasNext(); )
357                 {
358                     ArtifactMetadata m = (ArtifactMetadata) it.next();
359 
360                     if ( m instanceof SnapshotArtifactRepositoryMetadata )
361                     {
362                         SnapshotArtifactRepositoryMetadata snapshotMetadata = (SnapshotArtifactRepositoryMetadata) m;
363 
364                         // Removed not found log
365                         int oldThreshold = loggerManager.getThreshold();
366                         loggerManager.setThreshold( RepositoryMetadataManager.class.getName(), Logger.LEVEL_DISABLED );
367                         try
368                         {
369                             repositoryMetadataManager.resolveAlways( snapshotMetadata, localRepository, repo );
370                         }
371                         catch ( RepositoryMetadataResolutionException e )
372                         {
373                             loggerManager.setThreshold( RepositoryMetadataManager.class.getName(), oldThreshold );
374                             if ( log.isDebugEnabled() )
375                             {
376                                 log.error( "Unable to connect to: " + repo.getUrl(), e );
377                             }
378                             else
379                             {
380                                 log.error( "Unable to connect to: " + repo.getUrl() );
381                             }
382                             return repo.getUrl() + "/" + repo.pathOf( copyArtifact );
383                         }
384                         finally
385                         {
386                             loggerManager.setThreshold( RepositoryMetadataManager.class.getName(), oldThreshold );
387                         }
388 
389                         Metadata metadata = snapshotMetadata.getMetadata();
390                         if ( metadata.getVersioning() == null || metadata.getVersioning().getSnapshot() == null
391                             || metadata.getVersioning().getSnapshot().isLocalCopy()
392                             || metadata.getVersioning().getSnapshot().getTimestamp() == null )
393                         {
394                             continue;
395                         }
396 
397                         // create the version according SnapshotTransformation
398                         String version =
399                             StringUtils.replace( copyArtifact.getVersion(), Artifact.SNAPSHOT_VERSION,
400                                                  metadata.getVersioning().getSnapshot().getTimestamp() )
401                                 + "-" + metadata.getVersioning().getSnapshot().getBuildNumber();
402                         copyArtifact.setVersion( version );
403                     }
404                 }
405             }
406         }
407 
408         return repo.getUrl() + "/" + repo.pathOf( copyArtifact );
409     }
410 
411     // ----------------------------------------------------------------------
412     // Private methods
413     // ----------------------------------------------------------------------
414 
415     /**
416      * Convenience method to map a <code>Proxy</code> object from the user system settings to a <code>ProxyInfo</code>
417      * object.
418      *
419      * @return a proxyInfo object instanced or null if no active proxy is define in the settings.xml
420      */
421     private ProxyInfo getProxyInfo()
422     {
423         ProxyInfo proxyInfo = null;
424         if ( settings != null && settings.getActiveProxy() != null )
425         {
426             Proxy settingsProxy = settings.getActiveProxy();
427 
428             proxyInfo = new ProxyInfo();
429             proxyInfo.setHost( settingsProxy.getHost() );
430             proxyInfo.setType( settingsProxy.getProtocol() );
431             proxyInfo.setPort( settingsProxy.getPort() );
432             proxyInfo.setNonProxyHosts( settingsProxy.getNonProxyHosts() );
433             proxyInfo.setUserName( settingsProxy.getUsername() );
434             proxyInfo.setPassword( settingsProxy.getPassword() );
435         }
436 
437         return proxyInfo;
438     }
439 }