View Javadoc

1   package org.apache.maven.plugin.dependency;
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.io.File;
23  import java.io.IOException;
24  import java.util.ArrayList;
25  import java.util.Arrays;
26  import java.util.Collections;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.regex.Matcher;
30  import java.util.regex.Pattern;
31  
32  import org.apache.commons.io.FileUtils;
33  import org.apache.maven.artifact.Artifact;
34  import org.apache.maven.artifact.factory.ArtifactFactory;
35  import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
36  import org.apache.maven.artifact.repository.ArtifactRepository;
37  import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
38  import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
39  import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
40  import org.apache.maven.artifact.resolver.AbstractArtifactResolutionException;
41  import org.apache.maven.artifact.resolver.ArtifactResolver;
42  import org.apache.maven.plugin.AbstractMojo;
43  import org.apache.maven.plugin.MojoExecutionException;
44  import org.apache.maven.plugin.MojoFailureException;
45  import org.codehaus.plexus.util.StringUtils;
46  
47  /**
48   * Downloads a single artifact transitively from the specified remote repositories. Caveat: will always check the
49   * central repository defined in the super pom. You could use a mirror entry in your settings.xml
50   * 
51   * @goal get
52   * @requiresProject false
53   */
54  public class GetMojo
55      extends AbstractMojo
56  {
57      private static final Pattern ALT_REPO_SYNTAX_PATTERN = Pattern.compile( "(.+)::(.*)::(.+)" );
58  
59      /**
60       * @component
61       * @readonly
62       */
63      private ArtifactFactory artifactFactory;
64  
65      /**
66       * @component
67       * @readonly
68       */
69      private ArtifactResolver artifactResolver;
70  
71      /**
72       * @component
73       * @readonly
74       */
75      private ArtifactRepositoryFactory artifactRepositoryFactory;
76  
77      /**
78       * Map that contains the layouts.
79       *
80       * @component role="org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout"
81       */
82      private Map repositoryLayouts;
83  
84      /**
85       * @component
86       * @readonly
87       */
88      private ArtifactMetadataSource source;
89  
90      /**
91       *
92       * @parameter expression="${localRepository}"
93       * @readonly
94       */
95      private ArtifactRepository localRepository;
96  
97      /**
98       * The groupId of the artifact to download. Ignored if {@link #artifact} is used.
99       * @parameter expression="${groupId}"
100      */
101     private String groupId;
102 
103     /**
104      * The artifactId of the artifact to download. Ignored if {@link #artifact} is used.
105      * @parameter expression="${artifactId}"
106      */
107     private String artifactId;
108 
109     /**
110      * The version of the artifact to download. Ignored if {@link #artifact} is used.
111      * @parameter expression="${version}"
112      */
113     private String version;
114 
115     /**
116      * The classifier of the artifact to download. Ignored if {@link #artifact} is used.
117      * @parameter expression="${classifier}"
118      * @since 2.3
119      */
120     private String classifier;
121 
122     /**
123      * The packaging of the artifact to download. Ignored if {@link #artifact} is used.
124      * @parameter expression="${packaging}" default-value="jar"
125      */
126     private String packaging = "jar";
127 
128     /**
129      * The id of the repository from which we'll download the artifact
130      * @parameter expression="${repoId}" default-value="temp"
131      * @deprecated Use remoteRepositories
132      */
133     private String repositoryId = "temp";
134 
135     /**
136      * The url of the repository from which we'll download the artifact. DEPRECATED Use remoteRepositories
137      * 
138      * @deprecated Use remoteRepositories
139      * @parameter expression="${repoUrl}"
140      */
141     private String repositoryUrl;
142 
143     /**
144      * Repositories in the format id::[layout]::url or just url, separated by comma.
145      * ie. central::default::http://repo1.maven.apache.org/maven2,myrepo::::http://repo.acme.com,http://repo.acme2.com
146      * 
147      * @parameter expression="${remoteRepositories}"
148      */
149     private String remoteRepositories;
150 
151     /**
152      * A string of the form groupId:artifactId:version[:packaging][:classifier].
153      * 
154      * @parameter expression="${artifact}"
155      */
156     private String artifact;
157 
158     /**
159      * The destination file to copy the artifact to, if other than the local repository
160      * @parameter expression="${dest}"
161      * @since 2.4
162      */
163     private String destination;
164 
165     /**
166      *
167      * @parameter expression="${project.remoteArtifactRepositories}"
168      * @required
169      * @readonly
170      */
171     private List pomRemoteRepositories;
172 
173     /**
174      * Download transitively, retrieving the specified artifact and all of its dependencies.
175      * @parameter expression="${transitive}" default-value=true
176      */
177     private boolean transitive = true;
178 
179     public void execute()
180         throws MojoExecutionException, MojoFailureException
181     {
182 
183         if ( artifactId == null && artifact == null )
184         {
185             throw new MojoFailureException( "You must specify an artifact, "
186                 + "e.g. -Dartifact=org.apache.maven.plugins:maven-downloader-plugin:1.0" );
187         }
188         if ( artifact != null )
189         {
190             String[] tokens = StringUtils.split( artifact, ":" );
191             if ( tokens.length < 3 || tokens.length > 5 )
192             {
193                 throw new MojoFailureException(
194                     "Invalid artifact, you must specify groupId:artifactId:version[:packaging][:classifier] "
195                         + artifact );
196             }
197             groupId = tokens[0];
198             artifactId = tokens[1];
199             version = tokens[2];
200             if ( tokens.length >= 4 )
201             {
202                 packaging = tokens[3];
203             }
204             if ( tokens.length == 5 )
205             {
206                 classifier = tokens[4];
207             }
208             else
209             {
210                 classifier = null;
211             }
212         }
213 
214         Artifact toDownload = classifier == null
215             ? artifactFactory.createBuildArtifact( groupId, artifactId, version, packaging )
216             : artifactFactory.createArtifactWithClassifier( groupId, artifactId, version, packaging, classifier );
217         Artifact dummyOriginatingArtifact =
218             artifactFactory.createBuildArtifact( "org.apache.maven.plugins", "maven-downloader-plugin", "1.0", "jar" );
219 
220         ArtifactRepositoryPolicy always =
221             new ArtifactRepositoryPolicy( true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS,
222                                           ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN );
223 
224         List<ArtifactRepository> repoList = new ArrayList<ArtifactRepository>();
225 
226         if ( pomRemoteRepositories != null )
227         {
228             repoList.addAll( pomRemoteRepositories );
229         }
230 
231         if ( remoteRepositories != null )
232         {
233             // Use the same format as in the deploy plugin id::layout::url
234             List<String> repos = Arrays.asList( StringUtils.split( remoteRepositories, "," ) );
235             for ( String repo : repos )
236             {
237                 repoList.add( parseRepository( repo, always ) );
238             }
239         }
240 
241         if ( repositoryUrl != null )
242         {
243             getLog().warn( "repositoryUrl parameter is deprecated. Use remoteRepositories instead" );
244             ArtifactRepository remoteRepo =
245                 artifactRepositoryFactory.createArtifactRepository( repositoryId, repositoryUrl,
246                                                                     getLayout( "default" ), always, always );
247             repoList.add( remoteRepo );
248         }
249 
250         try
251         {
252             if ( transitive )
253             {
254                 artifactResolver.resolveTransitively( Collections.singleton( toDownload ), dummyOriginatingArtifact,
255                                                       repoList, localRepository, source );
256             }
257             else
258             {
259                 artifactResolver.resolve( toDownload, repoList, localRepository );
260             }
261         }
262         catch ( AbstractArtifactResolutionException e )
263         {
264             throw new MojoExecutionException( "Couldn't download artifact: " + e.getMessage(), e );
265         }
266 
267         if ( destination != null )
268         {
269             File src = toDownload.getFile();
270             File dest = new File( destination );
271             if ( getLog().isInfoEnabled() )
272             {
273                 getLog().info( "Copying " + src.getAbsolutePath() + " to " + dest.getAbsolutePath() );
274             }
275             try
276             {
277                 FileUtils.copyFile( toDownload.getFile(), new File( destination ) );
278             }
279             catch ( IOException e )
280             {
281                 throw new MojoExecutionException( "Couldn't copy downloaded artifact from " + src.getAbsolutePath()
282                     + " to " + dest.getAbsolutePath() + " : " + e.getMessage(), e );
283             }
284         }
285     }
286 
287     ArtifactRepository parseRepository( String repo, ArtifactRepositoryPolicy policy )
288         throws MojoFailureException
289     {
290         // if it's a simple url
291         String id = repositoryId;
292         ArtifactRepositoryLayout layout = getLayout( "default" );
293         String url = repo;
294 
295         // if it's an extended repo URL of the form id::layout::url
296         if ( repo.indexOf( "::" ) >= 0 )
297         {
298             Matcher matcher = ALT_REPO_SYNTAX_PATTERN.matcher( repo );
299             if ( !matcher.matches() )
300             {
301                 throw new MojoFailureException( repo, "Invalid syntax for repository: " + repo,
302                                                 "Invalid syntax for repository. Use \"id::layout::url\" or \"URL\"." );
303             }
304 
305             id = matcher.group( 1 ).trim();
306             if ( !StringUtils.isEmpty( matcher.group( 2 ) ) )
307             {
308                 layout = getLayout( matcher.group( 2 ).trim() );
309             }
310             url = matcher.group( 3 ).trim();
311         }
312         return artifactRepositoryFactory.createArtifactRepository( id, url, layout, policy, policy );
313     }
314 
315     private ArtifactRepositoryLayout getLayout( String id )
316         throws MojoFailureException
317     {
318         ArtifactRepositoryLayout layout = (ArtifactRepositoryLayout) repositoryLayouts.get( id );
319 
320         if ( layout == null )
321         {
322             throw new MojoFailureException( id, "Invalid repository layout", "Invalid repository layout: " + id );
323         }
324 
325         return layout;
326     }
327 }