Coverage Report - org.apache.maven.plugins.linkcheck.SiteInvoker
 
Classes in this File Line Coverage Branch Coverage Complexity
SiteInvoker
0%
0/156
0%
0/48
4,6
 
 1  
 /*
 2  
  *  Licensed under the Apache License, Version 2.0 (the "License");
 3  
  *  you may not use this file except in compliance with the License.
 4  
  *  You may obtain a copy of the License at
 5  
  * 
 6  
  *       http://www.apache.org/licenses/LICENSE-2.0
 7  
  * 
 8  
  *  Unless required by applicable law or agreed to in writing, software
 9  
  *  distributed under the License is distributed on an "AS IS" BASIS,
 10  
  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 11  
  *  See the License for the specific language governing permissions and
 12  
  *  limitations under the License.
 13  
  */
 14  
 
 15  
 package org.apache.maven.plugins.linkcheck;
 16  
 
 17  
 import java.io.File;
 18  
 import java.io.FileNotFoundException;
 19  
 import java.io.FileOutputStream;
 20  
 import java.io.IOException;
 21  
 import java.io.OutputStream;
 22  
 import java.io.PrintStream;
 23  
 import java.io.Reader;
 24  
 import java.io.UnsupportedEncodingException;
 25  
 import java.io.Writer;
 26  
 import java.util.ArrayList;
 27  
 
 28  
 import java.util.Collections;
 29  
 import java.util.Iterator;
 30  
 import java.util.List;
 31  
 import java.util.Properties;
 32  
 
 33  
 import org.apache.commons.lang.SystemUtils;
 34  
 import org.apache.maven.artifact.repository.ArtifactRepository;
 35  
 
 36  
 import org.apache.maven.model.Profile;
 37  
 import org.apache.maven.model.Reporting;
 38  
 import org.apache.maven.project.MavenProject;
 39  
 
 40  
 import org.apache.maven.plugin.logging.Log;
 41  
 import org.apache.maven.shared.invoker.DefaultInvocationRequest;
 42  
 import org.apache.maven.shared.invoker.DefaultInvoker;
 43  
 import org.apache.maven.shared.invoker.InvocationOutputHandler;
 44  
 import org.apache.maven.shared.invoker.InvocationRequest;
 45  
 import org.apache.maven.shared.invoker.InvocationResult;
 46  
 import org.apache.maven.shared.invoker.Invoker;
 47  
 import org.apache.maven.shared.invoker.MavenInvocationException;
 48  
 import org.apache.maven.shared.invoker.PrintStreamHandler;
 49  
 
 50  
 import org.codehaus.plexus.util.FileUtils;
 51  
 import org.codehaus.plexus.util.IOUtil;
 52  
 import org.codehaus.plexus.util.ReaderFactory;
 53  
 import org.codehaus.plexus.util.StringUtils;
 54  
 import org.codehaus.plexus.util.WriterFactory;
 55  
 import org.codehaus.plexus.util.cli.CommandLineUtils;
 56  
 
 57  
 
 58  
 /**
 59  
  *
 60  
  * @author ltheussl
 61  
  * @since 1.1
 62  
  */
 63  
 public class SiteInvoker
 64  
 {
 65  
     private final ArtifactRepository localRepository;
 66  
     private final Log log;
 67  
 
 68  
     public SiteInvoker( ArtifactRepository localRepository, Log log )
 69  0
     {
 70  0
         this.localRepository = localRepository;
 71  0
         this.log = log;
 72  0
     }
 73  
 
 74  
     /**
 75  
      * Invoke Maven for the <code>site</code> phase for a temporary Maven project using
 76  
      * <code>tmpReportingOutputDirectory</code> as <code>${project.reporting.outputDirectory}</code>.
 77  
      * This is a workaround to be sure that all site files have been correctly generated.
 78  
      * <br/>
 79  
      * <b>Note 1</b>: the Maven Home should be defined in the <code>maven.home</code> Java system property
 80  
      * or defined in <code>M2_HOME</code> system env variables.
 81  
      * <b>Note 2</be>: we can't use <code>siteOutputDirectory</code> param from site plugin because some plugins
 82  
      * <code>${project.reporting.outputDirectory}</code> in their conf.
 83  
      *
 84  
      * @param project the MavenProject to invoke the site on. Not null.
 85  
      * @param tmpReportingOutputDirectory not null
 86  
      * @throws IOException if any
 87  
      */
 88  
     public void invokeSite( MavenProject project, File tmpReportingOutputDirectory )
 89  
         throws IOException
 90  
     {
 91  0
         String mavenHome = getMavenHome();
 92  0
         if ( StringUtils.isEmpty( mavenHome ) )
 93  
         {
 94  0
             getLog().error( "Could NOT invoke Maven because no Maven Home is defined. "
 95  
                 + "You need to set the M2_HOME system env variable or a 'maven.home' Java system property." );
 96  0
             return;
 97  
         }
 98  
 
 99  
         // invoker site parameters
 100  0
         List goals = Collections.singletonList( "site" );
 101  0
         Properties properties = new Properties();
 102  0
         properties.put( "linkcheck.skip", "true" ); // to stop recursion
 103  
 
 104  0
         File invokerLog =
 105  
             FileUtils.createTempFile( "invoker-site-plugin", ".txt", new File( project.getBuild().getDirectory() ) );
 106  
 
 107  
         // clone project and set a new reporting output dir
 108  
         MavenProject clone;
 109  
         try
 110  
         {
 111  0
             clone = (MavenProject) project.clone();
 112  
         }
 113  0
         catch ( CloneNotSupportedException e )
 114  
         {
 115  0
             IOException ioe = new IOException( "CloneNotSupportedException: " + e.getMessage() );
 116  0
             ioe.setStackTrace( e.getStackTrace() );
 117  0
             throw ioe;
 118  0
         }
 119  
 
 120  
         // MLINKCHECK-1
 121  0
         if ( clone.getOriginalModel().getReporting() == null )
 122  
         {
 123  0
             clone.getOriginalModel().setReporting( new Reporting() );
 124  
         }
 125  
 
 126  0
         clone.getOriginalModel().getReporting().setOutputDirectory( tmpReportingOutputDirectory.getAbsolutePath() );
 127  0
         List profileIds = getActiveProfileIds( clone );
 128  
 
 129  
         // create the original model as tmp pom file for the invoker
 130  0
         File tmpProjectFile = FileUtils.createTempFile( "pom", ".xml", project.getBasedir() );
 131  0
         Writer writer = null;
 132  
         try
 133  
         {
 134  0
             writer = WriterFactory.newXmlWriter( tmpProjectFile );
 135  0
             clone.writeOriginalModel( writer );
 136  
         }
 137  
         finally
 138  
         {
 139  0
             IOUtil.close( writer );
 140  0
         }
 141  
 
 142  
         // invoke it
 143  
         try
 144  
         {
 145  0
             invoke( tmpProjectFile, invokerLog, mavenHome, goals, profileIds, properties );
 146  
         }
 147  
         finally
 148  
         {
 149  0
             if ( !getLog().isDebugEnabled() )
 150  
             {
 151  0
                 tmpProjectFile.delete();
 152  
             }
 153  
         }
 154  0
     }
 155  
 
 156  
     private static List getActiveProfileIds( MavenProject clone )
 157  
     {
 158  0
         List profileIds = new ArrayList();
 159  
 
 160  0
         for ( Iterator it = clone.getActiveProfiles().iterator(); it.hasNext(); )
 161  
         {
 162  0
             profileIds.add( ( (Profile) it.next() ).getId() );
 163  
         }
 164  
 
 165  0
         return profileIds;
 166  
     }
 167  
 
 168  
     /**
 169  
      * @param projectFile not null, should be in the ${project.basedir}
 170  
      * @param invokerLog not null
 171  
      * @param mavenHome not null
 172  
      * @param goals the list of goals
 173  
      * @param properties the properties for the invoker
 174  
      */
 175  
     private void invoke( File projectFile, File invokerLog, String mavenHome,
 176  
         List goals, List activeProfiles, Properties properties )
 177  
     {
 178  0
         Invoker invoker = new DefaultInvoker();
 179  0
         invoker.setMavenHome( new File( mavenHome ) );
 180  0
         File localRepoDir = new File( localRepository.getBasedir() );
 181  0
         invoker.setLocalRepositoryDirectory( localRepoDir );
 182  
 
 183  0
         InvocationRequest request = new DefaultInvocationRequest();
 184  0
         request.setLocalRepositoryDirectory( localRepoDir );
 185  
         //request.setUserSettingsFile( settingsFile );
 186  0
         request.setInteractive( false );
 187  0
         request.setShowErrors( getLog().isErrorEnabled() );
 188  0
         request.setDebug( getLog().isDebugEnabled() );
 189  
         //request.setShowVersion( false );
 190  0
         request.setBaseDirectory( projectFile.getParentFile() );
 191  0
         request.setPomFile( projectFile );
 192  0
         request.setGoals( goals );
 193  0
         request.setProperties( properties );
 194  0
         request.setProfiles( activeProfiles );
 195  
 
 196  0
         File javaHome = getJavaHome();
 197  0
         if ( javaHome != null )
 198  
         {
 199  0
             request.setJavaHome( javaHome );
 200  
         }
 201  
 
 202  
         InvocationResult invocationResult;
 203  
         try
 204  
         {
 205  0
             if ( getLog().isDebugEnabled() )
 206  
             {
 207  0
                 getLog().debug( "Invoking Maven for the goals: " + goals + " with properties=" + properties );
 208  
             }
 209  0
             invocationResult = invoke( invoker, request, invokerLog, goals, properties, null );
 210  
         }
 211  0
         catch ( MavenInvocationException e )
 212  
         {
 213  0
             getLog().error( "Error when invoking Maven, consult the invoker log." );
 214  0
             getLog().debug( e );
 215  0
             return;
 216  0
         }
 217  
 
 218  0
         String invokerLogContent = null;
 219  0
         Reader reader = null;
 220  
         try
 221  
         {
 222  0
             reader = ReaderFactory.newReader( invokerLog, "UTF-8" );
 223  0
             invokerLogContent = IOUtil.toString( reader );
 224  
         }
 225  0
         catch ( IOException e )
 226  
         {
 227  0
             getLog().error( "IOException: " + e.getMessage() );
 228  0
             getLog().debug( e );
 229  
         }
 230  
         finally
 231  
         {
 232  0
             IOUtil.close( reader );
 233  0
         }
 234  
 
 235  0
         if ( invokerLogContent != null
 236  
             && invokerLogContent.indexOf( "Error occurred during initialization of VM" ) != -1 )
 237  
         {
 238  0
             getLog().info( "Error occurred during initialization of VM, try to use an empty MAVEN_OPTS." );
 239  
 
 240  0
             if ( getLog().isDebugEnabled() )
 241  
             {
 242  0
                 getLog().debug( "Reinvoking Maven for the goals: " + goals + " with an empty MAVEN_OPTS" );
 243  
             }
 244  
 
 245  
             try
 246  
             {
 247  0
                 invocationResult = invoke( invoker, request, invokerLog, goals, properties, "" );
 248  
             }
 249  0
             catch ( MavenInvocationException e )
 250  
             {
 251  0
                 getLog().error( "Error when reinvoking Maven, consult the invoker log." );
 252  0
                 getLog().debug( e );
 253  0
                 return;
 254  0
             }
 255  
         }
 256  
 
 257  0
         if ( invocationResult.getExitCode() != 0 )
 258  
         {
 259  0
             if ( getLog().isErrorEnabled() )
 260  
             {
 261  0
                 getLog().error( "Error when invoking Maven, consult the invoker log file: "
 262  
                                     + invokerLog.getAbsolutePath() );
 263  
             }
 264  
         }
 265  0
     }
 266  
 
 267  
     /**
 268  
      * @param invoker not null
 269  
      * @param request not null
 270  
      * @param invokerLog not null
 271  
      * @param goals the list of goals
 272  
      * @param properties the properties for the invoker
 273  
      * @param mavenOpts could be null
 274  
      * @return the invocation result
 275  
      * @throws MavenInvocationException if any
 276  
      */
 277  
     private InvocationResult invoke( Invoker invoker, InvocationRequest request, File invokerLog, List goals,
 278  
                                      Properties properties, String mavenOpts )
 279  
         throws MavenInvocationException
 280  
     {
 281  
         PrintStream ps;
 282  0
         OutputStream os = null;
 283  0
         if ( invokerLog != null )
 284  
         {
 285  0
             if ( getLog().isDebugEnabled() )
 286  
             {
 287  0
                 getLog().debug( "Using " + invokerLog.getAbsolutePath() + " to log the invoker" );
 288  
             }
 289  
 
 290  
             try
 291  
             {
 292  0
                 if ( !invokerLog.exists() )
 293  
                 {
 294  0
                     invokerLog.getParentFile().mkdirs();
 295  
                 }
 296  0
                 os = new FileOutputStream( invokerLog );
 297  0
                 ps = new PrintStream( os, true, "UTF-8" );
 298  
             }
 299  0
             catch ( FileNotFoundException e )
 300  
             {
 301  0
                 if ( getLog().isErrorEnabled() )
 302  
                 {
 303  0
                     getLog().error( "FileNotFoundException: " + e.getMessage()
 304  
                                         + ". Using System.out to log the invoker." );
 305  
                 }
 306  0
                 ps = System.out;
 307  
             }
 308  0
             catch ( UnsupportedEncodingException e )
 309  
             {
 310  0
                 if ( getLog().isErrorEnabled() )
 311  
                 {
 312  0
                     getLog().error( "UnsupportedEncodingException: " + e.getMessage()
 313  
                                         + ". Using System.out to log the invoker." );
 314  
                 }
 315  0
                 ps = System.out;
 316  0
             }
 317  
         }
 318  
         else
 319  
         {
 320  0
             getLog().debug( "Using System.out to log the invoker." );
 321  
 
 322  0
             ps = System.out;
 323  
         }
 324  
 
 325  0
         if ( mavenOpts != null )
 326  
         {
 327  0
             request.setMavenOpts( mavenOpts );
 328  
         }
 329  
 
 330  0
         InvocationOutputHandler outputHandler = new PrintStreamHandler( ps, false );
 331  0
         request.setOutputHandler( outputHandler );
 332  0
         request.setErrorHandler( outputHandler );
 333  
 
 334  0
         outputHandler.consumeLine( "Invoking Maven for the goals: " + goals + " with properties=" + properties );
 335  0
         outputHandler.consumeLine( "" );
 336  0
         outputHandler.consumeLine( "M2_HOME=" + getMavenHome() );
 337  0
         outputHandler.consumeLine( "MAVEN_OPTS=" + getMavenOpts() );
 338  0
         outputHandler.consumeLine( "JAVA_HOME=" + getJavaHome() );
 339  0
         outputHandler.consumeLine( "JAVA_OPTS=" + getJavaOpts() );
 340  0
         outputHandler.consumeLine( "" );
 341  
 
 342  
         try
 343  
         {
 344  0
             return invoker.execute( request );
 345  
         }
 346  
         finally
 347  
         {
 348  0
             IOUtil.close( os );
 349  0
             ps = null;
 350  
         }
 351  
     }
 352  
 
 353  
     /**
 354  
      * @return the Maven home defined in the <code>maven.home</code> system property or defined
 355  
      * in <code>M2_HOME</code> system env variables or null if never setted.
 356  
      * @see #invoke(Invoker, InvocationRequest, File, List, Properties, String)
 357  
      */
 358  
     private String getMavenHome()
 359  
     {
 360  0
         String mavenHome = System.getProperty( "maven.home" );
 361  0
         if ( mavenHome == null )
 362  
         {
 363  
             try
 364  
             {
 365  0
                 mavenHome = CommandLineUtils.getSystemEnvVars().getProperty( "M2_HOME" );
 366  
             }
 367  0
             catch ( IOException e )
 368  
             {
 369  0
                 getLog().error( "IOException: " + e.getMessage() );
 370  0
                 getLog().debug( e );
 371  0
             }
 372  
         }
 373  
 
 374  0
         File m2Home = new File( mavenHome );
 375  0
         if ( !m2Home.exists() )
 376  
         {
 377  0
             getLog().error( "Cannot find Maven application directory. Either specify \'maven.home\' "
 378  
                 + "system property, or M2_HOME environment variable." );
 379  
         }
 380  
 
 381  0
         return mavenHome;
 382  
     }
 383  
 
 384  
     /**
 385  
      * @return the <code>MAVEN_OPTS</code> env variable value or null if not setted.
 386  
      * @see #invoke(Invoker, InvocationRequest, File, List, Properties, String)
 387  
      */
 388  
     private String getMavenOpts()
 389  
     {
 390  0
         String mavenOpts = null;
 391  
         try
 392  
         {
 393  0
             mavenOpts = CommandLineUtils.getSystemEnvVars().getProperty( "MAVEN_OPTS" );
 394  
         }
 395  0
         catch ( IOException e )
 396  
         {
 397  0
             getLog().error( "IOException: " + e.getMessage() );
 398  0
             getLog().debug( e );
 399  0
         }
 400  
 
 401  0
         return mavenOpts;
 402  
     }
 403  
 
 404  
     /**
 405  
      * @return the <code>JAVA_HOME</code> from System.getProperty( "java.home" )
 406  
      * By default, <code>System.getProperty( "java.home" ) = JRE_HOME</code> and <code>JRE_HOME</code>
 407  
      * should be in the <code>JDK_HOME</code> or null if not setted.
 408  
      * @see #invoke(Invoker, InvocationRequest, File, List, Properties, String)
 409  
      */
 410  
     private File getJavaHome()
 411  
     {
 412  
         File javaHome;
 413  0
         if ( SystemUtils.IS_OS_MAC_OSX )
 414  
         {
 415  0
             javaHome = SystemUtils.getJavaHome();
 416  
         }
 417  
         else
 418  
         {
 419  0
             javaHome = new File( SystemUtils.getJavaHome(), ".." );
 420  
         }
 421  
 
 422  0
         if ( javaHome == null || !javaHome.exists() )
 423  
         {
 424  
             try
 425  
             {
 426  0
                 javaHome = new File( CommandLineUtils.getSystemEnvVars().getProperty( "JAVA_HOME" ) );
 427  
             }
 428  0
             catch ( IOException e )
 429  
             {
 430  0
                 getLog().error( "IOException: " + e.getMessage() );
 431  0
                 getLog().debug( e );
 432  0
             }
 433  
         }
 434  
 
 435  0
         if ( javaHome == null || !javaHome.exists() )
 436  
         {
 437  0
             getLog().error( "Cannot find Java application directory. Either specify \'java.home\' "
 438  
                 + "system property, or JAVA_HOME environment variable." );
 439  
         }
 440  
 
 441  0
         return javaHome;
 442  
     }
 443  
 
 444  
     /**
 445  
      * @return the <code>JAVA_OPTS</code> env variable value or null if not setted.
 446  
      * @see #invoke(Invoker, InvocationRequest, File, List, Properties, String)
 447  
      */
 448  
     private String getJavaOpts()
 449  
     {
 450  0
         String javaOpts = null;
 451  
         try
 452  
         {
 453  0
             javaOpts = CommandLineUtils.getSystemEnvVars().getProperty( "JAVA_OPTS" );
 454  
         }
 455  0
         catch ( IOException e )
 456  
         {
 457  0
             getLog().error( "IOException: " + e.getMessage() );
 458  0
             getLog().debug( e );
 459  0
         }
 460  
 
 461  0
         return javaOpts;
 462  
     }
 463  
 
 464  
     private Log getLog()
 465  
     {
 466  0
         return log;
 467  
     }
 468  
 }