Coverage Report - org.apache.maven.shared.test.plugin.RepositoryTool
 
Classes in this File Line Coverage Branch Coverage Complexity
RepositoryTool
100%
46/46
N/A
4,667
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements.  See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership.  The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License.  You may obtain a copy of the License at
 9  
  *
 10  
  *   http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied.  See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package org.apache.maven.shared.test.plugin;
 20  
 
 21  
 import java.io.File;
 22  
 import java.io.FileReader;
 23  
 import java.io.IOException;
 24  
 import java.net.MalformedURLException;
 25  
 
 26  
 import org.apache.maven.artifact.Artifact;
 27  
 import org.apache.maven.artifact.factory.ArtifactFactory;
 28  
 import org.apache.maven.artifact.installer.ArtifactInstallationException;
 29  
 import org.apache.maven.artifact.installer.ArtifactInstaller;
 30  
 import org.apache.maven.artifact.repository.ArtifactRepository;
 31  
 import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
 32  
 import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
 33  
 import org.apache.maven.model.Model;
 34  
 import org.apache.maven.model.Parent;
 35  
 import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
 36  
 import org.apache.maven.project.MavenProject;
 37  
 import org.apache.maven.project.artifact.ProjectArtifactMetadata;
 38  
 import org.apache.maven.settings.MavenSettingsBuilder;
 39  
 import org.apache.maven.settings.Settings;
 40  
 import org.codehaus.plexus.PlexusConstants;
 41  
 import org.codehaus.plexus.PlexusContainer;
 42  
 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
 43  
 import org.codehaus.plexus.context.Context;
 44  
 import org.codehaus.plexus.context.ContextException;
 45  
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
 46  
 import org.codehaus.plexus.util.IOUtil;
 47  
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 48  
 
 49  
 /**
 50  
  * Tools to access and manage Maven repositories for test builds, including construction of a local 
 51  
  * repository directory structure.
 52  
  * 
 53  
  * <p>
 54  
  * <b>WARNING:</b> Currently, the <code>createLocalRepositoryFromPlugin</code> method will not 
 55  
  * resolve parent POMs that exist <b>only</b> in your normal local repository, and are not reachable 
 56  
  * using the relativePath element. This may result in failed test builds, as one or more of the 
 57  
  * plugin's ancestor POMs cannot be resolved.
 58  
  * </p>
 59  
  * 
 60  
  * @plexus.component role="org.apache.maven.shared.test.plugin.RepositoryTool" role-hint="default"
 61  
  * @author jdcasey
 62  
  */
 63  4
 public class RepositoryTool
 64  
     implements Contextualizable
 65  
 {
 66  2
     public static final String ROLE = RepositoryTool.class.getName();
 67  
 
 68  
     /**
 69  
      * @plexus.requirement
 70  
      */
 71  
     private ArtifactRepositoryFactory repositoryFactory;
 72  
 
 73  
     /**
 74  
      * @plexus.requirement
 75  
      */
 76  
     private MavenSettingsBuilder settingsBuilder;
 77  
 
 78  
     /**
 79  
      * @plexus.requirement
 80  
      */
 81  
     private ArtifactFactory artifactFactory;
 82  
 
 83  
     /**
 84  
      * @plexus.requirement
 85  
      */
 86  
     private ArtifactInstaller artifactInstaller;
 87  
 
 88  
     // contextualized.
 89  
     private PlexusContainer container;
 90  
 
 91  
     /**
 92  
      * Lookup and return the location of the normal Maven local repository.
 93  
      */
 94  
     public File findLocalRepositoryDirectory()
 95  
         throws TestToolsException
 96  
     {
 97  
         Settings settings;
 98  
         try
 99  
         {
 100  2
             settings = settingsBuilder.buildSettings();
 101  
         }
 102  
         catch ( IOException e )
 103  
         {
 104  
             throw new TestToolsException( "Error building Maven settings.", e );
 105  
         }
 106  
         catch ( XmlPullParserException e )
 107  
         {
 108  
             throw new TestToolsException( "Error building Maven settings.", e );
 109  2
         }
 110  
 
 111  2
         return new File( settings.getLocalRepository() );
 112  
     }
 113  
 
 114  
     /**
 115  
      * Construct an ArtifactRepository instance that refers to the normal Maven local repository.
 116  
      */
 117  
     public ArtifactRepository createLocalArtifactRepositoryInstance()
 118  
         throws TestToolsException
 119  
     {
 120  2
         File localRepoDir = findLocalRepositoryDirectory();
 121  
 
 122  2
         return createLocalArtifactRepositoryInstance( localRepoDir );
 123  
     }
 124  
 
 125  
     /**
 126  
      * Construct an ArtifactRepository instance that refers to the test-time Maven local repository.
 127  
      * @param localRepositoryDirectory The location of the local repository to be used for test builds.
 128  
      */
 129  
     public ArtifactRepository createLocalArtifactRepositoryInstance( File localRepositoryDirectory )
 130  
         throws TestToolsException
 131  
     {
 132  
         ArtifactRepositoryLayout defaultLayout;
 133  
         try
 134  
         {
 135  3
             defaultLayout = (ArtifactRepositoryLayout) container.lookup( ArtifactRepositoryLayout.ROLE, "default" );
 136  
         }
 137  
         catch ( ComponentLookupException e )
 138  
         {
 139  
             throw new TestToolsException( "Error retrieving default repository layout.", e );
 140  3
         }
 141  
 
 142  
         try
 143  
         {
 144  3
             return repositoryFactory.createArtifactRepository( "local", localRepositoryDirectory.toURL()
 145  
                 .toExternalForm(), defaultLayout, null, null );
 146  
         }
 147  
         catch ( MalformedURLException e )
 148  
         {
 149  
             throw new TestToolsException( "Error converting local repo directory to a URL.", e );
 150  
         }
 151  
 
 152  
     }
 153  
 
 154  
     /**
 155  
      * Install a test version of a plugin - along with its POM, and as many ancestor POMs as can be
 156  
      * reached using the &lt;relativePath/&gt; element - to a clean local repository directory for
 157  
      * use in test builds.
 158  
      * 
 159  
      * <p>
 160  
      * <b>WARNING:</b> Currently, this method will not resolve parent POMs that exist <b>only</b> in
 161  
      * your normal local repository, and are not reachable using the relativePath element. This may
 162  
      * result in failed test builds, as one or more of the plugin's ancestor POMs cannot be resolved.
 163  
      * </p>
 164  
      * 
 165  
      * @param pluginProject
 166  
      * @param targetLocalRepoBasedir
 167  
      * @throws TestToolsException
 168  
      */
 169  
     public void createLocalRepositoryFromPlugin( MavenProject pluginProject, File targetLocalRepoBasedir )
 170  
         throws TestToolsException
 171  
     {
 172  1
         Artifact artifact = pluginProject.getArtifact();
 173  1
         ArtifactRepository localRepository = createLocalArtifactRepositoryInstance( targetLocalRepoBasedir );
 174  
 
 175  1
         String localPath = localRepository.pathOf( artifact );
 176  
 
 177  1
         File destination = new File( localRepository.getBasedir(), localPath );
 178  1
         if ( !destination.getParentFile().exists() )
 179  
         {
 180  1
             destination.getParentFile().mkdirs();
 181  
         }
 182  
 
 183  
         try
 184  
         {
 185  1
             artifactInstaller.install( artifact.getFile(), artifact, localRepository );
 186  
         }
 187  
         catch ( ArtifactInstallationException e )
 188  
         {
 189  
             throw new TestToolsException( "Error installing plugin artifact to target local repository: "
 190  
                 + targetLocalRepoBasedir, e );
 191  1
         }
 192  
 
 193  1
         installLocallyReachableAncestorPoms( pluginProject.getFile(), localRepository );
 194  1
     }
 195  
 
 196  
     /**
 197  
      * Traverse &lt;relativePath/&gt; links for successive POMs in the plugin's ancestry, installing
 198  
      * each one into the test-time local repository.
 199  
      * 
 200  
      * @param pomFile The plugin POM; a starting point.
 201  
      * @param localRepo The test-time local repository instance
 202  
      */
 203  
     private void installLocallyReachableAncestorPoms( File pomFile, ArtifactRepository localRepo )
 204  
         throws TestToolsException
 205  
     {
 206  1
         MavenXpp3Reader pomReader = new MavenXpp3Reader();
 207  
 
 208  1
         File pom = pomFile;
 209  
 
 210  1
         boolean firstPass = true;
 211  
 
 212  2
         while ( pom != null )
 213  
         {
 214  
 
 215  1
             if ( !pom.exists() )
 216  
             {
 217  
                 pom = null;
 218  
                 break;
 219  
             }
 220  
 
 221  1
             String pomGroupId = null;
 222  1
             String pomArtifactId = null;
 223  1
             String pomVersion = null;
 224  
 
 225  1
             FileReader reader = null;
 226  
 
 227  1
             File currentPom = pom;
 228  
 
 229  
             try
 230  
             {
 231  1
                 reader = new FileReader( pom );
 232  
 
 233  1
                 Model model = pomReader.read( reader );
 234  
 
 235  1
                 pomGroupId = model.getGroupId();
 236  1
                 pomArtifactId = model.getArtifactId();
 237  1
                 pomVersion = model.getVersion();
 238  
 
 239  1
                 Parent parent = model.getParent();
 240  1
                 if ( parent != null )
 241  
                 {
 242  
                     pom = new File( pom.getParentFile(), parent.getRelativePath() );
 243  
                 }
 244  
                 else
 245  
                 {
 246  1
                     pom = null;
 247  
                 }
 248  
             }
 249  
             catch ( IOException e )
 250  
             {
 251  
                 throw new TestToolsException( "Error reading ancestor POM: " + currentPom, e );
 252  
             }
 253  
             catch ( XmlPullParserException e )
 254  
             {
 255  
                 throw new TestToolsException( "Error reading ancestor POM: " + currentPom, e );
 256  
             }
 257  
             finally
 258  
             {
 259  1
                 IOUtil.close( reader );
 260  1
             }
 261  
 
 262  1
             if ( !firstPass )
 263  
             {
 264  
                 Artifact pomArtifact = artifactFactory.createProjectArtifact( pomGroupId, pomArtifactId, pomVersion );
 265  
                 pomArtifact.addMetadata( new ProjectArtifactMetadata( pomArtifact, currentPom ) );
 266  
 
 267  
                 try
 268  
                 {
 269  
                     artifactInstaller.install( currentPom, pomArtifact, localRepo );
 270  
                 }
 271  
                 catch ( ArtifactInstallationException e )
 272  
                 {
 273  
                     throw new TestToolsException( "Error installing ancestor POM: " + currentPom
 274  
                         + " to target local repository: " + localRepo.getBasedir(), e );
 275  
                 }
 276  
             }
 277  
             else
 278  
             {
 279  1
                 firstPass = false;
 280  
             }
 281  1
         }
 282  1
     }
 283  
 
 284  
     /**
 285  
      * Retrieve the PlexusContainer instance used to instantiate this component. The container is
 286  
      * used to retrieve the default ArtifactRepositoryLayout component, for use in constructing
 287  
      * instances of ArtifactRepository that can be used to access local repositories.
 288  
      */
 289  
     public void contextualize( Context context )
 290  
         throws ContextException
 291  
     {
 292  4
         this.container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
 293  4
     }
 294  
 
 295  
 }