Coverage Report - org.apache.maven.plugin.invoker.InstallMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
InstallMojo
0%
0/85
0%
0/36
5.571
 
 1  
 package org.apache.maven.plugin.invoker;
 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.Collection;
 25  
 import java.util.HashMap;
 26  
 import java.util.HashSet;
 27  
 import java.util.Iterator;
 28  
 import java.util.Map;
 29  
 
 30  
 import org.apache.maven.artifact.Artifact;
 31  
 import org.apache.maven.artifact.ArtifactUtils;
 32  
 import org.apache.maven.artifact.factory.ArtifactFactory;
 33  
 import org.apache.maven.artifact.installer.ArtifactInstaller;
 34  
 import org.apache.maven.artifact.repository.ArtifactRepository;
 35  
 import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
 36  
 import org.apache.maven.plugin.AbstractMojo;
 37  
 import org.apache.maven.plugin.MojoExecutionException;
 38  
 import org.apache.maven.project.MavenProject;
 39  
 
 40  
 /**
 41  
  * Installs the project artifacts of the main build into the local repository as a preparation to run the sub projects.
 42  
  * More precisely, all artifacts of the project itself, all its locally reachable parent POMs and all its dependencies
 43  
  * from the reactor will be installed to the local repository.
 44  
  * 
 45  
  * @goal install
 46  
  * @phase pre-integration-test
 47  
  * @requiresDependencyResolution runtime
 48  
  * @since 1.2
 49  
  * @author Paul Gier
 50  
  * @author Benjamin Bentmann
 51  
  * @version $Id: InstallMojo.java 698334 2008-09-23 20:16:00Z bentmann $
 52  
  */
 53  0
 public class InstallMojo
 54  
     extends AbstractMojo
 55  
 {
 56  
 
 57  
     /**
 58  
      * Maven artifact install component to copy artifacts to the local repository.
 59  
      * 
 60  
      * @component
 61  
      */
 62  
     private ArtifactInstaller installer;
 63  
 
 64  
     /**
 65  
      * The component used to create artifacts.
 66  
      * 
 67  
      * @component
 68  
      */
 69  
     private ArtifactFactory artifactFactory;
 70  
 
 71  
     /**
 72  
      * The component used to create artifacts.
 73  
      * 
 74  
      * @component
 75  
      */
 76  
     private ArtifactRepositoryFactory repositoryFactory;
 77  
 
 78  
     /**
 79  
      * @parameter expression="${localRepository}"
 80  
      * @required
 81  
      * @readonly
 82  
      */
 83  
     private ArtifactRepository localRepository;
 84  
 
 85  
     /**
 86  
      * The path to the local repository into which the project artifacts should be installed for the integration tests.
 87  
      * If not set, the regular local repository will be used. To prevent soiling of your regular local repository with
 88  
      * possibly broken artifacts, it is strongly recommended to use an isolated repository for the integration tests
 89  
      * (e.g. <code>${project.build.directory}/it-repo</code>).
 90  
      * 
 91  
      * @parameter expression="${invoker.localRepositoryPath}"
 92  
      */
 93  
     private File localRepositoryPath;
 94  
 
 95  
     /**
 96  
      * The current Maven project.
 97  
      * 
 98  
      * @parameter expression="${project}"
 99  
      * @required
 100  
      * @readonly
 101  
      */
 102  
     private MavenProject project;
 103  
 
 104  
     /**
 105  
      * The set of Maven projects in the reactor build.
 106  
      * 
 107  
      * @parameter default-value="${reactorProjects}"
 108  
      * @readonly
 109  
      */
 110  
     private Collection reactorProjects;
 111  
 
 112  
     /**
 113  
      * Performs this mojo's tasks.
 114  
      * 
 115  
      * @throws MojoExecutionException If the artifacts could not be installed.
 116  
      */
 117  
     public void execute()
 118  
         throws MojoExecutionException
 119  
     {
 120  0
         ArtifactRepository testRepository = createTestRepository();
 121  
 
 122  0
         installProjectArtifacts( project, testRepository );
 123  0
         installProjectParents( project, testRepository );
 124  0
         installProjectDependencies( project, reactorProjects, testRepository );
 125  0
     }
 126  
 
 127  
     /**
 128  
      * Creates the local repository for the integration tests. If the user specified a custom repository location, the
 129  
      * custom repository will have the same identifier, layout and policies as the real local repository. That means
 130  
      * apart from the location, the custom repository will be indistinguishable from the real repository such that its
 131  
      * usage is transparent to the integration tests.
 132  
      * 
 133  
      * @return The local repository for the integration tests, never <code>null</code>.
 134  
      * @throws MojoExecutionException If the repository could not be created.
 135  
      */
 136  
     private ArtifactRepository createTestRepository()
 137  
         throws MojoExecutionException
 138  
     {
 139  0
         ArtifactRepository testRepository = localRepository;
 140  
 
 141  0
         if ( localRepositoryPath != null )
 142  
         {
 143  
             try
 144  
             {
 145  0
                 if ( !localRepositoryPath.exists() && !localRepositoryPath.mkdirs() )
 146  
                 {
 147  0
                     throw new IOException( "Failed to create directory: " + localRepositoryPath );
 148  
                 }
 149  
 
 150  0
                 testRepository =
 151  
                     repositoryFactory.createArtifactRepository( localRepository.getId(),
 152  
                                                                 localRepositoryPath.toURL().toExternalForm(),
 153  
                                                                 localRepository.getLayout(),
 154  
                                                                 localRepository.getSnapshots(),
 155  
                                                                 localRepository.getReleases() );
 156  
             }
 157  0
             catch ( Exception e )
 158  
             {
 159  0
                 throw new MojoExecutionException( "Failed to create local repository: " + localRepositoryPath, e );
 160  0
             }
 161  
         }
 162  
 
 163  0
         return testRepository;
 164  
     }
 165  
 
 166  
     /**
 167  
      * Installs the specified artifact to the local repository.
 168  
      * 
 169  
      * @param file The file associated with the artifact, must not be <code>null</code>. This is in most cases the value
 170  
      *            of <code>artifact.getFile()</code> with the exception of the main artifact from a project with
 171  
      *            packaging "pom". Projects with packaging "pom" have no main artifact file. They have however artifact
 172  
      *            metadata (e.g. site descriptors) which needs to be installed.
 173  
      * @param artifact The artifact to install, must not be <code>null</code>.
 174  
      * @param testRepository The local repository to install the artifact to, must not be <code>null</code>.
 175  
      * @throws MojoExecutionException If the artifact could not be installed (e.g. has no associated file).
 176  
      */
 177  
     private void installArtifact( File file, Artifact artifact, ArtifactRepository testRepository )
 178  
         throws MojoExecutionException
 179  
     {
 180  
         try
 181  
         {
 182  0
             if ( file == null )
 183  
             {
 184  0
                 throw new IllegalStateException( "Artifact has no associated file: " + file );
 185  
             }
 186  0
             if ( !file.isFile() )
 187  
             {
 188  0
                 throw new IllegalStateException( "Artifact is not fully assembled: " + file );
 189  
             }
 190  0
             installer.install( file, artifact, testRepository );
 191  
         }
 192  0
         catch ( Exception e )
 193  
         {
 194  0
             throw new MojoExecutionException( "Failed to install artifact: " + artifact, e );
 195  0
         }
 196  0
     }
 197  
 
 198  
     /**
 199  
      * Installs the main artifact and any attached artifacts of the specified project to the local repository.
 200  
      * 
 201  
      * @param mvnProject The project whose artifacts should be installed, must not be <code>null</code>.
 202  
      * @param testRepository The local repository to install the artifacts to, must not be <code>null</code>.
 203  
      * @throws MojoExecutionException If any artifact could not be installed.
 204  
      */
 205  
     private void installProjectArtifacts( MavenProject mvnProject, ArtifactRepository testRepository )
 206  
         throws MojoExecutionException
 207  
     {
 208  
         try
 209  
         {
 210  0
             installProjectPom( mvnProject, testRepository );
 211  
 
 212  
             // Install the main project artifact (if the project has one, e.g. has no "pom" packaging)
 213  0
             Artifact mainArtifact = mvnProject.getArtifact();
 214  0
             if ( mainArtifact.getFile() != null )
 215  
             {
 216  0
                 installArtifact( mainArtifact.getFile(), mainArtifact, testRepository );
 217  
             }
 218  
 
 219  
             // Install any attached project artifacts
 220  0
             Collection attachedArtifacts = mvnProject.getAttachedArtifacts();
 221  0
             for ( Iterator artifactIter = attachedArtifacts.iterator(); artifactIter.hasNext(); )
 222  
             {
 223  0
                 Artifact attachedArtifact = (Artifact) artifactIter.next();
 224  0
                 installArtifact( attachedArtifact.getFile(), attachedArtifact, testRepository );
 225  
             }
 226  
         }
 227  0
         catch ( Exception e )
 228  
         {
 229  0
             throw new MojoExecutionException( "Failed to install project artifacts: " + mvnProject, e );
 230  0
         }
 231  0
     }
 232  
 
 233  
     /**
 234  
      * Installs the (locally reachable) parent POMs of the specified project to the local repository. The parent POMs
 235  
      * from the reactor must be installed or the forked IT builds will fail when using a clean repository.
 236  
      * 
 237  
      * @param mvnProject The project whose parent POMs should be installed, must not be <code>null</code>.
 238  
      * @param testRepository The local repository to install the POMs to, must not be <code>null</code>.
 239  
      * @throws MojoExecutionException If any POM could not be installed.
 240  
      */
 241  
     private void installProjectParents( MavenProject mvnProject, ArtifactRepository testRepository )
 242  
         throws MojoExecutionException
 243  
     {
 244  
         try
 245  
         {
 246  0
             for ( MavenProject parent = mvnProject.getParent(); parent != null; parent = parent.getParent() )
 247  
             {
 248  0
                 if ( parent.getFile() == null )
 249  
                 {
 250  0
                     break;
 251  
                 }
 252  0
                 installProjectPom( parent, testRepository );
 253  
             }
 254  
         }
 255  0
         catch ( Exception e )
 256  
         {
 257  0
             throw new MojoExecutionException( "Failed to install project parents: " + mvnProject, e );
 258  0
         }
 259  0
     }
 260  
 
 261  
     /**
 262  
      * Installs the POM of the specified project to the local repository.
 263  
      * 
 264  
      * @param mvnProject The project whose POM should be installed, must not be <code>null</code>.
 265  
      * @param testRepository The local repository to install the POM to, must not be <code>null</code>.
 266  
      * @throws MojoExecutionException If the POM could not be installed.
 267  
      */
 268  
     private void installProjectPom( MavenProject mvnProject, ArtifactRepository testRepository )
 269  
         throws MojoExecutionException
 270  
     {
 271  
         try
 272  
         {
 273  0
             Artifact pomArtifact = null;
 274  0
             if ( "pom".equals( mvnProject.getPackaging() ) )
 275  
             {
 276  0
                 pomArtifact = mvnProject.getArtifact();
 277  
             }
 278  0
             if ( pomArtifact == null )
 279  
             {
 280  0
                 pomArtifact =
 281  
                     artifactFactory.createProjectArtifact( mvnProject.getGroupId(), mvnProject.getArtifactId(),
 282  
                                                            mvnProject.getVersion() );
 283  
             }
 284  0
             installArtifact( mvnProject.getFile(), pomArtifact, testRepository );
 285  
         }
 286  0
         catch ( Exception e )
 287  
         {
 288  0
             throw new MojoExecutionException( "Failed to install POM: " + mvnProject, e );
 289  0
         }
 290  0
     }
 291  
 
 292  
     /**
 293  
      * Installs the dependent projects from the reactor to the local repository. The dependencies on other modules from
 294  
      * the reactor must be installed or the forked IT builds will fail when using a clean repository.
 295  
      * 
 296  
      * @param mvnProject The project whose dependent projects should be installed, must not be <code>null</code>.
 297  
      * @param reactorProjects The set of projects in the reactor build, must not be <code>null</code>.
 298  
      * @param testRepository The local repository to install the POMs to, must not be <code>null</code>.
 299  
      * @throws MojoExecutionException If any dependency could not be installed.
 300  
      */
 301  
     private void installProjectDependencies( MavenProject mvnProject, Collection reactorProjects,
 302  
                                              ArtifactRepository testRepository )
 303  
         throws MojoExecutionException
 304  
     {
 305  
         // index available reactor projects
 306  0
         Map projects = new HashMap();
 307  0
         for ( Iterator it = reactorProjects.iterator(); it.hasNext(); )
 308  
         {
 309  0
             MavenProject reactorProject = (MavenProject) it.next();
 310  0
             String id = reactorProject.getGroupId() + ':' + reactorProject.getArtifactId();
 311  0
             projects.put( id, reactorProject );
 312  
         }
 313  
 
 314  
         // collect transitive dependencies
 315  0
         Collection dependencies = new HashSet();
 316  0
         for ( Iterator it = mvnProject.getRuntimeArtifacts().iterator(); it.hasNext(); )
 317  
         {
 318  0
             Artifact artifact = (Artifact) it.next();
 319  0
             String id = ArtifactUtils.versionlessKey( artifact );
 320  
             
 321  0
             dependencies.add( id );
 322  
         }
 323  
 
 324  
         // install dependencies
 325  
         try
 326  
         {
 327  
             // install dependencies from reactor
 328  0
             for ( Iterator it = dependencies.iterator(); it.hasNext(); )
 329  
             {
 330  0
                 String id = (String) it.next();
 331  0
                 MavenProject requiredProject = (MavenProject) projects.remove( id );
 332  0
                 if ( requiredProject != null )
 333  
                 {
 334  0
                     it.remove();
 335  0
                     installProjectArtifacts( requiredProject, testRepository );
 336  0
                     installProjectParents( requiredProject, testRepository );
 337  
                 }
 338  
             }
 339  
 
 340  
             // install remaining dependencies from local repository
 341  0
             for ( Iterator it = mvnProject.getRuntimeArtifacts().iterator(); it.hasNext(); )
 342  
             {
 343  0
                 Artifact artifact = (Artifact) it.next();
 344  0
                 String id = ArtifactUtils.versionlessKey( artifact );
 345  
 
 346  0
                 if ( dependencies.contains( id ) )
 347  
                 {
 348  0
                     File artifactFile = artifact.getFile();
 349  
 
 350  0
                     installArtifact( artifactFile, artifact, testRepository );
 351  
 
 352  0
                     Artifact pomArtifact =
 353  
                         artifactFactory.createArtifact( artifact.getGroupId(), artifact.getArtifactId(),
 354  
                                                         artifact.getVersion(), null, "pom" );
 355  
 
 356  0
                     File pomFile = new File( localRepository.getBasedir(), localRepository.pathOf( pomArtifact ) );
 357  
 
 358  0
                     if ( pomFile.exists() )
 359  
                     {
 360  0
                         installArtifact( pomFile, pomArtifact, testRepository );
 361  
                     }
 362  
                 }
 363  
             }
 364  
         }
 365  0
         catch ( Exception e )
 366  
         {
 367  0
             throw new MojoExecutionException( "Failed to install project dependencies: " + mvnProject, e );
 368  0
         }
 369  0
     }
 370  
 
 371  
 }