View Javadoc
1   package org.apache.maven;
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.Collection;
24  import java.util.Collections;
25  import java.util.Iterator;
26  import java.util.List;
27  import java.util.Map;
28  import java.util.Objects;
29  
30  import org.apache.maven.artifact.handler.ArtifactHandler;
31  import org.apache.maven.artifact.handler.DefaultArtifactHandler;
32  import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
33  import org.apache.maven.artifact.repository.ArtifactRepository;
34  import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
35  import org.eclipse.aether.RepositorySystemSession;
36  import org.eclipse.aether.artifact.Artifact;
37  import org.eclipse.aether.artifact.ArtifactProperties;
38  import org.eclipse.aether.artifact.ArtifactType;
39  import org.eclipse.aether.artifact.ArtifactTypeRegistry;
40  import org.eclipse.aether.artifact.DefaultArtifact;
41  import org.eclipse.aether.artifact.DefaultArtifactType;
42  import org.eclipse.aether.graph.Dependency;
43  import org.eclipse.aether.graph.DependencyFilter;
44  import org.eclipse.aether.graph.DependencyNode;
45  import org.eclipse.aether.graph.Exclusion;
46  import org.eclipse.aether.repository.Authentication;
47  import org.eclipse.aether.repository.Proxy;
48  import org.eclipse.aether.repository.RemoteRepository;
49  import org.eclipse.aether.repository.RepositoryPolicy;
50  import org.eclipse.aether.repository.WorkspaceReader;
51  import org.eclipse.aether.repository.WorkspaceRepository;
52  import org.eclipse.aether.util.repository.AuthenticationBuilder;
53  
54  /**
55   * <strong>Warning:</strong> This is an internal utility class that is only public for technical reasons, it is not part
56   * of the public API. In particular, this class can be changed or deleted without prior notice.
57   *
58   * @author Benjamin Bentmann
59   */
60  public class RepositoryUtils
61  {
62  
63      private static String nullify( String string )
64      {
65          return ( string == null || string.length() <= 0 ) ? null : string;
66      }
67  
68      private static org.apache.maven.artifact.Artifact toArtifact( Dependency dependency )
69      {
70          if ( dependency == null )
71          {
72              return null;
73          }
74  
75          org.apache.maven.artifact.Artifact result = toArtifact( dependency.getArtifact() );
76          result.setScope( dependency.getScope() );
77          result.setOptional( dependency.isOptional() );
78  
79          return result;
80      }
81  
82      public static org.apache.maven.artifact.Artifact toArtifact( Artifact artifact )
83      {
84          if ( artifact == null )
85          {
86              return null;
87          }
88  
89          ArtifactHandler handler = newHandler( artifact );
90  
91          /*
92           * NOTE: From Artifact.hasClassifier(), an empty string and a null both denote "no classifier". However, some
93           * plugins only check for null, so be sure to nullify an empty classifier.
94           */
95          org.apache.maven.artifact.Artifact result =
96              new org.apache.maven.artifact.DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(),
97                                                             artifact.getVersion(), null,
98                                                             artifact.getProperty( ArtifactProperties.TYPE,
99                                                                                   artifact.getExtension() ),
100                                                            nullify( artifact.getClassifier() ), handler );
101 
102         result.setFile( artifact.getFile() );
103         result.setResolved( artifact.getFile() != null );
104 
105         List<String> trail = new ArrayList<>( 1 );
106         trail.add( result.getId() );
107         result.setDependencyTrail( trail );
108 
109         return result;
110     }
111 
112     public static void toArtifacts( Collection<org.apache.maven.artifact.Artifact> artifacts,
113                                     Collection<? extends DependencyNode> nodes, List<String> trail,
114                                     DependencyFilter filter )
115     {
116         for ( DependencyNode node : nodes )
117         {
118             org.apache.maven.artifact.Artifact artifact = toArtifact( node.getDependency() );
119 
120             List<String> nodeTrail = new ArrayList<>( trail.size() + 1 );
121             nodeTrail.addAll( trail );
122             nodeTrail.add( artifact.getId() );
123 
124             if ( filter == null || filter.accept( node, Collections.<DependencyNode>emptyList() ) )
125             {
126                 artifact.setDependencyTrail( nodeTrail );
127                 artifacts.add( artifact );
128             }
129 
130             toArtifacts( artifacts, node.getChildren(), nodeTrail, filter );
131         }
132     }
133 
134     public static Artifact toArtifact( org.apache.maven.artifact.Artifact artifact )
135     {
136         if ( artifact == null )
137         {
138             return null;
139         }
140 
141         String version = artifact.getVersion();
142         if ( version == null && artifact.getVersionRange() != null )
143         {
144             version = artifact.getVersionRange().toString();
145         }
146 
147         Map<String, String> props = null;
148         if ( org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
149         {
150             String localPath = ( artifact.getFile() != null ) ? artifact.getFile().getPath() : "";
151             props = Collections.singletonMap( ArtifactProperties.LOCAL_PATH, localPath );
152         }
153 
154         Artifact result =
155             new DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(), artifact.getClassifier(),
156                                  artifact.getArtifactHandler().getExtension(), version, props,
157                                  newArtifactType( artifact.getType(), artifact.getArtifactHandler() ) );
158         result = result.setFile( artifact.getFile() );
159 
160         return result;
161     }
162 
163     public static Dependency toDependency( org.apache.maven.artifact.Artifact artifact,
164                                            Collection<org.apache.maven.model.Exclusion> exclusions )
165     {
166         if ( artifact == null )
167         {
168             return null;
169         }
170 
171         Artifact result = toArtifact( artifact );
172 
173         List<Exclusion> excl = null;
174         if ( exclusions != null )
175         {
176             excl = new ArrayList<>( exclusions.size() );
177             for ( org.apache.maven.model.Exclusion exclusion : exclusions )
178             {
179                 excl.add( toExclusion( exclusion ) );
180             }
181         }
182 
183         return new Dependency( result, artifact.getScope(), artifact.isOptional(), excl );
184     }
185 
186     public static List<RemoteRepository> toRepos( List<ArtifactRepository> repos )
187     {
188         if ( repos == null )
189         {
190             return null;
191         }
192 
193         List<RemoteRepository> results = new ArrayList<>( repos.size() );
194         for ( ArtifactRepository repo : repos )
195         {
196             results.add( toRepo( repo ) );
197         }
198         return results;
199     }
200 
201     public static RemoteRepository toRepo( ArtifactRepository repo )
202     {
203         RemoteRepository result = null;
204         if ( repo != null )
205         {
206             RemoteRepository.Builder builder =
207                 new RemoteRepository.Builder( repo.getId(), getLayout( repo ), repo.getUrl() );
208             builder.setSnapshotPolicy( toPolicy( repo.getSnapshots() ) );
209             builder.setReleasePolicy( toPolicy( repo.getReleases() ) );
210             builder.setAuthentication( toAuthentication( repo.getAuthentication() ) );
211             builder.setProxy( toProxy( repo.getProxy() ) );
212             builder.setMirroredRepositories( toRepos( repo.getMirroredRepositories() ) );
213             result = builder.build();
214         }
215         return result;
216     }
217 
218     public static String getLayout( ArtifactRepository repo )
219     {
220         try
221         {
222             return repo.getLayout().getId();
223         }
224         catch ( LinkageError e )
225         {
226             /*
227              * NOTE: getId() was added in 3.x and is as such not implemented by plugins compiled against 2.x APIs.
228              */
229             String className = repo.getLayout().getClass().getSimpleName();
230             if ( className.endsWith( "RepositoryLayout" ) )
231             {
232                 String layout = className.substring( 0, className.length() - "RepositoryLayout".length() );
233                 if ( layout.length() > 0 )
234                 {
235                     layout = Character.toLowerCase( layout.charAt( 0 ) ) + layout.substring( 1 );
236                     return layout;
237                 }
238             }
239             return "";
240         }
241     }
242 
243     private static RepositoryPolicy toPolicy( ArtifactRepositoryPolicy policy )
244     {
245         RepositoryPolicy result = null;
246         if ( policy != null )
247         {
248             result = new RepositoryPolicy( policy.isEnabled(), policy.getUpdatePolicy(), policy.getChecksumPolicy() );
249         }
250         return result;
251     }
252 
253     private static Authentication toAuthentication( org.apache.maven.artifact.repository.Authentication auth )
254     {
255         Authentication result = null;
256         if ( auth != null )
257         {
258             AuthenticationBuilder authBuilder = new AuthenticationBuilder();
259             authBuilder.addUsername( auth.getUsername() ).addPassword( auth.getPassword() );
260             authBuilder.addPrivateKey( auth.getPrivateKey(), auth.getPassphrase() );
261             result = authBuilder.build();
262         }
263         return result;
264     }
265 
266     private static Proxy toProxy( org.apache.maven.repository.Proxy proxy )
267     {
268         Proxy result = null;
269         if ( proxy != null )
270         {
271             AuthenticationBuilder authBuilder = new AuthenticationBuilder();
272             authBuilder.addUsername( proxy.getUserName() ).addPassword( proxy.getPassword() );
273             result = new Proxy( proxy.getProtocol(), proxy.getHost(), proxy.getPort(), authBuilder.build() );
274         }
275         return result;
276     }
277 
278     public static ArtifactHandler newHandler( Artifact artifact )
279     {
280         String type = artifact.getProperty( ArtifactProperties.TYPE, artifact.getExtension() );
281         DefaultArtifactHandler handler = new DefaultArtifactHandler( type );
282         handler.setExtension( artifact.getExtension() );
283         handler.setLanguage( artifact.getProperty( ArtifactProperties.LANGUAGE, null ) );
284         String addedToClasspath = artifact.getProperty( ArtifactProperties.CONSTITUTES_BUILD_PATH, "" );
285         handler.setAddedToClasspath( Boolean.parseBoolean( addedToClasspath ) );
286         String includesDependencies = artifact.getProperty( ArtifactProperties.INCLUDES_DEPENDENCIES, "" );
287         handler.setIncludesDependencies( Boolean.parseBoolean( includesDependencies ) );
288         return handler;
289     }
290 
291     public static ArtifactType newArtifactType( String id, ArtifactHandler handler )
292     {
293         return new DefaultArtifactType( id, handler.getExtension(), handler.getClassifier(), handler.getLanguage(),
294                                         handler.isAddedToClasspath(), handler.isIncludesDependencies() );
295     }
296 
297     public static Dependency toDependency( org.apache.maven.model.Dependency dependency,
298                                            ArtifactTypeRegistry stereotypes )
299     {
300         ArtifactType stereotype = stereotypes.get( dependency.getType() );
301         if ( stereotype == null )
302         {
303             stereotype = new DefaultArtifactType( dependency.getType() );
304         }
305 
306         boolean system = dependency.getSystemPath() != null && dependency.getSystemPath().length() > 0;
307 
308         Map<String, String> props = null;
309         if ( system )
310         {
311             props = Collections.singletonMap( ArtifactProperties.LOCAL_PATH, dependency.getSystemPath() );
312         }
313 
314         Artifact artifact =
315             new DefaultArtifact( dependency.getGroupId(), dependency.getArtifactId(), dependency.getClassifier(), null,
316                                  dependency.getVersion(), props, stereotype );
317 
318         List<Exclusion> exclusions = new ArrayList<>( dependency.getExclusions().size() );
319         for ( org.apache.maven.model.Exclusion exclusion : dependency.getExclusions() )
320         {
321             exclusions.add( toExclusion( exclusion ) );
322         }
323 
324         Dependency result = new Dependency( artifact,
325                                             dependency.getScope(),
326                                             dependency.getOptional() != null
327                                                 ? dependency.isOptional()
328                                                 : null,
329                                             exclusions );
330 
331         return result;
332     }
333 
334     private static Exclusion toExclusion( org.apache.maven.model.Exclusion exclusion )
335     {
336         return new Exclusion( exclusion.getGroupId(), exclusion.getArtifactId(), "*", "*" );
337     }
338 
339     public static ArtifactTypeRegistry newArtifactTypeRegistry( ArtifactHandlerManager handlerManager )
340     {
341         return new MavenArtifactTypeRegistry( handlerManager );
342     }
343 
344     static class MavenArtifactTypeRegistry
345         implements ArtifactTypeRegistry
346     {
347 
348         private final ArtifactHandlerManager handlerManager;
349 
350         MavenArtifactTypeRegistry( ArtifactHandlerManager handlerManager )
351         {
352             this.handlerManager = handlerManager;
353         }
354 
355         public ArtifactType get( String stereotypeId )
356         {
357             ArtifactHandler handler = handlerManager.getArtifactHandler( stereotypeId );
358             return newArtifactType( stereotypeId, handler );
359         }
360 
361     }
362 
363     public static Collection<Artifact> toArtifacts( Collection<org.apache.maven.artifact.Artifact> artifactsToConvert )
364     {
365         List<Artifact> artifacts = new ArrayList<>();
366         for ( org.apache.maven.artifact.Artifact a : artifactsToConvert )
367         {
368             artifacts.add( toArtifact( a ) );
369         }
370         return artifacts;
371     }
372 
373     public static WorkspaceRepository getWorkspace( RepositorySystemSession session )
374     {
375         WorkspaceReader reader = session.getWorkspaceReader();
376         return ( reader != null ) ? reader.getRepository() : null;
377     }
378 
379     public static boolean repositoriesEquals( List<RemoteRepository> r1, List<RemoteRepository> r2 )
380     {
381         if ( r1.size() != r2.size() )
382         {
383             return false;
384         }
385     
386         for ( Iterator<RemoteRepository> it1 = r1.iterator(), it2 = r2.iterator(); it1.hasNext(); )
387         {
388             if ( !repositoryEquals( it1.next(), it2.next() ) )
389             {
390                 return false;
391             }
392         }
393     
394         return true;
395     }
396 
397     public static int repositoriesHashCode( List<RemoteRepository> repositories )
398     {
399         int result = 17;
400         for ( RemoteRepository repository : repositories )
401         {
402             result = 31 * result + repositoryHashCode( repository );
403         }
404         return result;
405     }
406 
407     private static int repositoryHashCode( RemoteRepository repository )
408     {
409         int result = 17;
410         Object obj = repository.getUrl();
411         result = 31 * result + ( obj != null ? obj.hashCode() : 0 );
412         return result;
413     }
414 
415     private static boolean policyEquals( RepositoryPolicy p1, RepositoryPolicy p2 )
416     {
417         if ( p1 == p2 )
418         {
419             return true;
420         }
421         // update policy doesn't affect contents
422         return p1.isEnabled() == p2.isEnabled() && Objects.equals( p1.getChecksumPolicy(), p2.getChecksumPolicy() );
423     }
424 
425     private static boolean repositoryEquals( RemoteRepository r1, RemoteRepository r2 )
426     {
427         if ( r1 == r2 )
428         {
429             return true;
430         }
431     
432         return Objects.equals( r1.getId(), r2.getId() ) && Objects.equals( r1.getUrl(), r2.getUrl() )
433             && policyEquals( r1.getPolicy( false ), r2.getPolicy( false ) )
434             && policyEquals( r1.getPolicy( true ), r2.getPolicy( true ) );
435     }
436 }