Coverage Report - org.apache.maven.reporting.exec.DefaultMavenReportExecutor
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultMavenReportExecutor
56%
96/169
33%
35/106
8
 
 1  
 package org.apache.maven.reporting.exec;
 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.util.ArrayList;
 23  
 import java.util.Arrays;
 24  
 import java.util.Collections;
 25  
 import java.util.LinkedHashMap;
 26  
 import java.util.List;
 27  
 import java.util.Map;
 28  
 import java.util.Map.Entry;
 29  
 
 30  
 import org.apache.maven.artifact.repository.DefaultRepositoryRequest;
 31  
 import org.apache.maven.artifact.repository.RepositoryRequest;
 32  
 import org.apache.maven.artifact.resolver.filter.ExclusionSetFilter;
 33  
 import org.apache.maven.execution.MavenSession;
 34  
 import org.apache.maven.lifecycle.LifecycleExecutor;
 35  
 import org.apache.maven.model.Plugin;
 36  
 import org.apache.maven.plugin.MavenPluginManager;
 37  
 import org.apache.maven.plugin.Mojo;
 38  
 import org.apache.maven.plugin.MojoExecution;
 39  
 import org.apache.maven.plugin.MojoExecutionException;
 40  
 import org.apache.maven.plugin.MojoNotFoundException;
 41  
 import org.apache.maven.plugin.PluginConfigurationException;
 42  
 import org.apache.maven.plugin.PluginContainerException;
 43  
 import org.apache.maven.plugin.descriptor.MojoDescriptor;
 44  
 import org.apache.maven.plugin.descriptor.PluginDescriptor;
 45  
 import org.apache.maven.plugin.version.DefaultPluginVersionRequest;
 46  
 import org.apache.maven.plugin.version.PluginVersionRequest;
 47  
 import org.apache.maven.plugin.version.PluginVersionResolutionException;
 48  
 import org.apache.maven.plugin.version.PluginVersionResolver;
 49  
 import org.apache.maven.plugin.version.PluginVersionResult;
 50  
 import org.apache.maven.project.MavenProject;
 51  
 import org.apache.maven.reporting.MavenReport;
 52  
 import org.codehaus.classworlds.ClassRealm;
 53  
 import org.codehaus.plexus.component.annotations.Component;
 54  
 import org.codehaus.plexus.component.annotations.Requirement;
 55  
 import org.codehaus.plexus.configuration.PlexusConfiguration;
 56  
 import org.codehaus.plexus.logging.Logger;
 57  
 import org.codehaus.plexus.util.StringUtils;
 58  
 import org.codehaus.plexus.util.xml.Xpp3Dom;
 59  
 import org.codehaus.plexus.util.xml.Xpp3DomUtils;
 60  
 import org.sonatype.aether.repository.RemoteRepository;
 61  
 import org.sonatype.aether.util.filter.ExclusionsDependencyFilter;
 62  
 
 63  
 /**
 64  
  * <p>
 65  
  *   This component will build some {@link MavenReportExecution} from {@link MavenReportExecutorRequest}.
 66  
  *   If a {@link MavenReport} need to fork a lifecycle, this fork is executed here. 
 67  
  *   It will ask the core to get some informations in order to correctly setup {@link MavenReport}.
 68  
  * </p>
 69  
  * <p>
 70  
  *   <b>Note</b> if no version is defined in the report plugin the version will be search 
 71  
  *   with method {@link #getPluginVersion(ReportPlugin, RepositoryRequest, MavenReportExecutorRequest)}
 72  
  *   Steps to find a plugin version stop after each step if a non <code>null</code> value has been found:
 73  
  *   <ul>
 74  
  *     <li>use the one defined in the reportPlugin configuration</li>
 75  
  *     <li>search similar (same groupId and artifactId) mojo in the build/plugins section of the pom</li>
 76  
  *     <li>search similar (same groupId and artifactId) mojo in the build/pluginManagement section of the pom</li>
 77  
  *     <li>ask {@link PluginVersionResolver} to get a version and display a warning as it's not a recommended use</li>  
 78  
  *   </ul>
 79  
  * </p>
 80  
  * <p>
 81  
  *   Following steps are done
 82  
  *   <ul>
 83  
  *     <li>get {@link PluginDescriptor} from the {@link MavenPluginManager#getPluginDescriptor(Plugin, RepositoryRequest)}</li>
 84  
  *     <li>setup a {@link ClassLoader} with the Mojo Site plugin {@link ClassLoader} as parent for the report execution. 
 85  
  *       You must note some classes are imported from the current Site Mojo {@link ClassRealm} see {@link #IMPORTS}.
 86  
  *       The artifact resolution excludes the following artifacts (with using an {@link ExclusionSetFilter}: 
 87  
  *       doxia-site-renderer, doxia-sink-api, maven-reporting-api.
 88  
  *       done using {@link MavenPluginManager#setupPluginRealm(PluginDescriptor, org.apache.maven.execution.MavenSession, ClassLoader, List, org.apache.maven.artifact.resolver.filter.ArtifactFilter)}
 89  
  *     </li>
 90  
  *     <li>
 91  
  *       setup the mojo using {@link MavenPluginManager#getConfiguredMojo(Class, org.apache.maven.execution.MavenSession, MojoExecution)}
 92  
  *     </li>
 93  
  *     <li>
 94  
  *       verify with {@link LifecycleExecutor#calculateForkedExecutions(MojoExecution, org.apache.maven.execution.MavenSession)}
 95  
  *       if any forked execution is needed: if yes executes the forked execution here
 96  
  *     </li>
 97  
  *   </ul>
 98  
  * </p>
 99  
  * @author Olivier Lamy
 100  
  * @since 3.0-beta-1
 101  
  */
 102  
 @Component( role = MavenReportExecutor.class )
 103  2
 public class DefaultMavenReportExecutor
 104  
     implements MavenReportExecutor
 105  
 {
 106  
     @Requirement
 107  
     private Logger logger;
 108  
 
 109  
     @Requirement
 110  
     protected MavenPluginManager mavenPluginManager;
 111  
 
 112  
     @Requirement
 113  
     protected LifecycleExecutor lifecycleExecutor;
 114  
 
 115  
     @Requirement
 116  
     protected PluginVersionResolver pluginVersionResolver;
 117  
 
 118  1
     private static final List<String> IMPORTS = Arrays.asList( "org.apache.maven.reporting.MavenReport",
 119  
                                                                "org.apache.maven.reporting.MavenMultiPageReport",
 120  
                                                                "org.apache.maven.doxia.siterenderer.Renderer",
 121  
                                                                "org.apache.maven.doxia.sink.SinkFactory",
 122  
                                                                "org.codehaus.doxia.sink.Sink",
 123  
                                                                "org.apache.maven.doxia.sink.Sink",
 124  
                                                                "org.apache.maven.doxia.sink.SinkEventAttributes",
 125  
                                                                "org.apache.maven.doxia.logging.LogEnabled",
 126  
                                                                "org.apache.maven.doxia.logging.Log" );
 127  
 
 128  1
     private static final ExclusionsDependencyFilter EXCLUDES =
 129  
         new ExclusionsDependencyFilter( Arrays.asList( "doxia-site-renderer", "doxia-sink-api", "maven-reporting-api" ) );
 130  
 
 131  
     public List<MavenReportExecution> buildMavenReports( MavenReportExecutorRequest mavenReportExecutorRequest )
 132  
         throws MojoExecutionException
 133  
     {
 134  1
         if ( mavenReportExecutorRequest.getReportPlugins() == null )
 135  
         {
 136  0
             return Collections.emptyList();
 137  
         }
 138  1
         getLog().debug( "DefaultMavenReportExecutor.buildMavenReports()" );
 139  
 
 140  1
         List<String> reportPluginKeys = new ArrayList<String>();
 141  1
         List<MavenReportExecution> reports = new ArrayList<MavenReportExecution>();
 142  
 
 143  1
         String pluginKey = "";
 144  
         try
 145  
         {
 146  2
             for ( ReportPlugin reportPlugin : mavenReportExecutorRequest.getReportPlugins() )
 147  
             {
 148  1
                 pluginKey = reportPlugin.getGroupId() + ":" + reportPlugin.getArtifactId();
 149  
 
 150  1
                 buildReportPlugin( mavenReportExecutorRequest, reportPlugin, reportPluginKeys, reports );
 151  
             }
 152  1
             return reports;
 153  
         }
 154  0
         catch ( Exception e )
 155  
         {
 156  0
             throw new MojoExecutionException( "failed to get report for " + pluginKey, e );
 157  
         }
 158  
     }
 159  
 
 160  
     protected void buildReportPlugin( MavenReportExecutorRequest mavenReportExecutorRequest, ReportPlugin reportPlugin,
 161  
                                       List<String> reportPluginKeys, List<MavenReportExecution> reports )
 162  
         throws Exception
 163  
     {
 164  1
         Plugin plugin = new Plugin();
 165  1
         plugin.setGroupId( reportPlugin.getGroupId() );
 166  1
         plugin.setArtifactId( reportPlugin.getArtifactId() );
 167  
 
 168  1
         String pluginKey = reportPlugin.getGroupId() + ":" + reportPlugin.getArtifactId();
 169  1
         if ( reportPluginKeys.contains( pluginKey ) )
 170  
         {
 171  0
             logger.info( "plugin " + pluginKey + " will be executed more than one time" );
 172  
         }
 173  
         else
 174  
         {
 175  1
             reportPluginKeys.add( pluginKey );
 176  
         }
 177  
 
 178  1
         RepositoryRequest repositoryRequest = new DefaultRepositoryRequest();
 179  1
         repositoryRequest.setLocalRepository( mavenReportExecutorRequest.getLocalRepository() );
 180  1
         repositoryRequest.setRemoteRepositories( mavenReportExecutorRequest.getProject().getPluginArtifactRepositories() );
 181  
 
 182  1
         plugin.setVersion( getPluginVersion( reportPlugin, repositoryRequest, mavenReportExecutorRequest ) );
 183  
 
 184  1
         mergePluginToReportPlugin( mavenReportExecutorRequest, plugin, reportPlugin );
 185  
 
 186  1
         logger.info( "configuring report plugin " + plugin.getId() );
 187  
 
 188  1
         MavenSession session = mavenReportExecutorRequest.getMavenSession();
 189  1
         List<RemoteRepository> remoteRepositories = session.getCurrentProject().getRemotePluginRepositories();
 190  
 
 191  1
         PluginDescriptor pluginDescriptor =
 192  
             mavenPluginManager.getPluginDescriptor( plugin, remoteRepositories, session.getRepositorySession() );
 193  
 
 194  1
         Map<String, PlexusConfiguration> goalsWithConfiguration = new LinkedHashMap<String, PlexusConfiguration>();
 195  
 
 196  1
         if ( reportPlugin.getReportSets().isEmpty() && reportPlugin.getReports().isEmpty() )
 197  
         {
 198  0
             List<MojoDescriptor> mojoDescriptors = pluginDescriptor.getMojos();
 199  0
             for ( MojoDescriptor mojoDescriptor : mojoDescriptors )
 200  
             {
 201  0
                 goalsWithConfiguration.put( mojoDescriptor.getGoal(), mojoDescriptor.getConfiguration() );
 202  
             }
 203  0
         }
 204  
         else
 205  
         {
 206  1
             for ( ReportSet reportSet : reportPlugin.getReportSets() )
 207  
             {
 208  1
                 for ( String report : reportSet.getReports() )
 209  
                 {
 210  2
                     goalsWithConfiguration.put( report, reportSet.getConfiguration() );
 211  
                 }
 212  
             }
 213  
 
 214  1
             for ( String report : reportPlugin.getReports() )
 215  
             {
 216  0
                 goalsWithConfiguration.put( report, reportPlugin.getConfiguration() );
 217  
             }
 218  
         }
 219  
 
 220  1
         for ( Entry<String, PlexusConfiguration> entry : goalsWithConfiguration.entrySet() )
 221  
         {
 222  2
             MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( entry.getKey() );
 223  2
             if ( mojoDescriptor == null )
 224  
             {
 225  0
                 throw new MojoNotFoundException( entry.getKey(), pluginDescriptor );
 226  
             }
 227  
 
 228  2
             MojoExecution mojoExecution = new MojoExecution( plugin, entry.getKey(), "report:" + entry.getKey() );
 229  
 
 230  2
             mojoExecution.setConfiguration( convert( mojoDescriptor ) );
 231  
 
 232  2
             if ( reportPlugin.getConfiguration() != null || entry.getValue() != null )
 233  
             {
 234  0
                 Xpp3Dom reportConfiguration =
 235  
                     reportPlugin.getConfiguration() == null ? new Xpp3Dom( "fake" )
 236  
                                     : convert( reportPlugin.getConfiguration() );
 237  
 
 238  
                 // MSITE-512 configuration from ReportSet must win
 239  0
                 Xpp3Dom mergedConfigurationWithReportSet =
 240  
                     Xpp3DomUtils.mergeXpp3Dom( convert( entry.getValue() ), reportConfiguration );
 241  
 
 242  0
                 Xpp3Dom mergedConfiguration =
 243  
                     Xpp3DomUtils.mergeXpp3Dom( mergedConfigurationWithReportSet, convert( mojoDescriptor ) );
 244  
 
 245  0
                 Xpp3Dom cleanedConfiguration = new Xpp3Dom( "configuration" );
 246  0
                 if ( mergedConfiguration.getChildren() != null )
 247  
                 {
 248  0
                     for ( Xpp3Dom parameter : mergedConfiguration.getChildren() )
 249  
                     {
 250  0
                         if ( mojoDescriptor.getParameterMap().containsKey( parameter.getName() ) )
 251  
                         {
 252  0
                             cleanedConfiguration.addChild( parameter );
 253  
                         }
 254  
                     }
 255  
                 }
 256  0
                 if ( getLog().isDebugEnabled() )
 257  
                 {
 258  0
                     getLog().debug( "mojoExecution mergedConfiguration: " + mergedConfiguration );
 259  0
                     getLog().debug( "mojoExecution cleanedConfiguration: " + cleanedConfiguration );
 260  
                 }
 261  
 
 262  0
                 mojoExecution.setConfiguration( cleanedConfiguration );
 263  
             }
 264  
 
 265  2
             mojoExecution.setMojoDescriptor( mojoDescriptor );
 266  
 
 267  2
             mavenPluginManager.setupPluginRealm( pluginDescriptor, mavenReportExecutorRequest.getMavenSession(),
 268  
                                                  Thread.currentThread().getContextClassLoader(), IMPORTS, EXCLUDES );
 269  2
             MavenReport mavenReport =
 270  
                 getConfiguredMavenReport( mojoExecution, pluginDescriptor, mavenReportExecutorRequest );
 271  
 
 272  2
             if ( mavenReport == null )
 273  
             {
 274  0
                 continue;
 275  
             }
 276  
 
 277  2
             MavenReportExecution mavenReportExecution =
 278  
                 new MavenReportExecution( mojoExecution.getPlugin(), mavenReport, pluginDescriptor.getClassRealm() );
 279  
 
 280  2
             lifecycleExecutor.calculateForkedExecutions( mojoExecution, mavenReportExecutorRequest.getMavenSession() );
 281  
 
 282  2
             if ( !mojoExecution.getForkedExecutions().isEmpty() )
 283  
             {
 284  2
                 lifecycleExecutor.executeForkedExecutions( mojoExecution, mavenReportExecutorRequest.getMavenSession() );
 285  
             }
 286  
 
 287  2
             if ( canGenerateReport( mavenReport, mojoExecution ) )
 288  
             {
 289  2
                 reports.add( mavenReportExecution );
 290  
             }
 291  2
         }
 292  1
     }
 293  
 
 294  
     private boolean canGenerateReport( MavenReport mavenReport, MojoExecution mojoExecution )
 295  
     {
 296  2
         ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
 297  
         try
 298  
         {
 299  2
             Thread.currentThread().setContextClassLoader( mojoExecution.getMojoDescriptor().getRealm() );
 300  
 
 301  2
             return mavenReport.canGenerateReport();
 302  
         }
 303  
         finally
 304  
         {
 305  2
             Thread.currentThread().setContextClassLoader( originalClassLoader );
 306  
         } 
 307  
     }
 308  
 
 309  
     private MavenReport getConfiguredMavenReport( MojoExecution mojoExecution, PluginDescriptor pluginDescriptor,
 310  
                                                   MavenReportExecutorRequest mavenReportExecutorRequest )
 311  
         throws PluginContainerException, PluginConfigurationException
 312  
     {
 313  
         try
 314  
         {
 315  2
             if ( !isMavenReport( mojoExecution, pluginDescriptor ) )
 316  
             {
 317  0
                 return null;
 318  
             }
 319  
 
 320  2
             Mojo mojo = mavenPluginManager.getConfiguredMojo( Mojo.class,
 321  
                                                               mavenReportExecutorRequest.getMavenSession(),
 322  
                                                               mojoExecution );
 323  
 
 324  2
             return (MavenReport) mojo;
 325  
         }
 326  0
         catch ( ClassCastException e )
 327  
         {
 328  0
             getLog().warn( "skip ClassCastException " + e.getMessage() );
 329  0
             return null;
 330  
         }
 331  0
         catch ( PluginContainerException e )
 332  
         {
 333  
             /**
 334  
              * ignore old plugin which are using removed PluginRegistry
 335  
              * [INFO] Caused by: java.lang.NoClassDefFoundError: org/apache/maven/plugin/registry/PluginRegistry
 336  
              */
 337  0
             if ( e.getCause() != null && e.getCause() instanceof NoClassDefFoundError
 338  
                 && e.getMessage().contains( "PluginRegistry" ) )
 339  
             {
 340  0
                 getLog().warn( "skip NoClassDefFoundError with PluginRegistry " );
 341  
                 // too noisy, only in debug mode + e.getMessage() );
 342  0
                 if ( getLog().isDebugEnabled() )
 343  
                 {
 344  0
                     getLog().debug( e.getMessage(), e );
 345  
                 }
 346  0
                 return null;
 347  
             }
 348  0
             throw e;
 349  
         }
 350  
     }
 351  
 
 352  
     private boolean isMavenReport( MojoExecution mojoExecution, PluginDescriptor pluginDescriptor )
 353  
     {
 354  2
         ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
 355  
         Class<?> mojoClass;
 356  2
         Thread.currentThread().setContextClassLoader( mojoExecution.getMojoDescriptor().getRealm() );
 357  
         try
 358  
         {
 359  2
             mojoClass =
 360  
                 pluginDescriptor.getClassRealm().loadClass( mojoExecution.getMojoDescriptor().getImplementation() );
 361  
         }
 362  0
         catch ( ClassNotFoundException e )
 363  
         {
 364  0
             getLog().warn( "skip ClassNotFoundException mojoExecution.goal '" + mojoExecution.getGoal() + "': "
 365  
                                + e.getMessage(), e );
 366  0
             return false;
 367  
         }
 368  
         finally
 369  
         {
 370  2
             Thread.currentThread().setContextClassLoader( originalClassLoader );
 371  2
         }       
 372  
 
 373  
         try
 374  
         {
 375  2
             Thread.currentThread().setContextClassLoader( mojoExecution.getMojoDescriptor().getRealm() );
 376  2
             MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( mojoExecution.getGoal() );
 377  
 
 378  2
             boolean isMavenReport = MavenReport.class.isAssignableFrom( mojoClass );
 379  
 
 380  2
             if ( getLog().isDebugEnabled() )
 381  
             {
 382  2
                 if ( mojoDescriptor != null && mojoDescriptor.getImplementationClass() != null )
 383  
                 {
 384  2
                     getLog().debug( "class " + mojoDescriptor.getImplementationClass().getName() + " isMavenReport: "
 385  
                                         + isMavenReport );
 386  
                 }
 387  
 
 388  2
                 if ( !isMavenReport )
 389  
                 {
 390  0
                     getLog().debug( "skip non MavenReport " + mojoExecution.getMojoDescriptor().getId() );
 391  
                 }
 392  
             }
 393  
 
 394  2
             return isMavenReport;
 395  
         }
 396  0
         catch ( LinkageError e )
 397  
         {
 398  0
             getLog().warn( "skip LinkageError mojoExecution.goal '" + mojoExecution.getGoal() + "': " + e.getMessage(),
 399  
                            e );
 400  0
             return false;
 401  
         }
 402  
         finally
 403  
         {
 404  2
             Thread.currentThread().setContextClassLoader( originalClassLoader );
 405  
         }
 406  
     }
 407  
 
 408  
     private Xpp3Dom convert( MojoDescriptor mojoDescriptor )
 409  
     {
 410  2
         PlexusConfiguration config = mojoDescriptor.getMojoConfiguration();
 411  2
         return ( config != null ) ? convert( config ) : new Xpp3Dom( "configuration" );
 412  
     }
 413  
 
 414  
     private Xpp3Dom convert( PlexusConfiguration config )
 415  
     {
 416  200
         if ( config == null )
 417  
         {
 418  0
             return null;
 419  
         }
 420  
 
 421  200
         Xpp3Dom dom = new Xpp3Dom( config.getName() );
 422  200
         dom.setValue( config.getValue( null ) );
 423  
 
 424  495
         for ( String attrib : config.getAttributeNames() )
 425  
         {
 426  295
             dom.setAttribute( attrib, config.getAttribute( attrib, null ) );
 427  
         }
 428  
 
 429  398
         for ( int n = config.getChildCount(), i = 0; i < n; i++ )
 430  
         {
 431  198
             dom.addChild( convert( config.getChild( i ) ) );
 432  
         }
 433  
 
 434  200
         return dom;
 435  
     }
 436  
 
 437  
     private Logger getLog()
 438  
     {
 439  8
         return logger;
 440  
     }
 441  
 
 442  
     /**
 443  
      * Resolve report plugin version. 
 444  
      * Steps to find a plugin version stop after each step if a non <code>null</code> value has been found:
 445  
      * <ol>
 446  
      *   <li>use the one defined in the reportPlugin configuration</li>
 447  
      *   <li>search similar (same groupId and artifactId) mojo in the build/plugins section of the pom</li>
 448  
      *   <li>search similar (same groupId and artifactId) mojo in the build/pluginManagement section of the pom</li>
 449  
      *   <li>ask {@link PluginVersionResolver} to get a version and display a warning as it's not a recommended use</li>  
 450  
      * </ol>
 451  
      *
 452  
      * @param reportPlugin the report plugin to resolve the version
 453  
      * @param repositoryRequest TODO: unused, to be removed?
 454  
      * @param mavenReportExecutorRequest the current report execution context
 455  
      * @return the report plugin version
 456  
      * @throws PluginVersionResolutionException
 457  
      */
 458  
     protected String getPluginVersion( ReportPlugin reportPlugin, RepositoryRequest repositoryRequest,
 459  
                                        MavenReportExecutorRequest mavenReportExecutorRequest )
 460  
         throws PluginVersionResolutionException
 461  
     {
 462  1
         String reportPluginKey = reportPlugin.getGroupId() + ':' + reportPlugin.getArtifactId();
 463  1
         if ( getLog().isDebugEnabled() )
 464  
         {
 465  1
             getLog().debug( "resolving version for " + reportPluginKey );
 466  
         }
 467  
 
 468  
         // look for version defined in the reportPlugin configuration
 469  1
         if ( reportPlugin.getVersion() != null )
 470  
         {
 471  1
             if ( getLog().isDebugEnabled() )
 472  
             {
 473  1
                 logger.debug( "resolved " + reportPluginKey + " version from the reporting.plugins section: "
 474  
                     + reportPlugin.getVersion() );
 475  
             }
 476  1
             return reportPlugin.getVersion();
 477  
         }
 478  
 
 479  0
         MavenProject project = mavenReportExecutorRequest.getProject();
 480  
 
 481  
         // search in the build section
 482  0
         if ( project.getBuild() != null )
 483  
         {
 484  0
             Plugin plugin = find( reportPlugin, project.getBuild().getPlugins() );
 485  
 
 486  0
             if ( plugin != null && plugin.getVersion() != null )
 487  
             {
 488  0
                 if ( getLog().isDebugEnabled() )
 489  
                 {
 490  0
                     logger.debug( "resolved " + reportPluginKey + " version from the build.plugins section: "
 491  
                         + plugin.getVersion() );
 492  
                 }
 493  0
                 return plugin.getVersion();
 494  
             }
 495  
         }
 496  
 
 497  
         // search in pluginManagement section
 498  0
         if ( project.getBuild() != null && project.getBuild().getPluginManagement() != null )
 499  
         {
 500  0
             Plugin plugin = find( reportPlugin, project.getBuild().getPluginManagement().getPlugins() );
 501  
 
 502  0
             if ( plugin != null && plugin.getVersion() != null )
 503  
             {
 504  0
                 if ( getLog().isDebugEnabled() )
 505  
                 {
 506  0
                     logger.debug( "resolved " + reportPluginKey
 507  
                         + " version from the build.pluginManagement.plugins section: " + plugin.getVersion() );
 508  
                 }
 509  0
                 return plugin.getVersion();
 510  
             }
 511  
         }
 512  
 
 513  
 
 514  0
         logger.warn( "Report plugin " + reportPluginKey + " has an empty version." );
 515  0
         logger.warn( "" );
 516  0
         logger.warn( "It is highly recommended to fix these problems"
 517  
             + " because they threaten the stability of your build." );
 518  0
         logger.warn( "" );
 519  0
         logger.warn( "For this reason, future Maven versions might no"
 520  
             + " longer support building such malformed projects." );
 521  
 
 522  0
         Plugin plugin = new Plugin();
 523  0
         plugin.setGroupId( reportPlugin.getGroupId() );
 524  0
         plugin.setArtifactId( reportPlugin.getArtifactId() );
 525  
         
 526  0
         PluginVersionRequest pluginVersionRequest =
 527  
             new DefaultPluginVersionRequest( plugin, mavenReportExecutorRequest.getMavenSession() );
 528  
 
 529  0
         PluginVersionResult result = pluginVersionResolver.resolve( pluginVersionRequest );
 530  0
         if ( getLog().isDebugEnabled() )
 531  
         {
 532  0
             getLog().debug( "resolved " + reportPluginKey + " version from repository: " + result.getVersion() );
 533  
         }
 534  0
         return result.getVersion();
 535  
     }
 536  
 
 537  
     /**
 538  
      * Search similar (same groupId and artifactId) mojo as a given report plugin.
 539  
      * 
 540  
      * @param reportPlugin the report plugin to search for a similar mojo
 541  
      * @param plugins the candidate mojos 
 542  
      * @return the first similar mojo
 543  
      */
 544  
     private Plugin find( ReportPlugin reportPlugin, List<Plugin> plugins )
 545  
     {
 546  1
         if ( plugins == null )
 547  
         {
 548  0
             return null;
 549  
         }
 550  1
         for ( Plugin plugin : plugins )
 551  
         {
 552  0
             if ( StringUtils.equals( plugin.getArtifactId(), reportPlugin.getArtifactId() )
 553  
                 && StringUtils.equals( plugin.getGroupId(), reportPlugin.getGroupId() ) )
 554  
             {
 555  0
                 return plugin;
 556  
             }
 557  
         }
 558  1
         return null;
 559  
     }
 560  
 
 561  
     /**
 562  
      * TODO other stuff to merge ?
 563  
      * <p>
 564  
      * this method will "merge" some part of the plugin declaration existing in the build section 
 565  
      * to the fake plugin build for report execution:
 566  
      * <ul>
 567  
      *   <li>dependencies</li>
 568  
      * </ul>
 569  
      * </p>
 570  
      * @param mavenReportExecutorRequest
 571  
      * @param buildPlugin
 572  
      * @param reportPlugin
 573  
      */
 574  
     private void mergePluginToReportPlugin( MavenReportExecutorRequest mavenReportExecutorRequest, Plugin buildPlugin,
 575  
                                             ReportPlugin reportPlugin )
 576  
     {
 577  1
         Plugin configuredPlugin = find( reportPlugin, mavenReportExecutorRequest.getProject().getBuild().getPlugins() );
 578  1
         if ( configuredPlugin != null )
 579  
         {
 580  0
             if ( !configuredPlugin.getDependencies().isEmpty() )
 581  
             {
 582  0
                 buildPlugin.getDependencies().addAll( configuredPlugin.getDependencies() );
 583  
             }
 584  
         }
 585  1
     }   
 586  
 }