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