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 748489 2009-02-27 11:55:12Z vsiveton $
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.resolveAlways( 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         wagon.setTimeout( 1000 );
198 
199         if ( log.isDebugEnabled() )
200         {
201             Debug debug = new Debug();
202 
203             wagon.addSessionListener( debug );
204             wagon.addTransferListener( debug );
205         }
206 
207         try
208         {
209             AuthenticationInfo auth = wagonManager.getAuthenticationInfo( repo.getId() );
210 
211             ProxyInfo proxyInfo = getProxyInfo();
212             if ( proxyInfo != null )
213             {
214                 wagon.connect( repository, auth, proxyInfo );
215             }
216             else
217             {
218                 wagon.connect( repository, auth );
219             }
220 
221             return wagon.resourceExists( StringUtils.replace( getDependencyUrlFromRepository( artifact, repo ),
222                                                               repo.getUrl(), "" ) );
223         }
224         catch ( ConnectionException e )
225         {
226             if ( log.isDebugEnabled() )
227             {
228                 log.error( "Unable to connect to: " + repo.getUrl(), e );
229             }
230             else
231             {
232                 log.error( "Unable to connect to: " + repo.getUrl() );
233             }
234             return false;
235         }
236         catch ( AuthenticationException e )
237         {
238             if ( log.isDebugEnabled() )
239             {
240                 log.error( "Unable to connect to: " + repo.getUrl(), e );
241             }
242             else
243             {
244                 log.error( "Unable to connect to: " + repo.getUrl() );
245             }
246             return false;
247         }
248         catch ( TransferFailedException e )
249         {
250             if ( log.isDebugEnabled() )
251             {
252                 log.error( "Unable to determine if resource " + artifact + " exists in " + repo.getUrl(), e );
253             }
254             else
255             {
256                 log.error( "Unable to determine if resource " + artifact + " exists in " + repo.getUrl() );
257             }
258             return false;
259         }
260         catch ( AuthorizationException e )
261         {
262             if ( log.isDebugEnabled() )
263             {
264                 log.error( "Unable to connect to: " + repo.getUrl(), e );
265             }
266             else
267             {
268                 log.error( "Unable to connect to: " + repo.getUrl() );
269             }
270             return false;
271         }
272         catch ( AbstractMethodError e )
273         {
274             log.error( "Wagon " + wagon.getClass().getName() + " does not support the resourceExists method" );
275             return false;
276         }
277         finally
278         {
279             try
280             {
281                 wagon.disconnect();
282             }
283             catch ( ConnectionException e )
284             {
285                 if ( log.isDebugEnabled() )
286                 {
287                     log.error( "Error disconnecting wagon - ignored", e );
288                 }
289                 else
290                 {
291                     log.error( "Error disconnecting wagon - ignored" );
292                 }
293             }
294         }
295     }
296 
297     /**
298      * Get the <code>Maven project</code> from the repository depending the <code>Artifact</code> given.
299      *
300      * @param artifact an artifact
301      * @return the Maven project for the given artifact
302      * @throws ProjectBuildingException if any
303      */
304     public MavenProject getMavenProjectFromRepository( Artifact artifact )
305         throws ProjectBuildingException
306     {
307         Artifact projectArtifact = artifact;
308 
309         boolean allowStubModel = false;
310         if ( !"pom".equals( artifact.getType() ) )
311         {
312             projectArtifact = factory.createProjectArtifact( artifact.getGroupId(), artifact.getArtifactId(),
313                                                              artifact.getVersion(), artifact.getScope() );
314             allowStubModel = true;
315         }
316 
317         // TODO: we should use the MavenMetadataSource instead
318         return mavenProjectBuilder.buildFromRepository( projectArtifact, remoteRepositories, localRepository,
319                                                         allowStubModel );
320     }
321 
322     /**
323      * @param artifact not null
324      * @param repo not null
325      * @return the artifact url in the given repo for the given artifact. If it is a snapshot artifact, the version
326      * will be the timestamp and the build number from the metadata. Could return null if the repo is blacklisted.
327      */
328     public String getDependencyUrlFromRepository( Artifact artifact, ArtifactRepository repo )
329     {
330         if ( repo.isBlacklisted() )
331         {
332             return null;
333         }
334 
335         Artifact copyArtifact = ArtifactUtils.copyArtifact( artifact );
336         // Try to get the last artifact repo name depending the snapshot version
337         if ( ( artifact.isSnapshot() && repo.getSnapshots().isEnabled() ) )
338         {
339             if ( artifact.getBaseVersion().equals( artifact.getVersion() ))
340             {
341                 // Try to resolve it if not already done
342                 if ( artifact.getMetadataList() == null || artifact.getMetadataList().isEmpty() )
343                 {
344                     try
345                     {
346                         resolve( artifact );
347                     }
348                     catch ( ArtifactResolutionException e )
349                     {
350                         log.error( "Artifact: " + artifact.getId() + " could not be resolved." );
351                     }
352                     catch ( ArtifactNotFoundException e )
353                     {
354                         log.error( "Artifact: " + artifact.getId() + " was not found." );
355                     }
356                 }
357 
358                 for ( Iterator it = artifact.getMetadataList().iterator(); it.hasNext(); )
359                 {
360                     ArtifactMetadata m = (ArtifactMetadata) it.next();
361 
362                     if ( m instanceof SnapshotArtifactRepositoryMetadata )
363                     {
364                         SnapshotArtifactRepositoryMetadata snapshotMetadata = (SnapshotArtifactRepositoryMetadata) m;
365 
366                         // Removed not found log
367                         int oldThreshold = loggerManager.getThreshold();
368                         loggerManager.setThreshold( RepositoryMetadataManager.class.getName(), Logger.LEVEL_DISABLED );
369                         try
370                         {
371                             repositoryMetadataManager.resolveAlways( snapshotMetadata, localRepository, repo );
372                         }
373                         catch ( RepositoryMetadataResolutionException e )
374                         {
375                             loggerManager.setThreshold( RepositoryMetadataManager.class.getName(), oldThreshold );
376                             if ( log.isDebugEnabled() )
377                             {
378                                 log.error( "Unable to connect to: " + repo.getUrl(), e );
379                             }
380                             else
381                             {
382                                 log.error( "Unable to connect to: " + repo.getUrl() );
383                             }
384                             return repo.getUrl() + "/" + repo.pathOf( copyArtifact );
385                         }
386                         finally
387                         {
388                             loggerManager.setThreshold( RepositoryMetadataManager.class.getName(), oldThreshold );
389                         }
390 
391                         Metadata metadata = snapshotMetadata.getMetadata();
392                         if ( metadata.getVersioning() == null || metadata.getVersioning().getSnapshot() == null
393                             || metadata.getVersioning().getSnapshot().isLocalCopy()
394                             || metadata.getVersioning().getSnapshot().getTimestamp() == null )
395                         {
396                             continue;
397                         }
398 
399                         // create the version according SnapshotTransformation
400                         String version =
401                             StringUtils.replace( copyArtifact.getVersion(), Artifact.SNAPSHOT_VERSION,
402                                                  metadata.getVersioning().getSnapshot().getTimestamp() )
403                                 + "-" + metadata.getVersioning().getSnapshot().getBuildNumber();
404                         copyArtifact.setVersion( version );
405                     }
406                 }
407             }
408         }
409 
410         return repo.getUrl() + "/" + repo.pathOf( copyArtifact );
411     }
412 
413     // ----------------------------------------------------------------------
414     // Private methods
415     // ----------------------------------------------------------------------
416 
417     /**
418      * Convenience method to map a <code>Proxy</code> object from the user system settings to a <code>ProxyInfo</code>
419      * object.
420      *
421      * @return a proxyInfo object instanced or null if no active proxy is define in the settings.xml
422      */
423     private ProxyInfo getProxyInfo()
424     {
425         ProxyInfo proxyInfo = null;
426         if ( settings != null && settings.getActiveProxy() != null )
427         {
428             Proxy settingsProxy = settings.getActiveProxy();
429 
430             proxyInfo = new ProxyInfo();
431             proxyInfo.setHost( settingsProxy.getHost() );
432             proxyInfo.setType( settingsProxy.getProtocol() );
433             proxyInfo.setPort( settingsProxy.getPort() );
434             proxyInfo.setNonProxyHosts( settingsProxy.getNonProxyHosts() );
435             proxyInfo.setUserName( settingsProxy.getUsername() );
436             proxyInfo.setPassword( settingsProxy.getPassword() );
437         }
438 
439         return proxyInfo;
440     }
441 }