View Javadoc

1   /**
2    * The MIT License
3    *
4    * Copyright 2006-2012 The Codehaus.
5    *
6    * Permission is hereby granted, free of charge, to any person obtaining a copy of
7    * this software and associated documentation files (the "Software"), to deal in
8    * the Software without restriction, including without limitation the rights to
9    * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10   *  of the Software, and to permit persons to whom the Software is furnished to do
11   * so, subject to the following conditions:
12   *
13   * The above copyright notice and this permission notice shall be included in all
14   * copies or substantial portions of the Software.
15   *
16   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22   * SOFTWARE.
23   */
24  package org.codehaus.mojo.appassembler;
25  
26  import java.io.File;
27  import java.io.IOException;
28  import java.util.Collections;
29  import java.util.Iterator;
30  import java.util.Map;
31  import java.util.Set;
32  
33  import org.apache.maven.artifact.Artifact;
34  import org.apache.maven.artifact.factory.ArtifactFactory;
35  import org.apache.maven.artifact.installer.ArtifactInstallationException;
36  import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
37  import org.apache.maven.artifact.repository.ArtifactRepository;
38  import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
39  import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
40  import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
41  import org.apache.maven.artifact.resolver.ArtifactResolutionException;
42  import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
43  import org.apache.maven.artifact.resolver.ArtifactResolver;
44  import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
45  import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
46  import org.apache.maven.artifact.versioning.VersionRange;
47  import org.apache.maven.plugin.AbstractMojo;
48  import org.apache.maven.plugin.MojoExecutionException;
49  import org.apache.maven.plugin.MojoFailureException;
50  import org.codehaus.plexus.util.FileUtils;
51  
52  /**
53   * Creates an appassembler repository. Note that this is deliberately a bit more specific than the assembly plugin
54   * version - if it can generate a flat layout and exclude JARs, it may be a suitable replacement.
55   * 
56   * @author <a href="mailto:kristian.nordal@gmail.com">Kristian Nordal</a>
57   * @version $Id: CreateRepositoryMojo.java 16448 2012-04-22 15:47:18Z khmarbaise $
58   * @goal create-repository
59   * @requiresDependencyResolution runtime
60   * @phase package
61   * @threadsafe
62   */
63  public class CreateRepositoryMojo
64          extends AbstractMojo
65  {
66      // -----------------------------------------------------------------------
67      // Parameters
68      // -----------------------------------------------------------------------
69  
70      /**
71       * The directory that will be used to assemble the artifacts in and place the bin scripts.
72       * 
73       * @required
74       * @parameter expression="${project.build.directory}/appassembler"
75       */
76      private File assembleDirectory;
77  
78      /**
79       * The directory that will be used for the dependencies, relative to <code>assembleDirectory</code>.
80       * 
81       * @required
82       * @parameter default-value="repo"
83       * @todo customisation doesn't work due to the shell scripts not honouring it
84       */
85      private String repoPath;
86  
87      /**
88       * The layout of the generated Maven repository. Supported types - "default" (Maven2) | "legacy" (Maven1) | "flat"
89       * (flat <code>lib/</code> style).
90       * The style "legacy" is only supported if you are running under Maven 2.2.1 and before.
91       * 
92       * @parameter default-value="default"
93       */
94      private String repositoryLayout;
95  
96      // -----------------------------------------------------------------------
97      // Read-only parameters
98      // -----------------------------------------------------------------------
99  
100     /**
101      * @readonly
102      * @parameter expression="${project.artifacts}"
103      */
104     private Set artifacts;
105 
106     /**
107      * @readonly
108      * @parameter expression="${plugin.version}"
109      */
110     private String pluginVersion;
111 
112     /**
113      * @readonly
114      * @parameter expression="${localRepository}"
115      */
116     private ArtifactRepository localRepository;
117 
118     /**
119      * @readonly
120      * @parameter expression="${project.artifact}"
121      */
122     private Artifact projectArtifact;
123 
124     /**
125      * Whether to install the booter artifacts into the repository. This may be needed if you are using the Shell script
126      * generators.
127      * 
128      * @parameter default-value="false"
129      */
130     private boolean installBooterArtifacts;
131 
132     // -----------------------------------------------------------------------
133     // Components
134     // -----------------------------------------------------------------------
135 
136     /** @component */
137     private ArtifactFactory artifactFactory;
138 
139     /**
140      * @component
141      */
142     private ArtifactRepositoryFactory artifactRepositoryFactory;
143 
144     /**
145      * @component role="org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout"
146      */
147     private Map availableRepositoryLayouts;
148 
149     /** @component */
150     private ArtifactResolver artifactResolver;
151 
152     /** @component */
153     private ArtifactMetadataSource metadataSource;
154 
155     /* (non-Javadoc)
156      * @see org.apache.maven.plugin.AbstractMojo#execute()
157      */
158     public void execute ()
159             throws MojoExecutionException, MojoFailureException
160     {
161         // ----------------------------------------------------------------------
162         // Create new repository for dependencies
163         // ----------------------------------------------------------------------
164 
165         ArtifactRepositoryLayout artifactRepositoryLayout =
166                 ( ArtifactRepositoryLayout ) availableRepositoryLayouts.get ( repositoryLayout );
167         if ( artifactRepositoryLayout == null )
168         {
169             throw new MojoFailureException ( "Unknown repository layout '" + repositoryLayout + "'." );
170         }
171 
172         // -----------------------------------------------------------------------
173         // Initialize
174         // -----------------------------------------------------------------------
175 
176         String path = "file://" + assembleDirectory.getAbsolutePath ( ) + "/" + repoPath;
177 
178         ArtifactRepository artifactRepository =
179                 artifactRepositoryFactory.createDeploymentArtifactRepository ( "appassembler", path,
180                         artifactRepositoryLayout, true );
181 
182         // -----------------------------------------------------------------------
183         // Install the project's artifact in the new repository
184         // -----------------------------------------------------------------------
185 
186         installArtifact ( projectArtifact, artifactRepository );
187 
188         // ----------------------------------------------------------------------
189         // Install dependencies in the new repository
190         // ----------------------------------------------------------------------
191 
192         // TODO: merge with the artifacts below so no duplicate versions included
193         for ( Iterator it = artifacts.iterator ( ); it.hasNext ( ); )
194         {
195             Artifact artifact = ( Artifact ) it.next ( );
196 
197             installArtifact ( artifact, artifactRepository );
198         }
199 
200         if ( installBooterArtifacts )
201         {
202             // ----------------------------------------------------------------------
203             // Install appassembler booter in the new repos
204             // ----------------------------------------------------------------------
205             installBooterArtifacts ( artifactRepository );
206         }
207     }
208 
209     private void installBooterArtifacts ( ArtifactRepository artifactRepository )
210             throws MojoExecutionException
211     {
212         Artifact artifact =
213                 artifactFactory.createDependencyArtifact ( "org.codehaus.mojo.appassembler", "appassembler-booter",
214                         VersionRange.createFromVersion ( pluginVersion ), "jar", null,
215                         Artifact.SCOPE_RUNTIME );
216         try
217         {
218             Artifact p =
219                     artifactFactory.createBuildArtifact ( "org.codehaus.mojo.appassembler", "appassembler-maven-plugin",
220                             pluginVersion, "jar" );
221 
222             ArtifactFilter filter = new ExcludesArtifactFilter ( Collections.singletonList ( "junit:junit" ) );
223             ArtifactResolutionResult result =
224                     artifactResolver.resolveTransitively ( Collections.singleton ( artifact ), p, localRepository,
225                             Collections.EMPTY_LIST, metadataSource, filter );
226             for ( Iterator i = result.getArtifacts ( ).iterator ( ); i.hasNext ( ); )
227             {
228                 Artifact a = ( Artifact ) i.next ( );
229                 installArtifact ( a, artifactRepository );
230             }
231         }
232         catch ( ArtifactResolutionException e )
233         {
234             throw new MojoExecutionException ( "Failed to copy artifact.", e );
235         }
236         catch ( ArtifactNotFoundException e )
237         {
238             throw new MojoExecutionException ( "Failed to copy artifact.", e );
239         }
240     }
241 
242     private void installArtifact ( Artifact artifact, ArtifactRepository artifactRepository )
243             throws MojoExecutionException
244     {
245         if ( artifact.getFile ( ) != null )
246         {
247             try
248             {
249                 // Necessary for the artifact's baseVersion to be set correctly
250                 // See: http://mail-archives.apache.org/mod_mbox/maven-dev/200511.mbox/%3c437288F4.4080003@apache.org%3e
251                 artifact.isSnapshot ( );
252 
253                 install ( artifact.getFile ( ), artifact, artifactRepository );
254             }
255             catch ( ArtifactInstallationException e )
256             {
257                 throw new MojoExecutionException ( "Failed to copy artifact.", e );
258             }
259         }
260     }
261 
262     /**
263      * Set the available repository layouts.
264      * @param availableRepositoryLayouts
265      */
266     public void setAvailableRepositoryLayouts ( Map availableRepositoryLayouts )
267     {
268         this.availableRepositoryLayouts = availableRepositoryLayouts;
269     }
270 
271     private void install ( File source, Artifact artifact, ArtifactRepository destinationRepository )
272             throws ArtifactInstallationException
273     {
274         try
275         {
276             String localPath = destinationRepository.pathOf ( artifact );
277 
278             File destination = new File ( destinationRepository.getBasedir ( ), localPath );
279             if ( !destination.getParentFile ( ).exists ( ) )
280             {
281                 destination.getParentFile ( ).mkdirs ( );
282             }
283 
284             getLog ( ).info ( "Installing artifact " + source.getPath ( ) + " to " + destination );
285 
286             FileUtils.copyFile ( source, destination );
287 
288         }
289         catch ( IOException e )
290         {
291             throw new ArtifactInstallationException ( "Error installing artifact: " + e.getMessage ( ), e );
292         }
293     }
294 }