View Javadoc
1   /*******************************************************************************
2    * Copyright (c) 2008, 2011 Sonatype Inc. and others.
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the Eclipse Public License v1.0
5    * which accompanies this distribution, and is available at
6    * http://www.eclipse.org/legal/epl-v10.html
7    *
8    * Contributors:
9    *    Sonatype Inc. - initial API and implementation
10   *******************************************************************************/
11  package com.simpligility.maven.plugins.android.common;
12  
13  import org.apache.maven.artifact.Artifact;
14  import org.apache.maven.artifact.repository.ArtifactRepository;
15  import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
16  import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
17  import org.apache.maven.artifact.resolver.ArtifactResolver;
18  import org.apache.maven.plugin.MojoExecutionException;
19  import org.codehaus.plexus.logging.Logger;
20  
21  import java.io.File;
22  import java.util.Arrays;
23  import java.util.Collection;
24  import java.util.Collections;
25  import java.util.LinkedHashSet;
26  import java.util.List;
27  import java.util.Set;
28  
29  /**
30   * Provides convenient functions for resolving artifacts.
31   */
32  public final class ArtifactResolverHelper
33  {
34      /**
35       * Which dependency scopes should be excluded when packing dependencies into the apk.
36       */
37      public static final List<String> EXCLUDE_NON_PACKAGED_SCOPES = Arrays.asList(
38              Artifact.SCOPE_PROVIDED, Artifact.SCOPE_IMPORT
39      );
40  
41      private final ArtifactResolver artifactResolver;
42      private final Logger log;
43      private final List<ArtifactRepository> remoteArtifactRepositories;
44  
45      /**
46       * Creates an ArtifactResolver that has no remote repositories to resolve against.
47       */
48      public ArtifactResolverHelper( ArtifactResolver artifactResolver, Logger log )
49      {
50          this( artifactResolver, log, Collections.<ArtifactRepository>emptyList() );
51      }
52  
53      public ArtifactResolverHelper( ArtifactResolver artifactResolver, Logger log,
54                                    final List<ArtifactRepository> remoteArtifactRepositories )
55      {
56          this.artifactResolver = artifactResolver;
57          this.log = log;
58          this.remoteArtifactRepositories = remoteArtifactRepositories;
59      }
60  
61      /**
62       * Filters provided artifacts and selects only defined types based on {@code types} argument
63       * or all types if {@code types} argument is empty.
64       *
65       * @param allArtifacts artifacts to be filtered
66       * @param types artifact types to be selected
67       * @return a {@code List} of all project dependencies. Never {@code null}.
68       *      This excludes artifacts of the {@code EXCLUDED_DEPENDENCY_SCOPES} scopes.
69       *      And this should maintain dependency order to comply with library project resource precedence.
70       */
71      public Set<Artifact> getFilteredArtifacts( Iterable<Artifact> allArtifacts, String... types )
72      {
73          return getFilteredArtifacts( EXCLUDE_NON_PACKAGED_SCOPES, allArtifacts, types );
74      }
75  
76      /**
77       * Filters provided artifacts and selects only defined types based on {@code types} argument
78       * or all types if {@code types} argument is empty.
79       *
80       * @param filteredScopes scopes to be filtered
81       * @param allArtifacts artifacts to be filtered
82       * @param types artifact types to be selected
83       * @return a {@code List} of all project dependencies. Never {@code null}.
84       *      This should maintain dependency order to comply with library project resource precedence.
85       */
86      public Set<Artifact> getFilteredArtifacts( List<String> filteredScopes,
87                                                 Iterable<Artifact> allArtifacts, String... types )
88      {
89          final List<String> acceptTypeList = Arrays.asList( types );
90          boolean acceptAllArtifacts = acceptTypeList.isEmpty();
91          final Set<Artifact> results = new LinkedHashSet<Artifact>();
92          for ( Artifact artifact : allArtifacts )
93          {
94              if ( artifact == null )
95              {
96                  continue;
97              }
98  
99              if ( filteredScopes.contains( artifact.getScope() ) )
100             {
101                 continue;
102             }
103 
104             if ( acceptAllArtifacts || acceptTypeList.contains( artifact.getType() ) )
105             {
106                 results.add( artifact );
107             }
108         }
109         return results;
110     }
111 
112     /**
113      * Attempts to resolve an {@link org.apache.maven.artifact.Artifact} to a {@link java.io.File}.
114      *
115      * @param artifact to resolve
116      * @return a {@link java.io.File} to the resolved artifact, never <code>null</code>.
117      * @throws org.apache.maven.plugin.MojoExecutionException if the artifact could not be resolved.
118      */
119     public File resolveArtifactToFile( Artifact artifact ) throws MojoExecutionException
120     {
121         final Artifact resolvedArtifact = resolveArtifact( artifact );
122         final File jar = resolvedArtifact.getFile();
123         if ( jar == null )
124         {
125             throw new MojoExecutionException( "Could not resolve artifact " + artifact.getId()
126                     + ". Please install it with \"mvn install:install-file ...\" or deploy it to a repository "
127                     + "with \"mvn deploy:deploy-file ...\"" );
128         }
129         return jar;
130     }
131 
132     public Set<Artifact> resolveArtifacts( Collection<Artifact> artifacts ) throws MojoExecutionException
133     {
134         final Set<Artifact> resolvedArtifacts = new LinkedHashSet<Artifact>();
135         for ( final Artifact artifact : artifacts )
136         {
137             resolvedArtifacts.add( resolveArtifact( artifact ) );
138         }
139         return resolvedArtifacts;
140     }
141 
142     /**
143      * Resolves an artifact to a particular repository.
144      *
145      * @param artifact  Artifact to resolve
146      * @return fully resolved artifact.
147      */
148     private Artifact resolveArtifact( Artifact artifact ) throws MojoExecutionException
149     {
150         final ArtifactResolutionRequest artifactResolutionRequest = new ArtifactResolutionRequest();
151         artifactResolutionRequest.setArtifact( artifact );
152         if ( remoteArtifactRepositories != null && !remoteArtifactRepositories.isEmpty() )
153         {
154             artifactResolutionRequest.setRemoteRepositories( remoteArtifactRepositories );
155         }
156         final ArtifactResolutionResult resolutionResult = this.artifactResolver.resolve( artifactResolutionRequest );
157 
158         log.debug( "Resolving : " + artifact );
159         if ( resolutionResult.getArtifacts().size() == 0 )
160         {
161             throw new MojoExecutionException( "Could not resolve artifact " + artifact
162                     + ". Please install it with \"mvn install:install-file ...\" or deploy it to a repository "
163                     + "with \"mvn deploy:deploy-file ...\"" );
164         }
165         if ( resolutionResult.getArtifacts().size() > 1 )
166         {
167             log.debug( "Resolved artifacts : " + resolutionResult.getArtifacts() );
168             throw new MojoExecutionException( "Could not resolve artifact " + artifact
169                     + " to single target. Found the following possible options : " + resolutionResult.getArtifacts() );
170         }
171 
172         final Artifact resolvedArtifact = resolutionResult.getArtifacts().iterator().next();
173         log.debug( "Resolved : " + resolvedArtifact );
174         return resolvedArtifact;
175     }
176 }