Coverage Report - org.apache.maven.plugin.DefaultPluginManager
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultPluginManager
0%
0/498
0%
0/242
5.767
 
 1  
 
 2  
 package org.apache.maven.plugin;
 3  
 
 4  
 /*
 5  
  * Licensed to the Apache Software Foundation (ASF) under one
 6  
  * or more contributor license agreements.  See the NOTICE file
 7  
  * distributed with this work for additional information
 8  
  * regarding copyright ownership.  The ASF licenses this file
 9  
  * to you under the Apache License, Version 2.0 (the
 10  
  * "License"); you may not use this file except in compliance
 11  
  * with the License.  You may obtain a copy of the License at
 12  
  *
 13  
  *  http://www.apache.org/licenses/LICENSE-2.0
 14  
  *
 15  
  * Unless required by applicable law or agreed to in writing,
 16  
  * software distributed under the License is distributed on an
 17  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 18  
  * KIND, either express or implied.  See the License for the
 19  
  * specific language governing permissions and limitations
 20  
  * under the License.
 21  
  */
 22  
 
 23  
 import java.io.File;
 24  
 import java.net.URL;
 25  
 import java.util.ArrayList;
 26  
 import java.util.Collection;
 27  
 import java.util.Collections;
 28  
 import java.util.HashMap;
 29  
 import java.util.HashSet;
 30  
 import java.util.Iterator;
 31  
 import java.util.LinkedHashMap;
 32  
 import java.util.LinkedHashSet;
 33  
 import java.util.List;
 34  
 import java.util.Map;
 35  
 import java.util.Set;
 36  
 
 37  
 import org.apache.maven.MavenArtifactFilterManager;
 38  
 import org.apache.maven.artifact.Artifact;
 39  
 import org.apache.maven.artifact.factory.ArtifactFactory;
 40  
 import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
 41  
 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
 42  
 import org.apache.maven.artifact.metadata.ResolutionGroup;
 43  
 import org.apache.maven.artifact.repository.ArtifactRepository;
 44  
 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
 45  
 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
 46  
 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
 47  
 import org.apache.maven.artifact.resolver.ArtifactResolver;
 48  
 import org.apache.maven.artifact.resolver.MultipleArtifactsNotFoundException;
 49  
 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
 50  
 import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
 51  
 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
 52  
 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
 53  
 import org.apache.maven.artifact.versioning.VersionRange;
 54  
 import org.apache.maven.execution.MavenSession;
 55  
 import org.apache.maven.execution.RuntimeInformation;
 56  
 import org.apache.maven.model.Plugin;
 57  
 import org.apache.maven.model.ReportPlugin;
 58  
 import org.apache.maven.monitor.event.EventDispatcher;
 59  
 import org.apache.maven.monitor.event.MavenEvents;
 60  
 import org.apache.maven.monitor.logging.DefaultLog;
 61  
 import org.apache.maven.plugin.descriptor.MojoDescriptor;
 62  
 import org.apache.maven.plugin.descriptor.Parameter;
 63  
 import org.apache.maven.plugin.descriptor.PluginDescriptor;
 64  
 import org.apache.maven.plugin.descriptor.PluginDescriptorBuilder;
 65  
 import org.apache.maven.plugin.logging.Log;
 66  
 import org.apache.maven.plugin.version.PluginVersionManager;
 67  
 import org.apache.maven.plugin.version.PluginVersionNotFoundException;
 68  
 import org.apache.maven.plugin.version.PluginVersionResolutionException;
 69  
 import org.apache.maven.project.MavenProject;
 70  
 import org.apache.maven.project.MavenProjectBuilder;
 71  
 import org.apache.maven.project.ProjectBuildingException;
 72  
 import org.apache.maven.project.artifact.InvalidDependencyVersionException;
 73  
 import org.apache.maven.project.artifact.MavenMetadataSource;
 74  
 import org.apache.maven.project.path.PathTranslator;
 75  
 import org.apache.maven.reporting.MavenReport;
 76  
 import org.apache.maven.settings.Settings;
 77  
 import org.codehaus.classworlds.ClassRealm;
 78  
 import org.codehaus.classworlds.NoSuchRealmException;
 79  
 import org.codehaus.plexus.PlexusConstants;
 80  
 import org.codehaus.plexus.PlexusContainer;
 81  
 import org.codehaus.plexus.PlexusContainerException;
 82  
 import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
 83  
 import org.codehaus.plexus.component.configurator.ComponentConfigurator;
 84  
 import org.codehaus.plexus.component.configurator.ConfigurationListener;
 85  
 import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
 86  
 import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
 87  
 import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
 88  
 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
 89  
 import org.codehaus.plexus.configuration.PlexusConfiguration;
 90  
 import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
 91  
 import org.codehaus.plexus.context.Context;
 92  
 import org.codehaus.plexus.context.ContextException;
 93  
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 94  
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
 95  
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
 96  
 import org.codehaus.plexus.util.StringUtils;
 97  
 import org.codehaus.plexus.util.xml.Xpp3Dom;
 98  
 
 99  
 public class DefaultPluginManager
 100  
     extends AbstractLogEnabled
 101  
     implements PluginManager, Initializable, Contextualizable
 102  
 {
 103  
     protected PlexusContainer container;
 104  
 
 105  
     protected PluginDescriptorBuilder pluginDescriptorBuilder;
 106  
 
 107  
     protected ArtifactFilter artifactFilter;
 108  
 
 109  
     private Log mojoLogger;
 110  
 
 111  0
     private Map resolvedCoreArtifactFiles = new HashMap();
 112  
 
 113  
     // component requirements
 114  
     protected PathTranslator pathTranslator;
 115  
 
 116  
     protected MavenPluginCollector pluginCollector;
 117  
 
 118  
     protected PluginVersionManager pluginVersionManager;
 119  
 
 120  
     protected ArtifactFactory artifactFactory;
 121  
 
 122  
     protected ArtifactResolver artifactResolver;
 123  
 
 124  
     protected ArtifactMetadataSource artifactMetadataSource;
 125  
 
 126  
     protected RuntimeInformation runtimeInformation;
 127  
 
 128  
     protected MavenProjectBuilder mavenProjectBuilder;
 129  
 
 130  
     protected PluginMappingManager pluginMappingManager;
 131  
 
 132  
     // END component requirements
 133  
 
 134  
     public DefaultPluginManager()
 135  0
     {
 136  0
         pluginDescriptorBuilder = new PluginDescriptorBuilder();
 137  0
     }
 138  
 
 139  
     // ----------------------------------------------------------------------
 140  
     //
 141  
     // ----------------------------------------------------------------------
 142  
 
 143  
     public PluginDescriptor getPluginDescriptorForPrefix( String prefix )
 144  
     {
 145  0
         return pluginCollector.getPluginDescriptorForPrefix( prefix );
 146  
     }
 147  
 
 148  
     public Plugin getPluginDefinitionForPrefix( String prefix,
 149  
                                                 MavenSession session,
 150  
                                                 MavenProject project )
 151  
     {
 152  
         // TODO: since this is only used in the lifecycle executor, maybe it should be moved there? There is no other
 153  
         // use for the mapping manager in here
 154  0
         return pluginMappingManager.getByPrefix( prefix, session.getSettings().getPluginGroups(),
 155  
                                                  project.getPluginArtifactRepositories(),
 156  
                                                  session.getLocalRepository() );
 157  
     }
 158  
 
 159  
     public PluginDescriptor verifyPlugin( Plugin plugin,
 160  
                                           MavenProject project,
 161  
                                           Settings settings,
 162  
                                           ArtifactRepository localRepository )
 163  
         throws ArtifactResolutionException, PluginVersionResolutionException, ArtifactNotFoundException,
 164  
         InvalidVersionSpecificationException, InvalidPluginException, PluginManagerException, PluginNotFoundException,
 165  
         PluginVersionNotFoundException
 166  
     {
 167  
         // TODO: this should be possibly outside
 168  
         // All version-resolution logic has been moved to DefaultPluginVersionManager.
 169  0
         if ( plugin.getVersion() == null )
 170  
         {
 171  0
             String version = pluginVersionManager.resolvePluginVersion( plugin.getGroupId(), plugin.getArtifactId(),
 172  
                                                                         project, settings, localRepository );
 173  0
             plugin.setVersion( version );
 174  
         }
 175  
 
 176  0
         return verifyVersionedPlugin( plugin, project, localRepository );
 177  
     }
 178  
 
 179  
     private PluginDescriptor verifyVersionedPlugin( Plugin plugin,
 180  
                                                     MavenProject project,
 181  
                                                     ArtifactRepository localRepository )
 182  
         throws PluginVersionResolutionException, ArtifactNotFoundException, ArtifactResolutionException,
 183  
         InvalidVersionSpecificationException, InvalidPluginException, PluginManagerException, PluginNotFoundException
 184  
     {
 185  
         // TODO: this might result in an artifact "RELEASE" being resolved continuously
 186  
         // FIXME: need to find out how a plugin gets marked as 'installed'
 187  
         // and no ChildContainer exists. The check for that below fixes
 188  
         // the 'Can't find plexus container for plugin: xxx' error.
 189  
         try
 190  
         {
 191  0
             VersionRange versionRange = VersionRange.createFromVersionSpec( plugin.getVersion() );
 192  
 
 193  0
             List remoteRepositories = new ArrayList();
 194  0
             remoteRepositories.addAll( project.getPluginArtifactRepositories() );
 195  0
             remoteRepositories.addAll( project.getRemoteArtifactRepositories() );
 196  
 
 197  0
             checkRequiredMavenVersion( plugin, localRepository, remoteRepositories );
 198  
 
 199  0
             Artifact pluginArtifact =
 200  
                 artifactFactory.createPluginArtifact( plugin.getGroupId(), plugin.getArtifactId(), versionRange );
 201  
 
 202  0
             pluginArtifact = project.replaceWithActiveArtifact( pluginArtifact );
 203  
 
 204  0
             artifactResolver.resolve( pluginArtifact, project.getPluginArtifactRepositories(), localRepository );
 205  
 
 206  0
             PlexusContainer pluginContainer = container.getChildContainer( plugin.getKey() );
 207  
 
 208  0
             File pluginFile = pluginArtifact.getFile();
 209  
 
 210  0
             if ( !pluginCollector.isPluginInstalled( plugin ) || ( pluginContainer == null ) )
 211  
             {
 212  0
                 addPlugin( plugin, pluginArtifact, project, localRepository );
 213  
             }
 214  0
             else if ( pluginFile.lastModified() > pluginContainer.getCreationDate().getTime() )
 215  
             {
 216  0
                 getLogger().info(
 217  
                     "Reloading plugin container for: " + plugin.getKey() + ". The plugin artifact has changed." );
 218  
 
 219  0
                 pluginContainer.dispose();
 220  
 
 221  0
                 pluginCollector.flushPluginDescriptor( plugin );
 222  
 
 223  0
                 addPlugin( plugin, pluginArtifact, project, localRepository );
 224  
             }
 225  
 
 226  0
             project.addPlugin( plugin );
 227  
         }
 228  0
         catch ( ArtifactNotFoundException e )
 229  
         {
 230  0
             String groupId = plugin.getGroupId();
 231  0
             String artifactId = plugin.getArtifactId();
 232  0
             String version = plugin.getVersion();
 233  
 
 234  0
             if ( ( groupId == null ) || ( artifactId == null ) || ( version == null ) )
 235  
             {
 236  0
                 throw new PluginNotFoundException( e );
 237  
             }
 238  0
             else if ( groupId.equals( e.getGroupId() ) && artifactId.equals( e.getArtifactId() ) &&
 239  
                 version.equals( e.getVersion() ) && "maven-plugin".equals( e.getType() ) )
 240  
             {
 241  0
                 throw new PluginNotFoundException( e );
 242  
             }
 243  
             else
 244  
             {
 245  0
                 throw e;
 246  
             }
 247  0
         }
 248  
 
 249  0
         return pluginCollector.getPluginDescriptor( plugin );
 250  
     }
 251  
 
 252  
     /**
 253  
      * @todo would be better to store this in the plugin descriptor, but then it won't be available to the version
 254  
      * manager which executes before the plugin is instantiated
 255  
      */
 256  
     private void checkRequiredMavenVersion( Plugin plugin,
 257  
                                             ArtifactRepository localRepository,
 258  
                                             List remoteRepositories )
 259  
         throws PluginVersionResolutionException, InvalidPluginException
 260  
     {
 261  
         try
 262  
         {
 263  0
             Artifact artifact = artifactFactory.createProjectArtifact( plugin.getGroupId(), plugin.getArtifactId(),
 264  
                                                                        plugin.getVersion() );
 265  0
             MavenProject project =
 266  
                 mavenProjectBuilder.buildFromRepository( artifact, remoteRepositories, localRepository, false );
 267  
             // if we don't have the required Maven version, then ignore an update
 268  0
             if ( ( project.getPrerequisites() != null ) && ( project.getPrerequisites().getMaven() != null ) )
 269  
             {
 270  0
                 DefaultArtifactVersion requiredVersion =
 271  
                     new DefaultArtifactVersion( project.getPrerequisites().getMaven() );
 272  0
                 if ( runtimeInformation.getApplicationVersion().compareTo( requiredVersion ) < 0 )
 273  
                 {
 274  0
                     throw new PluginVersionResolutionException( plugin.getGroupId(), plugin.getArtifactId(),
 275  
                                                                 "Plugin requires Maven version " + requiredVersion );
 276  
                 }
 277  
             }
 278  
         }
 279  0
         catch ( ProjectBuildingException e )
 280  
         {
 281  0
             throw new InvalidPluginException(
 282  
                 "Unable to build project for plugin '" + plugin.getKey() + "': " + e.getMessage(), e );
 283  0
         }
 284  0
     }
 285  
 
 286  
     protected void addPlugin( Plugin plugin,
 287  
                               Artifact pluginArtifact,
 288  
                               MavenProject project,
 289  
                               ArtifactRepository localRepository )
 290  
         throws PluginManagerException, InvalidPluginException
 291  
     {
 292  
         PlexusContainer child;
 293  
 
 294  
         try
 295  
         {
 296  0
             child = container.createChildContainer( plugin.getKey(),
 297  
                                                     Collections.singletonList( pluginArtifact.getFile() ),
 298  
                                                     Collections.EMPTY_MAP,
 299  
                                                     Collections.singletonList( pluginCollector ) );
 300  
             try
 301  
             {
 302  0
                 child.getContainerRealm().importFrom( "plexus.core", "org.codehaus.plexus.util.xml.Xpp3Dom" );
 303  0
                 child.getContainerRealm().importFrom( "plexus.core", "org.codehaus.plexus.util.xml.pull.XmlPullParser" );
 304  0
                 child.getContainerRealm().importFrom( "plexus.core", "org.codehaus.plexus.util.xml.pull.XmlPullParserException" );
 305  0
                 child.getContainerRealm().importFrom( "plexus.core", "org.codehaus.plexus.util.xml.pull.XmlSerializer" );
 306  
 
 307  
                 // MNG-2878
 308  0
                 child.getContainerRealm().importFrom( "plexus.core", "/default-report.xml" );
 309  
             }
 310  0
             catch ( NoSuchRealmException e )
 311  
             {
 312  
                 // won't happen
 313  0
             }
 314  
         }
 315  0
         catch ( PlexusContainerException e )
 316  
         {
 317  0
             throw new PluginManagerException(
 318  
                 "Failed to create plugin container for plugin '" + plugin + "': " + e.getMessage(), e );
 319  0
         }
 320  
 
 321  
         // this plugin's descriptor should have been discovered in the child creation, so we should be able to
 322  
         // circle around and set the artifacts and class realm
 323  0
         PluginDescriptor addedPlugin = pluginCollector.getPluginDescriptor( plugin );
 324  
 
 325  0
         if ( addedPlugin == null )
 326  
         {
 327  0
             throw new IllegalStateException( "The plugin descriptor for the plugin " + plugin + " was not found."
 328  
                 + " Please verify that the plugin JAR " + pluginArtifact.getFile() + " is intact." );
 329  
         }
 330  
 
 331  0
         addedPlugin.setClassRealm( child.getContainerRealm() );
 332  
 
 333  
         // we're only setting the plugin's artifact itself as the artifact list, to allow it to be retrieved
 334  
         // later when the plugin is first invoked. Retrieving this artifact will in turn allow us to
 335  
         // transitively resolve its dependencies, and add them to the plugin container...
 336  0
         addedPlugin.setArtifacts( Collections.singletonList( pluginArtifact ) );
 337  
 
 338  
         try
 339  
         {
 340  
             // the only Plugin instance which will have dependencies is the one specified in the project.
 341  
             // We need to look for a Plugin instance there, in case the instance we're using didn't come from
 342  
             // the project.
 343  0
             Plugin projectPlugin = (Plugin) project.getBuild().getPluginsAsMap().get( plugin.getKey() );
 344  
 
 345  0
             if ( projectPlugin == null )
 346  
             {
 347  0
                 projectPlugin = plugin;
 348  
             }
 349  
 
 350  0
             Set artifacts = MavenMetadataSource.createArtifacts( artifactFactory, projectPlugin.getDependencies(), null,
 351  
                                                                  null, project );
 352  
 
 353  
 //            Set artifacts =
 354  
 //                MavenMetadataSource.createArtifacts( artifactFactory, plugin.getDependencies(), null, null, project );
 355  
 
 356  0
             addedPlugin.setIntroducedDependencyArtifacts( artifacts );
 357  
         }
 358  0
         catch ( InvalidDependencyVersionException e )
 359  
         {
 360  0
             throw new InvalidPluginException( "Plugin '" + plugin + "' is invalid: " + e.getMessage(), e );
 361  0
         }
 362  0
     }
 363  
 
 364  
     // ----------------------------------------------------------------------
 365  
     // Mojo execution
 366  
     // ----------------------------------------------------------------------
 367  
 
 368  
     public void executeMojo( MavenProject project,
 369  
                              MojoExecution mojoExecution,
 370  
                              MavenSession session )
 371  
         throws ArtifactResolutionException, MojoExecutionException, MojoFailureException, ArtifactNotFoundException,
 372  
         InvalidDependencyVersionException, PluginManagerException, PluginConfigurationException
 373  
     {
 374  0
         MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
 375  
 
 376  
         // NOTE: I'm putting these checks in here, since this is the central point of access for
 377  
         // anything that wants to execute a mojo.
 378  0
         if ( mojoDescriptor.isProjectRequired() && !session.isUsingPOMsFromFilesystem() )
 379  
         {
 380  0
             throw new MojoExecutionException( "Cannot execute mojo: " + mojoDescriptor.getGoal() +
 381  
                 ". It requires a project with an existing pom.xml, but the build is not using one." );
 382  
         }
 383  
 
 384  0
         if ( mojoDescriptor.isOnlineRequired() && session.getSettings().isOffline() )
 385  
         {
 386  
             // TODO: Should we error out, or simply warn and skip??
 387  0
             throw new MojoExecutionException( "Mojo: " + mojoDescriptor.getGoal() +
 388  
                 " requires online mode for execution. Maven is currently offline." );
 389  
         }
 390  
 
 391  0
         if ( mojoDescriptor.isDependencyResolutionRequired() != null )
 392  
         {
 393  
             Collection projects;
 394  
 
 395  0
             if ( mojoDescriptor.isAggregator() )
 396  
             {
 397  0
                 projects = session.getSortedProjects();
 398  
             }
 399  
             else
 400  
             {
 401  0
                 projects = Collections.singleton( project );
 402  
             }
 403  
 
 404  0
             for ( Iterator i = projects.iterator(); i.hasNext(); )
 405  
             {
 406  0
                 MavenProject p = (MavenProject) i.next();
 407  
 
 408  0
                 resolveTransitiveDependencies( session, artifactResolver,
 409  
                                                mojoDescriptor.isDependencyResolutionRequired(), artifactFactory, p, mojoDescriptor.isAggregator() );
 410  0
             }
 411  
 
 412  0
             downloadDependencies( project, session, artifactResolver );
 413  
         }
 414  
 
 415  0
         String goalName = mojoDescriptor.getFullGoalName();
 416  
 
 417  
         Mojo plugin;
 418  
 
 419  0
         PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
 420  0
         String goalId = mojoDescriptor.getGoal();
 421  0
         String groupId = pluginDescriptor.getGroupId();
 422  0
         String artifactId = pluginDescriptor.getArtifactId();
 423  0
         String executionId = mojoExecution.getExecutionId();
 424  0
         Xpp3Dom dom = project.getGoalConfiguration( groupId, artifactId, executionId, goalId );
 425  0
         Xpp3Dom reportDom = project.getReportConfiguration( groupId, artifactId, executionId );
 426  0
         dom = Xpp3Dom.mergeXpp3Dom( dom, reportDom );
 427  0
         if ( mojoExecution.getConfiguration() != null )
 428  
         {
 429  0
             dom = Xpp3Dom.mergeXpp3Dom( dom, mojoExecution.getConfiguration() );
 430  
         }
 431  
 
 432  0
         plugin = getConfiguredMojo( session, dom, project, false, mojoExecution );
 433  
 
 434  
         // Event monitoring.
 435  0
         String event = MavenEvents.MOJO_EXECUTION;
 436  0
         EventDispatcher dispatcher = session.getEventDispatcher();
 437  
 
 438  0
         String goalExecId = goalName;
 439  
 
 440  0
         if ( mojoExecution.getExecutionId() != null )
 441  
         {
 442  0
             goalExecId += " {execution: " + mojoExecution.getExecutionId() + "}";
 443  
         }
 444  
 
 445  0
         dispatcher.dispatchStart( event, goalExecId );
 446  
 
 447  0
         ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader();
 448  
 
 449  
         try
 450  
         {
 451  0
             Thread.currentThread().setContextClassLoader(
 452  
                 mojoDescriptor.getPluginDescriptor().getClassRealm().getClassLoader() );
 453  
 
 454  0
             plugin.execute();
 455  
 
 456  0
             dispatcher.dispatchEnd( event, goalExecId );
 457  
         }
 458  0
         catch ( MojoExecutionException e )
 459  
         {
 460  0
             session.getEventDispatcher().dispatchError( event, goalExecId, e );
 461  
 
 462  0
             throw e;
 463  
         }
 464  0
         catch ( MojoFailureException e )
 465  
         {
 466  0
             session.getEventDispatcher().dispatchError( event, goalExecId, e );
 467  
 
 468  0
             throw e;
 469  
         }
 470  0
         catch ( LinkageError e )
 471  
         {
 472  0
             if ( getLogger().isFatalErrorEnabled() )
 473  
             {
 474  0
                 getLogger().fatalError(
 475  
                                         plugin.getClass().getName() + "#execute() caused a linkage error ("
 476  
                                             + e.getClass().getName() + ") and may be out-of-date. Check the realms:" );
 477  
 
 478  0
                 ClassRealm pluginRealm = mojoDescriptor.getPluginDescriptor().getClassRealm();
 479  0
                 StringBuffer sb = new StringBuffer();
 480  0
                 sb.append( "Plugin realm = " + pluginRealm.getId() ).append( '\n' );
 481  0
                 for ( int i = 0; i < pluginRealm.getConstituents().length; i++ )
 482  
                 {
 483  0
                     sb.append( "urls[" + i + "] = " + pluginRealm.getConstituents()[i] );
 484  0
                     if ( i != ( pluginRealm.getConstituents().length - 1 ) )
 485  
                     {
 486  0
                         sb.append( '\n' );
 487  
                     }
 488  
                 }
 489  0
                 getLogger().fatalError( sb.toString() );
 490  
 
 491  0
                 ClassRealm containerRealm = container.getContainerRealm();
 492  0
                 sb = new StringBuffer();
 493  0
                 sb.append( "Container realm = " + containerRealm.getId() ).append( '\n' );
 494  0
                 for ( int i = 0; i < containerRealm.getConstituents().length; i++ )
 495  
                 {
 496  0
                     sb.append( "urls[" + i + "] = " + containerRealm.getConstituents()[i] );
 497  0
                     if ( i != ( containerRealm.getConstituents().length - 1 ) )
 498  
                     {
 499  0
                         sb.append( '\n' );
 500  
                     }
 501  
                 }
 502  0
                 getLogger().fatalError( sb.toString() );
 503  
             }
 504  
 
 505  0
             session.getEventDispatcher().dispatchError( event, goalExecId, e );
 506  
 
 507  0
             throw e;
 508  
         }
 509  
         finally
 510  
         {
 511  
 
 512  0
             Thread.currentThread().setContextClassLoader( oldClassLoader );
 513  
 
 514  
             try
 515  
             {
 516  0
                 PlexusContainer pluginContainer = getPluginContainer( mojoDescriptor.getPluginDescriptor() );
 517  
 
 518  0
                 pluginContainer.release( plugin );
 519  
             }
 520  0
             catch ( ComponentLifecycleException e )
 521  
             {
 522  0
                 if ( getLogger().isErrorEnabled() )
 523  
                 {
 524  0
                     getLogger().error( "Error releasing plugin - ignoring.", e );
 525  
                 }
 526  0
             }
 527  0
         }
 528  0
     }
 529  
 
 530  
     public MavenReport getReport( MavenProject project,
 531  
                                   MojoExecution mojoExecution,
 532  
                                   MavenSession session )
 533  
         throws ArtifactNotFoundException, PluginConfigurationException, PluginManagerException,
 534  
         ArtifactResolutionException
 535  
     {
 536  0
         MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
 537  0
         PluginDescriptor descriptor = mojoDescriptor.getPluginDescriptor();
 538  0
         Xpp3Dom dom = project.getReportConfiguration( descriptor.getGroupId(), descriptor.getArtifactId(),
 539  
                                                       mojoExecution.getExecutionId() );
 540  0
         if ( mojoExecution.getConfiguration() != null )
 541  
         {
 542  0
             dom = Xpp3Dom.mergeXpp3Dom( dom, mojoExecution.getConfiguration() );
 543  
         }
 544  
 
 545  0
         return (MavenReport) getConfiguredMojo( session, dom, project, true, mojoExecution );
 546  
     }
 547  
 
 548  
     public PluginDescriptor verifyReportPlugin( ReportPlugin reportPlugin,
 549  
                                                 MavenProject project,
 550  
                                                 MavenSession session )
 551  
         throws PluginVersionResolutionException, ArtifactResolutionException, ArtifactNotFoundException,
 552  
         InvalidVersionSpecificationException, InvalidPluginException, PluginManagerException, PluginNotFoundException,
 553  
         PluginVersionNotFoundException
 554  
     {
 555  0
         String version = reportPlugin.getVersion();
 556  
 
 557  0
         if ( version == null )
 558  
         {
 559  0
             version = pluginVersionManager.resolveReportPluginVersion( reportPlugin.getGroupId(),
 560  
                                                                        reportPlugin.getArtifactId(), project,
 561  
                                                                        session.getSettings(),
 562  
                                                                        session.getLocalRepository() );
 563  0
             reportPlugin.setVersion( version );
 564  
         }
 565  
 
 566  0
         Plugin forLookup = new Plugin();
 567  
 
 568  0
         forLookup.setGroupId( reportPlugin.getGroupId() );
 569  0
         forLookup.setArtifactId( reportPlugin.getArtifactId() );
 570  0
         forLookup.setVersion( version );
 571  
 
 572  0
         return verifyVersionedPlugin( forLookup, project, session.getLocalRepository() );
 573  
     }
 574  
 
 575  
     private PlexusContainer getPluginContainer( PluginDescriptor pluginDescriptor )
 576  
         throws PluginManagerException
 577  
     {
 578  0
         String pluginKey = pluginDescriptor.getPluginLookupKey();
 579  
 
 580  0
         PlexusContainer pluginContainer = container.getChildContainer( pluginKey );
 581  
 
 582  0
         if ( pluginContainer == null )
 583  
         {
 584  0
             throw new PluginManagerException( "Cannot find Plexus container for plugin: " + pluginKey );
 585  
         }
 586  
 
 587  0
         return pluginContainer;
 588  
     }
 589  
 
 590  
     private Mojo getConfiguredMojo( MavenSession session,
 591  
                                     Xpp3Dom dom,
 592  
                                     MavenProject project,
 593  
                                     boolean report,
 594  
                                     MojoExecution mojoExecution )
 595  
         throws PluginConfigurationException, ArtifactNotFoundException, PluginManagerException,
 596  
         ArtifactResolutionException
 597  
     {
 598  0
         MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
 599  
 
 600  0
         PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
 601  
 
 602  0
         PlexusContainer pluginContainer = getPluginContainer( pluginDescriptor );
 603  
 
 604  
         // if this is the first time this plugin has been used, the plugin's container will only
 605  
         // contain the plugin's artifact in isolation; we need to finish resolving the plugin's
 606  
         // dependencies, and add them to the container.
 607  0
         ensurePluginContainerIsComplete( pluginDescriptor, pluginContainer, project, session );
 608  
 
 609  
         Mojo plugin;
 610  
         try
 611  
         {
 612  0
             plugin = (Mojo) pluginContainer.lookup( Mojo.ROLE, mojoDescriptor.getRoleHint() );
 613  0
             if ( report && !( plugin instanceof MavenReport ) )
 614  
             {
 615  
                 // TODO: the mojoDescriptor should actually capture this information so we don't get this far
 616  0
                 return null;
 617  
             }
 618  
         }
 619  0
         catch ( ComponentLookupException e )
 620  
         {
 621  0
             throw new PluginManagerException( "Unable to find the mojo '" + mojoDescriptor.getRoleHint() +
 622  
                 "' in the plugin '" + pluginDescriptor.getPluginLookupKey() + "'", e );
 623  0
         }
 624  
 
 625  0
         if ( plugin instanceof ContextEnabled )
 626  
         {
 627  0
             Map pluginContext = session.getPluginContext( pluginDescriptor, project );
 628  
 
 629  0
             ( (ContextEnabled) plugin ).setPluginContext( pluginContext );
 630  
         }
 631  
 
 632  0
         plugin.setLog( mojoLogger );
 633  
 
 634  
         XmlPlexusConfiguration pomConfiguration;
 635  0
         if ( dom == null )
 636  
         {
 637  0
             pomConfiguration = new XmlPlexusConfiguration( "configuration" );
 638  
         }
 639  
         else
 640  
         {
 641  0
             pomConfiguration = new XmlPlexusConfiguration( dom );
 642  
         }
 643  
 
 644  
         // Validate against non-editable (@readonly) parameters, to make sure users aren't trying to
 645  
         // override in the POM.
 646  0
         validatePomConfiguration( mojoDescriptor, pomConfiguration );
 647  
 
 648  0
         PlexusConfiguration mergedConfiguration = mergeMojoConfiguration( pomConfiguration, mojoDescriptor );
 649  
 
 650  
         // TODO: plexus changes to make this more like the component descriptor so this can be used instead
 651  
         //            PlexusConfiguration mergedConfiguration = mergeConfiguration( pomConfiguration,
 652  
         //                                                                          mojoDescriptor.getConfiguration() );
 653  
 
 654  0
         ExpressionEvaluator expressionEvaluator = new PluginParameterExpressionEvaluator( session, mojoExecution,
 655  
                                                                                           pathTranslator, getLogger(),
 656  
                                                                                           project,
 657  
                                                                                           session.getExecutionProperties() );
 658  
 
 659  0
         PlexusConfiguration extractedMojoConfiguration =
 660  
             extractMojoConfiguration( mergedConfiguration, mojoDescriptor );
 661  
 
 662  0
         checkRequiredParameters( mojoDescriptor, extractedMojoConfiguration, expressionEvaluator );
 663  
 
 664  0
         populatePluginFields( plugin, mojoDescriptor, extractedMojoConfiguration, pluginContainer,
 665  
                               expressionEvaluator );
 666  0
         return plugin;
 667  
     }
 668  
 
 669  
     private void ensurePluginContainerIsComplete( PluginDescriptor pluginDescriptor,
 670  
                                                   PlexusContainer pluginContainer,
 671  
                                                   MavenProject project,
 672  
                                                   MavenSession session )
 673  
         throws ArtifactNotFoundException, PluginManagerException, ArtifactResolutionException
 674  
     {
 675  
         // if the plugin's already been used once, don't re-do this step...
 676  
         // otherwise, we have to finish resolving the plugin's classpath and start the container.
 677  0
         if ( ( pluginDescriptor.getArtifacts() != null ) && ( pluginDescriptor.getArtifacts().size() == 1 ) )
 678  
         {
 679  0
             Artifact pluginArtifact = (Artifact) pluginDescriptor.getArtifacts().get( 0 );
 680  
 
 681  0
             ArtifactRepository localRepository = session.getLocalRepository();
 682  
 
 683  
             ResolutionGroup resolutionGroup;
 684  
             try
 685  
             {
 686  0
                 resolutionGroup = artifactMetadataSource.retrieve( pluginArtifact, localRepository,
 687  
                                                                    project.getPluginArtifactRepositories() );
 688  
             }
 689  0
             catch ( ArtifactMetadataRetrievalException e )
 690  
             {
 691  0
                 throw new ArtifactResolutionException( "Unable to download metadata from repository for plugin '" +
 692  
                     pluginArtifact.getId() + "': " + e.getMessage(), pluginArtifact, e );
 693  0
             }
 694  
 
 695  0
             checkPlexusUtils( resolutionGroup, artifactFactory );
 696  
 
 697  
             // [jdcasey; 20-March-2008]:
 698  
             // This is meant to eliminate the introduction of duplicated artifacts.
 699  
             // Since much of the reasoning for reversing the order of introduction of
 700  
             // plugin dependencies rests on the notion that we need to be able to
 701  
             // introduce upgraded versions of plugin dependencies on a case-by-case
 702  
             // basis, we need to remove the original version prior to artifact
 703  
             // resolution. This is consistent with recent thinking on duplicated
 704  
             // dependency specifications within a POM, where that case should
 705  
             // throw a model validation exception.
 706  
             //
 707  
             // Here, we just want to remove any chance that the ArtifactCollector
 708  
             // could make a bad choice, and use the old version in spite of our
 709  
             // explicit preference otherwise.
 710  
 
 711  
             // First, we're going to accumulate plugin dependencies in an ordered map,
 712  
             // keyed by dependencyConflictId (the ordered map is meant to preserve relative
 713  
             // ordering of the dependencies that do make the cut).
 714  0
             Map dependencyMap = new LinkedHashMap();
 715  
 
 716  
             // Next, we need to accumulate all dependencies in a List, to make it
 717  
             // simpler to iterate through them all and add them to the map.
 718  0
             List all = new ArrayList();
 719  
 
 720  
             // plugin-level dependencies from the consuming POM override dependencies
 721  
             // from the plugin's own POM.
 722  0
             all.addAll( pluginDescriptor.getIntroducedDependencyArtifacts() );
 723  
 
 724  
             // add in the deps from the plugin POM now.
 725  0
             all.addAll( resolutionGroup.getArtifacts() );
 726  
 
 727  0
             for ( Iterator it = all.iterator(); it.hasNext(); )
 728  
             {
 729  0
                 Artifact artifact = (Artifact) it.next();
 730  0
                 String conflictId = artifact.getDependencyConflictId();
 731  
 
 732  
                 // if the map already contains this dependencyConflictId, it constitutes an
 733  
                 // overridden dependency. Don't use the old one (we know it's old from the
 734  
                 // order in which dependencies were added to this list).
 735  0
                 if ( !dependencyMap.containsKey( conflictId ) )
 736  
                 {
 737  0
                     dependencyMap.put( conflictId, artifact );
 738  
                 }
 739  0
             }
 740  
 
 741  
             // Create an ordered set of dependencies from the ordered map we used above, to feed into the resolver.
 742  0
             Set dependencies = new LinkedHashSet( dependencyMap.values() );
 743  
 
 744  0
             if ( getLogger().isDebugEnabled() )
 745  
             {
 746  
                 // list all dependencies to be used by this plugin (first-level deps, not transitive ones).
 747  0
                 getLogger().debug( "Plugin dependencies for:\n\n" + pluginDescriptor.getId()
 748  
                                    + "\n\nare:\n\n"
 749  
                                    + StringUtils.join( dependencies.iterator(), "\n" ) + "\n\n" );
 750  
             }
 751  
 
 752  0
             List repositories = new ArrayList();
 753  0
             repositories.addAll( resolutionGroup.getResolutionRepositories() );
 754  0
             repositories.addAll( project.getRemoteArtifactRepositories() );
 755  
 
 756  
             /* get plugin managed versions */
 757  0
             Map pluginManagedDependencies = new HashMap();
 758  
             try
 759  
             {
 760  0
                 MavenProject pluginProject =
 761  
                     mavenProjectBuilder.buildFromRepository( pluginArtifact, project.getRemoteArtifactRepositories(),
 762  
                                                              localRepository );
 763  0
                 if ( pluginProject != null )
 764  
                 {
 765  0
                     pluginManagedDependencies = pluginProject.getManagedVersionMap();
 766  
                 }
 767  
             }
 768  0
             catch ( ProjectBuildingException e )
 769  
             {
 770  
                 // this can't happen, it would have blowed up at artifactMetadataSource.retrieve()
 771  0
             }
 772  
 
 773  0
             ArtifactResolutionResult result = artifactResolver.resolveTransitively( dependencies, pluginArtifact,
 774  
                                                                                     pluginManagedDependencies,
 775  
                                                                                     localRepository, repositories,
 776  
                                                                                     artifactMetadataSource,
 777  
                                                                                     artifactFilter );
 778  
 
 779  0
             Set resolved = result.getArtifacts();
 780  
 
 781  0
             for ( Iterator it = resolved.iterator(); it.hasNext(); )
 782  
             {
 783  0
                 Artifact artifact = (Artifact) it.next();
 784  
 
 785  0
                 if ( !artifact.equals( pluginArtifact ) )
 786  
                 {
 787  0
                     artifact = project.replaceWithActiveArtifact( artifact );
 788  
 
 789  
                     try
 790  
                     {
 791  0
                         pluginContainer.addJarResource( artifact.getFile() );
 792  
                     }
 793  0
                     catch ( PlexusContainerException e )
 794  
                     {
 795  0
                         throw new PluginManagerException( "Error adding plugin dependency '" +
 796  
                             artifact.getDependencyConflictId() + "' into plugin manager: " + e.getMessage(), e );
 797  0
                     }
 798  
                 }
 799  0
             }
 800  
 
 801  0
             pluginDescriptor.setClassRealm( pluginContainer.getContainerRealm() );
 802  
 
 803  0
             List unresolved = new ArrayList( dependencies );
 804  
 
 805  0
             unresolved.removeAll( resolved );
 806  
 
 807  0
             if ( getLogger().isDebugEnabled() )
 808  
             {
 809  
                 // list all artifacts that were filtered out during the resolution process.
 810  
                 // these are already present in the core container.
 811  0
                 getLogger().debug( " The following artifacts were filtered out for plugin: "
 812  
                                    + pluginDescriptor.getId()
 813  
                                    + " because they're already in the core of Maven:\n\n"
 814  
                                    + StringUtils.join( unresolved.iterator(), "\n" )
 815  
                                    + "\n\nThese will use the artifact files already in the core ClassRealm instead, to allow them to be included in PluginDescriptor.getArtifacts().\n\n" );
 816  
             }
 817  
 
 818  
             // Grab a file for all filtered artifacts, even if it means resolving them. This
 819  
             // is necessary in order to present a full complement of a plugin's transitive
 820  
             // dependencies to anyone who calls PluginDescriptor.getArtifacts().
 821  0
             resolveCoreArtifacts( unresolved, localRepository, resolutionGroup.getResolutionRepositories() );
 822  
 
 823  
             // Re-join resolved and filtered-but-now-resolved artifacts.
 824  
             // NOTE: The process of filtering then re-adding some artifacts will
 825  
             // result in different ordering within the PluginDescriptor.getArtifacts()
 826  
             // List than should have happened if none had been filtered. All filtered
 827  
             // artifacts will be listed last...
 828  0
             List allResolved = new ArrayList( resolved.size() + unresolved.size() );
 829  
 
 830  0
             allResolved.addAll( resolved );
 831  0
             allResolved.addAll( unresolved );
 832  
 
 833  0
             pluginDescriptor.setArtifacts( allResolved );
 834  
         }
 835  0
     }
 836  
 
 837  
     public static void checkPlexusUtils( ResolutionGroup resolutionGroup, ArtifactFactory artifactFactory )
 838  
     {
 839  
         // ----------------------------------------------------------------------------
 840  
         // If the plugin already declares a dependency on plexus-utils then we're all
 841  
         // set as the plugin author is aware of its use. If we don't have a dependency
 842  
         // on plexus-utils then we must protect users from stupid plugin authors who
 843  
         // did not declare a direct dependency on plexus-utils because the version
 844  
         // Maven uses is hidden from downstream use. We will also bump up any
 845  
         // anything below 1.1 to 1.1 as this mimics the behaviour in 2.0.5 where
 846  
         // plexus-utils 1.1 was being forced into use.
 847  
         // ----------------------------------------------------------------------------
 848  
 
 849  0
         VersionRange vr = null;
 850  
 
 851  
         try
 852  
         {
 853  0
             vr = VersionRange.createFromVersionSpec( "[1.1,)" );
 854  
         }
 855  0
         catch ( InvalidVersionSpecificationException e )
 856  
         {
 857  
             // Won't happen
 858  0
         }
 859  
 
 860  0
         boolean plexusUtilsPresent = false;
 861  
 
 862  0
         for ( Iterator i = resolutionGroup.getArtifacts().iterator(); i.hasNext(); )
 863  
         {
 864  0
             Artifact a = (Artifact) i.next();
 865  
 
 866  0
             if ( a.getArtifactId().equals( "plexus-utils" ) &&
 867  
                 vr.containsVersion( new DefaultArtifactVersion( a.getVersion() ) ) )
 868  
             {
 869  0
                 plexusUtilsPresent = true;
 870  
 
 871  0
                 break;
 872  
             }
 873  0
         }
 874  
 
 875  0
         if ( !plexusUtilsPresent )
 876  
         {
 877  
             // We will add plexus-utils as every plugin was getting this anyway from Maven itself. We will set the
 878  
             // version to the latest version we know that works as of the 2.0.6 release. We set the scope to runtime
 879  
             // as this is what's implicitly happening in 2.0.6.
 880  
 
 881  0
             resolutionGroup.getArtifacts().add( artifactFactory.createArtifact( "org.codehaus.plexus",
 882  
                                                                                 "plexus-utils", "1.1",
 883  
                                                                                 Artifact.SCOPE_RUNTIME, "jar" ) );
 884  
         }
 885  0
     }
 886  
 
 887  
     private void resolveCoreArtifacts( List unresolved,
 888  
                                        ArtifactRepository localRepository,
 889  
                                        List resolutionRepositories )
 890  
         throws ArtifactResolutionException, ArtifactNotFoundException
 891  
     {
 892  0
         for ( Iterator it = unresolved.iterator(); it.hasNext(); )
 893  
         {
 894  0
             Artifact artifact = (Artifact) it.next();
 895  
 
 896  0
             File artifactFile = (File) resolvedCoreArtifactFiles.get( artifact.getId() );
 897  
 
 898  0
             if ( artifactFile == null )
 899  
             {
 900  0
                 String resource =
 901  
                     "/META-INF/maven/" + artifact.getGroupId() + "/" + artifact.getArtifactId() + "/pom.xml";
 902  
 
 903  0
                 URL resourceUrl = container.getContainerRealm().getResource( resource );
 904  
 
 905  0
                 if ( resourceUrl == null )
 906  
                 {
 907  0
                     artifactResolver.resolve( artifact, resolutionRepositories, localRepository );
 908  
 
 909  0
                     artifactFile = artifact.getFile();
 910  
                 }
 911  
                 else
 912  
                 {
 913  0
                     String artifactPath = resourceUrl.getPath();
 914  
 
 915  0
                     if ( artifactPath.startsWith( "file:" ) )
 916  
                     {
 917  0
                         artifactPath = artifactPath.substring( "file:".length() );
 918  
                     }
 919  
 
 920  0
                     artifactPath = artifactPath.substring( 0, artifactPath.length() - resource.length() );
 921  
 
 922  0
                     if ( artifactPath.endsWith( "/" ) )
 923  
                     {
 924  0
                         artifactPath = artifactPath.substring( 0, artifactPath.length() - 1 );
 925  
                     }
 926  
 
 927  0
                     if ( artifactPath.endsWith( "!" ) )
 928  
                     {
 929  0
                         artifactPath = artifactPath.substring( 0, artifactPath.length() - 1 );
 930  
                     }
 931  
 
 932  0
                     artifactFile = new File( artifactPath ).getAbsoluteFile();
 933  
                 }
 934  
 
 935  0
                 resolvedCoreArtifactFiles.put( artifact.getId(), artifactFile );
 936  
             }
 937  
 
 938  0
             artifact.setFile( artifactFile );
 939  0
         }
 940  0
     }
 941  
 
 942  
     private PlexusConfiguration extractMojoConfiguration( PlexusConfiguration mergedConfiguration,
 943  
                                                           MojoDescriptor mojoDescriptor )
 944  
     {
 945  0
         Map parameterMap = mojoDescriptor.getParameterMap();
 946  
 
 947  0
         PlexusConfiguration[] mergedChildren = mergedConfiguration.getChildren();
 948  
 
 949  0
         XmlPlexusConfiguration extractedConfiguration = new XmlPlexusConfiguration( "configuration" );
 950  
 
 951  0
         for ( int i = 0; i < mergedChildren.length; i++ )
 952  
         {
 953  0
             PlexusConfiguration child = mergedChildren[i];
 954  
 
 955  0
             if ( parameterMap.containsKey( child.getName() ) )
 956  
             {
 957  0
                 extractedConfiguration.addChild( copyConfiguration( child ) );
 958  
             }
 959  
             else
 960  
             {
 961  
                 // TODO: I defy anyone to find these messages in the '-X' output! Do we need a new log level?
 962  
                 // ideally, this would be elevated above the true debug output, but below the default INFO level...
 963  
                 // [BP] (2004-07-18): need to understand the context more but would prefer this could be either WARN or
 964  
                 // removed - shouldn't need DEBUG to diagnose a problem most of the time.
 965  0
                 getLogger().debug( "*** WARNING: Configuration \'" + child.getName() + "\' is not used in goal \'" +
 966  
                     mojoDescriptor.getFullGoalName() + "; this may indicate a typo... ***" );
 967  
             }
 968  
         }
 969  
 
 970  0
         return extractedConfiguration;
 971  
     }
 972  
 
 973  
     private void checkRequiredParameters( MojoDescriptor goal,
 974  
                                           PlexusConfiguration configuration,
 975  
                                           ExpressionEvaluator expressionEvaluator )
 976  
         throws PluginConfigurationException
 977  
     {
 978  
         // TODO: this should be built in to the configurator, as we presently double process the expressions
 979  
 
 980  0
         List parameters = goal.getParameters();
 981  
 
 982  0
         if ( parameters == null )
 983  
         {
 984  0
             return;
 985  
         }
 986  
 
 987  0
         List invalidParameters = new ArrayList();
 988  
 
 989  0
         for ( int i = 0; i < parameters.size(); i++ )
 990  
         {
 991  0
             Parameter parameter = (Parameter) parameters.get( i );
 992  
 
 993  0
             if ( parameter.isRequired() )
 994  
             {
 995  
                 // the key for the configuration map we're building.
 996  0
                 String key = parameter.getName();
 997  
 
 998  0
                 Object fieldValue = null;
 999  0
                 String expression = null;
 1000  0
                 PlexusConfiguration value = configuration.getChild( key, false );
 1001  
                 try
 1002  
                 {
 1003  0
                     if ( value != null )
 1004  
                     {
 1005  0
                         expression = value.getValue( null );
 1006  
 
 1007  0
                         fieldValue = expressionEvaluator.evaluate( expression );
 1008  
 
 1009  0
                         if ( fieldValue == null )
 1010  
                         {
 1011  0
                             fieldValue = value.getAttribute( "default-value", null );
 1012  
                         }
 1013  
                     }
 1014  
 
 1015  0
                     if ( ( fieldValue == null ) && StringUtils.isNotEmpty( parameter.getAlias() ) )
 1016  
                     {
 1017  0
                         value = configuration.getChild( parameter.getAlias(), false );
 1018  0
                         if ( value != null )
 1019  
                         {
 1020  0
                             expression = value.getValue( null );
 1021  0
                             fieldValue = expressionEvaluator.evaluate( expression );
 1022  0
                             if ( fieldValue == null )
 1023  
                             {
 1024  0
                                 fieldValue = value.getAttribute( "default-value", null );
 1025  
                             }
 1026  
                         }
 1027  
                     }
 1028  
                 }
 1029  0
                 catch ( ExpressionEvaluationException e )
 1030  
                 {
 1031  0
                     throw new PluginConfigurationException( goal.getPluginDescriptor(), e.getMessage(), e );
 1032  0
                 }
 1033  
 
 1034  
                 // only mark as invalid if there are no child nodes
 1035  0
                 if ( ( fieldValue == null ) && ( ( value == null ) || ( value.getChildCount() == 0 ) ) )
 1036  
                 {
 1037  0
                     parameter.setExpression( expression );
 1038  0
                     invalidParameters.add( parameter );
 1039  
                 }
 1040  
             }
 1041  
         }
 1042  
 
 1043  0
         if ( !invalidParameters.isEmpty() )
 1044  
         {
 1045  0
             throw new PluginParameterException( goal, invalidParameters );
 1046  
         }
 1047  0
     }
 1048  
 
 1049  
     private void validatePomConfiguration( MojoDescriptor goal,
 1050  
                                            PlexusConfiguration pomConfiguration )
 1051  
         throws PluginConfigurationException
 1052  
     {
 1053  0
         List parameters = goal.getParameters();
 1054  
 
 1055  0
         if ( parameters == null )
 1056  
         {
 1057  0
             return;
 1058  
         }
 1059  
 
 1060  0
         for ( int i = 0; i < parameters.size(); i++ )
 1061  
         {
 1062  0
             Parameter parameter = (Parameter) parameters.get( i );
 1063  
 
 1064  
             // the key for the configuration map we're building.
 1065  0
             String key = parameter.getName();
 1066  
 
 1067  0
             PlexusConfiguration value = pomConfiguration.getChild( key, false );
 1068  
 
 1069  0
             if ( ( value == null ) && StringUtils.isNotEmpty( parameter.getAlias() ) )
 1070  
             {
 1071  0
                 key = parameter.getAlias();
 1072  0
                 value = pomConfiguration.getChild( key, false );
 1073  
             }
 1074  
 
 1075  0
             if ( value != null )
 1076  
             {
 1077  
                 // Make sure the parameter is either editable/configurable, or else is NOT specified in the POM
 1078  0
                 if ( !parameter.isEditable() )
 1079  
                 {
 1080  0
                     StringBuffer errorMessage = new StringBuffer()
 1081  
                         .append( "ERROR: Cannot override read-only parameter: " );
 1082  0
                     errorMessage.append( key );
 1083  0
                     errorMessage.append( " in goal: " ).append( goal.getFullGoalName() );
 1084  
 
 1085  0
                     throw new PluginConfigurationException( goal.getPluginDescriptor(), errorMessage.toString() );
 1086  
                 }
 1087  
 
 1088  0
                 String deprecated = parameter.getDeprecated();
 1089  0
                 if ( StringUtils.isNotEmpty( deprecated ) )
 1090  
                 {
 1091  0
                     getLogger().warn( "DEPRECATED [" + parameter.getName() + "]: " + deprecated );
 1092  
                 }
 1093  
             }
 1094  
         }
 1095  0
     }
 1096  
 
 1097  
     private PlexusConfiguration mergeMojoConfiguration( XmlPlexusConfiguration fromPom,
 1098  
                                                         MojoDescriptor mojoDescriptor )
 1099  
     {
 1100  0
         XmlPlexusConfiguration result = new XmlPlexusConfiguration( fromPom.getName() );
 1101  0
         result.setValue( fromPom.getValue( null ) );
 1102  
 
 1103  0
         if ( mojoDescriptor.getParameters() != null )
 1104  
         {
 1105  0
             PlexusConfiguration fromMojo = mojoDescriptor.getMojoConfiguration();
 1106  
 
 1107  0
             for ( Iterator it = mojoDescriptor.getParameters().iterator(); it.hasNext(); )
 1108  
             {
 1109  0
                 Parameter parameter = (Parameter) it.next();
 1110  
 
 1111  0
                 String paramName = parameter.getName();
 1112  0
                 String alias = parameter.getAlias();
 1113  0
                 String implementation = parameter.getImplementation();
 1114  
 
 1115  0
                 PlexusConfiguration pomConfig = fromPom.getChild( paramName );
 1116  0
                 PlexusConfiguration aliased = null;
 1117  
 
 1118  0
                 if ( alias != null )
 1119  
                 {
 1120  0
                     aliased = fromPom.getChild( alias );
 1121  
                 }
 1122  
 
 1123  0
                 PlexusConfiguration mojoConfig = fromMojo.getChild( paramName, false );
 1124  
 
 1125  
                 // first we'll merge configurations from the aliased and real params.
 1126  
                 // TODO: Is this the right thing to do?
 1127  0
                 if ( aliased != null )
 1128  
                 {
 1129  0
                     if ( pomConfig == null )
 1130  
                     {
 1131  0
                         pomConfig = new XmlPlexusConfiguration( paramName );
 1132  
                     }
 1133  
 
 1134  0
                     pomConfig = buildTopDownMergedConfiguration( pomConfig, aliased );
 1135  
                 }
 1136  
 
 1137  0
                 PlexusConfiguration toAdd = null;
 1138  
 
 1139  0
                 if ( pomConfig != null )
 1140  
                 {
 1141  0
                     pomConfig = buildTopDownMergedConfiguration( pomConfig, mojoConfig );
 1142  
 
 1143  0
                     if ( StringUtils.isNotEmpty( pomConfig.getValue( null ) ) || ( pomConfig.getChildCount() > 0 ) )
 1144  
                     {
 1145  0
                         toAdd = pomConfig;
 1146  
                     }
 1147  
                 }
 1148  
 
 1149  0
                 if ( ( toAdd == null ) && ( mojoConfig != null ) )
 1150  
                 {
 1151  0
                     toAdd = copyConfiguration( mojoConfig );
 1152  
                 }
 1153  
 
 1154  0
                 if ( toAdd != null )
 1155  
                 {
 1156  0
                     if ( ( implementation != null ) && ( toAdd.getAttribute( "implementation", null ) == null ) )
 1157  
                     {
 1158  
 
 1159  0
                         XmlPlexusConfiguration implementationConf = new XmlPlexusConfiguration( paramName );
 1160  
 
 1161  0
                         implementationConf.setAttribute( "implementation", parameter.getImplementation() );
 1162  
 
 1163  0
                         toAdd = buildTopDownMergedConfiguration( toAdd, implementationConf );
 1164  
                     }
 1165  
 
 1166  0
                     result.addChild( toAdd );
 1167  
                 }
 1168  0
             }
 1169  
         }
 1170  0
         return result;
 1171  
     }
 1172  
 
 1173  
     private XmlPlexusConfiguration buildTopDownMergedConfiguration( PlexusConfiguration dominant,
 1174  
                                                                     PlexusConfiguration recessive )
 1175  
     {
 1176  0
         XmlPlexusConfiguration result = new XmlPlexusConfiguration( dominant.getName() );
 1177  
 
 1178  0
         String value = dominant.getValue( null );
 1179  
 
 1180  0
         if ( StringUtils.isEmpty( value ) && ( recessive != null ) )
 1181  
         {
 1182  0
             value = recessive.getValue( null );
 1183  
         }
 1184  
 
 1185  0
         if ( StringUtils.isNotEmpty( value ) )
 1186  
         {
 1187  0
             result.setValue( value );
 1188  
         }
 1189  
 
 1190  0
         String[] attributeNames = dominant.getAttributeNames();
 1191  
 
 1192  0
         for ( int i = 0; i < attributeNames.length; i++ )
 1193  
         {
 1194  0
             String attributeValue = dominant.getAttribute( attributeNames[i], null );
 1195  
 
 1196  0
             result.setAttribute( attributeNames[i], attributeValue );
 1197  
         }
 1198  
 
 1199  0
         if ( recessive != null )
 1200  
         {
 1201  0
             attributeNames = recessive.getAttributeNames();
 1202  
 
 1203  0
             for ( int i = 0; i < attributeNames.length; i++ )
 1204  
             {
 1205  0
                 String attributeValue = recessive.getAttribute( attributeNames[i], null );
 1206  
                 // TODO: recessive seems to be dominant here?
 1207  0
                 result.setAttribute( attributeNames[i], attributeValue );
 1208  
             }
 1209  
         }
 1210  
 
 1211  0
         PlexusConfiguration[] children = dominant.getChildren();
 1212  
 
 1213  0
         for ( int i = 0; i < children.length; i++ )
 1214  
         {
 1215  0
             PlexusConfiguration childDom = children[i];
 1216  0
             PlexusConfiguration childRec = recessive == null ? null : recessive.getChild( childDom.getName(), false );
 1217  
 
 1218  0
             if ( childRec != null )
 1219  
             {
 1220  0
                 result.addChild( buildTopDownMergedConfiguration( childDom, childRec ) );
 1221  
             }
 1222  
             else
 1223  
             {   // FIXME: copy, or use reference?
 1224  0
                 result.addChild( copyConfiguration( childDom ) );
 1225  
             }
 1226  
         }
 1227  
 
 1228  0
         return result;
 1229  
     }
 1230  
 
 1231  
     public static PlexusConfiguration copyConfiguration( PlexusConfiguration src )
 1232  
     {
 1233  
         // TODO: shouldn't be necessary
 1234  0
         XmlPlexusConfiguration dom = new XmlPlexusConfiguration( src.getName() );
 1235  0
         dom.setValue( src.getValue( null ) );
 1236  
 
 1237  0
         String[] attributeNames = src.getAttributeNames();
 1238  0
         for ( int i = 0; i < attributeNames.length; i++ )
 1239  
         {
 1240  0
             String attributeName = attributeNames[i];
 1241  0
             dom.setAttribute( attributeName, src.getAttribute( attributeName, null ) );
 1242  
         }
 1243  
 
 1244  0
         PlexusConfiguration[] children = src.getChildren();
 1245  0
         for ( int i = 0; i < children.length; i++ )
 1246  
         {
 1247  0
             dom.addChild( copyConfiguration( children[i] ) );
 1248  
         }
 1249  
 
 1250  0
         return dom;
 1251  
     }
 1252  
 
 1253  
     // ----------------------------------------------------------------------
 1254  
     // Mojo Parameter Handling
 1255  
     // ----------------------------------------------------------------------
 1256  
 
 1257  
     private void populatePluginFields( Mojo plugin,
 1258  
                                        MojoDescriptor mojoDescriptor,
 1259  
                                        PlexusConfiguration configuration,
 1260  
                                        PlexusContainer pluginContainer,
 1261  
                                        ExpressionEvaluator expressionEvaluator )
 1262  
         throws PluginConfigurationException
 1263  
     {
 1264  0
         ComponentConfigurator configurator = null;
 1265  
 
 1266  
         try
 1267  
         {
 1268  0
             String configuratorId = mojoDescriptor.getComponentConfigurator();
 1269  
 
 1270  
             // TODO: could the configuration be passed to lookup and the configurator known to plexus via the descriptor
 1271  
             // so that this meethod could entirely be handled by a plexus lookup?
 1272  0
             if ( StringUtils.isNotEmpty( configuratorId ) )
 1273  
             {
 1274  0
                 configurator =
 1275  
                     (ComponentConfigurator) pluginContainer.lookup( ComponentConfigurator.ROLE, configuratorId );
 1276  
             }
 1277  
             else
 1278  
             {
 1279  0
                 configurator = (ComponentConfigurator) pluginContainer.lookup( ComponentConfigurator.ROLE );
 1280  
             }
 1281  
 
 1282  0
             ConfigurationListener listener = new DebugConfigurationListener( getLogger() );
 1283  
 
 1284  0
             getLogger().debug( "Configuring mojo '" + mojoDescriptor.getId() + "' -->" );
 1285  0
             configurator.configureComponent( plugin, configuration, expressionEvaluator,
 1286  
                                              pluginContainer.getContainerRealm(), listener );
 1287  0
             getLogger().debug( "-- end configuration --" );
 1288  
         }
 1289  0
         catch ( ComponentConfigurationException e )
 1290  
         {
 1291  0
             throw new PluginConfigurationException( mojoDescriptor.getPluginDescriptor(),
 1292  
                                                     "Unable to parse the created DOM for plugin configuration", e );
 1293  
         }
 1294  0
         catch ( ComponentLookupException e )
 1295  
         {
 1296  0
             throw new PluginConfigurationException( mojoDescriptor.getPluginDescriptor(),
 1297  
                                                     "Unable to retrieve component configurator for plugin configuration",
 1298  
                                                     e );
 1299  
         }
 1300  0
         catch ( LinkageError e )
 1301  
         {
 1302  0
             if ( getLogger().isFatalErrorEnabled() )
 1303  
             {
 1304  0
                 getLogger().fatalError(
 1305  
                                         configurator.getClass().getName() + "#configureComponent(...) caused a linkage error ("
 1306  
                                             + e.getClass().getName() + ") and may be out-of-date. Check the realms:" );
 1307  
 
 1308  0
                 ClassRealm pluginRealm = mojoDescriptor.getPluginDescriptor().getClassRealm();
 1309  0
                 StringBuffer sb = new StringBuffer();
 1310  0
                 sb.append( "Plugin realm = " + pluginRealm.getId() ).append( '\n' );
 1311  0
                 for ( int i = 0; i < pluginRealm.getConstituents().length; i++ )
 1312  
                 {
 1313  0
                     sb.append( "urls[" + i + "] = " + pluginRealm.getConstituents()[i] );
 1314  0
                     if ( i != ( pluginRealm.getConstituents().length - 1 ) )
 1315  
                     {
 1316  0
                         sb.append( '\n' );
 1317  
                     }
 1318  
                 }
 1319  0
                 getLogger().fatalError( sb.toString() );
 1320  
 
 1321  0
                 ClassRealm containerRealm = container.getContainerRealm();
 1322  0
                 sb = new StringBuffer();
 1323  0
                 sb.append( "Container realm = " + containerRealm.getId() ).append( '\n' );
 1324  0
                 for ( int i = 0; i < containerRealm.getConstituents().length; i++ )
 1325  
                 {
 1326  0
                     sb.append( "urls[" + i + "] = " + containerRealm.getConstituents()[i] );
 1327  0
                     if ( i != ( containerRealm.getConstituents().length - 1 ) )
 1328  
                     {
 1329  0
                         sb.append( '\n' );
 1330  
                     }
 1331  
                 }
 1332  0
                 getLogger().fatalError( sb.toString() );
 1333  
             }
 1334  
 
 1335  0
             throw new PluginConfigurationException( mojoDescriptor.getPluginDescriptor(),
 1336  
                                                     e.getClass().getName() + ": " + e.getMessage(), e );
 1337  
         }
 1338  
         finally
 1339  
         {
 1340  0
             if ( configurator != null )
 1341  
             {
 1342  
                 try
 1343  
                 {
 1344  0
                     pluginContainer.release( configurator );
 1345  
                 }
 1346  0
                 catch ( ComponentLifecycleException e )
 1347  
                 {
 1348  0
                     getLogger().debug( "Failed to release plugin container - ignoring." );
 1349  0
                 }
 1350  
             }
 1351  
         }
 1352  0
     }
 1353  
 
 1354  
     public static String createPluginParameterRequiredMessage( MojoDescriptor mojo,
 1355  
                                                                Parameter parameter,
 1356  
                                                                String expression )
 1357  
     {
 1358  0
         StringBuffer message = new StringBuffer();
 1359  
 
 1360  0
         message.append( "The '" );
 1361  0
         message.append( parameter.getName() );
 1362  0
         message.append( "' parameter is required for the execution of the " );
 1363  0
         message.append( mojo.getFullGoalName() );
 1364  0
         message.append( " mojo and cannot be null." );
 1365  0
         if ( expression != null )
 1366  
         {
 1367  0
             message.append( " The retrieval expression was: " ).append( expression );
 1368  
         }
 1369  
 
 1370  0
         return message.toString();
 1371  
     }
 1372  
 
 1373  
     // ----------------------------------------------------------------------
 1374  
     // Lifecycle
 1375  
     // ----------------------------------------------------------------------
 1376  
 
 1377  
     public void contextualize( Context context )
 1378  
         throws ContextException
 1379  
     {
 1380  0
         container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
 1381  
 
 1382  0
         mojoLogger = new DefaultLog( container.getLoggerManager().getLoggerForComponent( Mojo.ROLE ) );
 1383  0
     }
 1384  
 
 1385  
     public void initialize()
 1386  
     {
 1387  0
         artifactFilter = MavenArtifactFilterManager.createStandardFilter();
 1388  0
     }
 1389  
 
 1390  
     // ----------------------------------------------------------------------
 1391  
     // Artifact resolution
 1392  
     // ----------------------------------------------------------------------
 1393  
 
 1394  
     private void resolveTransitiveDependencies( MavenSession context,
 1395  
                                                 ArtifactResolver artifactResolver,
 1396  
                                                 String scope,
 1397  
                                                 ArtifactFactory artifactFactory,
 1398  
                                                 MavenProject project, boolean isAggregator )
 1399  
         throws ArtifactResolutionException, ArtifactNotFoundException, InvalidDependencyVersionException
 1400  
     {
 1401  0
         ArtifactFilter filter = new ScopeArtifactFilter( scope );
 1402  
 
 1403  
         // TODO: such a call in MavenMetadataSource too - packaging not really the intention of type
 1404  0
         Artifact artifact = artifactFactory.createBuildArtifact( project.getGroupId(), project.getArtifactId(),
 1405  
                                                                  project.getVersion(), project.getPackaging() );
 1406  
 
 1407  
         // TODO: we don't need to resolve over and over again, as long as we are sure that the parameters are the same
 1408  
         // check this with yourkit as a hot spot.
 1409  
         // Don't recreate if already created - for effeciency, and because clover plugin adds to it
 1410  0
         if ( project.getDependencyArtifacts() == null )
 1411  
         {
 1412  0
             project.setDependencyArtifacts( project.createArtifacts( artifactFactory, null, null ) );
 1413  
         }
 1414  
         
 1415  
         Set resolvedArtifacts;
 1416  
         try
 1417  
         {
 1418  0
             ArtifactResolutionResult result = artifactResolver.resolveTransitively( project.getDependencyArtifacts(),
 1419  
                                                                                 artifact,
 1420  
                                                                                 project.getManagedVersionMap(),
 1421  
                                                                                 context.getLocalRepository(),
 1422  
                                                                                 project.getRemoteArtifactRepositories(),
 1423  
                                                                                 artifactMetadataSource, filter );
 1424  0
             resolvedArtifacts = result.getArtifacts();
 1425  
         }
 1426  0
         catch (MultipleArtifactsNotFoundException me)
 1427  
         {
 1428  
             /*only do this if we are an aggregating plugin: MNG-2277
 1429  
             if the dependency doesn't yet exist but is in the reactor, then 
 1430  
             all we can do is warn and skip it. A better fix can be inserted into 2.1*/
 1431  0
             if (isAggregator && checkMissingArtifactsInReactor( context.getSortedProjects(), me.getMissingArtifacts() ))
 1432  
             {
 1433  0
                 resolvedArtifacts = new HashSet(me.getResolvedArtifacts());
 1434  
             }
 1435  
             else
 1436  
             {
 1437  
                 //we can't find all the artifacts in the reactor so bubble the exception up.
 1438  0
                 throw me;
 1439  
             }
 1440  0
         }
 1441  0
         project.setArtifacts( resolvedArtifacts );
 1442  0
     }
 1443  
 
 1444  
     /**
 1445  
      * This method is checking to see if the artifacts that can't be resolved are all
 1446  
      * part of this reactor. This is done to prevent a chicken or egg scenario with
 1447  
      * fresh projects that have a plugin that is an aggregator and requires dependencies. See
 1448  
      * MNG-2277 for more info.
 1449  
      * @param projects the sibling projects in the reactor
 1450  
      * @param missing the artifacts that can't be found
 1451  
      * @return true if ALL missing artifacts are found in the reactor.
 1452  
      */
 1453  
     private boolean checkMissingArtifactsInReactor(Collection projects, Collection missing)
 1454  
     {
 1455  0
         Collection foundInReactor = new HashSet();
 1456  0
         Iterator iter = missing.iterator();
 1457  0
         while (iter.hasNext())
 1458  
         {
 1459  0
             Artifact mArtifact = (Artifact) iter.next();
 1460  0
             Iterator pIter = projects.iterator();
 1461  0
             while (pIter.hasNext())
 1462  
             {
 1463  0
                 MavenProject p = (MavenProject) pIter.next();
 1464  0
                 if (p.getArtifactId().equals( mArtifact.getArtifactId()) &&
 1465  
                     p.getGroupId().equals( mArtifact.getGroupId()) &&
 1466  
                     p.getVersion().equals( mArtifact.getVersion()))
 1467  
                 {
 1468  
                     //TODO: the packaging could be different, but the exception doesn't contain that info
 1469  
                     //most likely it would be produced by the project we just found in the reactor since all
 1470  
                     //the other info matches. Assume it's ok.
 1471  0
                     getLogger().warn( "The dependency: "+ p.getId()+" can't be resolved but has been found in the reactor.\nThis dependency has been excluded from the plugin execution. You should rerun this mojo after executing mvn install.\n" );
 1472  
                     
 1473  
                     //found it, move on.
 1474  0
                     foundInReactor.add( p );
 1475  0
                     break;
 1476  
                 }   
 1477  0
             }
 1478  0
         }
 1479  
         
 1480  
         //if all of them have been found, we can continue.
 1481  0
         return foundInReactor.size() == missing.size();
 1482  
     }
 1483  
     
 1484  
     
 1485  
     // ----------------------------------------------------------------------
 1486  
     // Artifact downloading
 1487  
     // ----------------------------------------------------------------------
 1488  
 
 1489  
     private void downloadDependencies( MavenProject project,
 1490  
                                        MavenSession context,
 1491  
                                        ArtifactResolver artifactResolver )
 1492  
         throws ArtifactResolutionException, ArtifactNotFoundException
 1493  
     {
 1494  0
         ArtifactRepository localRepository = context.getLocalRepository();
 1495  0
         List remoteArtifactRepositories = project.getRemoteArtifactRepositories();
 1496  
 
 1497  0
         for ( Iterator it = project.getArtifacts().iterator(); it.hasNext(); )
 1498  
         {
 1499  0
             Artifact artifact = (Artifact) it.next();
 1500  
 
 1501  0
             artifactResolver.resolve( artifact, remoteArtifactRepositories, localRepository );
 1502  0
         }
 1503  0
     }
 1504  
 
 1505  
     public Object getPluginComponent( Plugin plugin,
 1506  
                                       String role,
 1507  
                                       String roleHint )
 1508  
         throws PluginManagerException, ComponentLookupException
 1509  
     {
 1510  0
         PluginDescriptor pluginDescriptor = pluginCollector.getPluginDescriptor( plugin );
 1511  
 
 1512  0
         PlexusContainer pluginContainer = getPluginContainer( pluginDescriptor );
 1513  
 
 1514  0
         return pluginContainer.lookup( role, roleHint );
 1515  
     }
 1516  
 
 1517  
     public Map getPluginComponents( Plugin plugin,
 1518  
                                     String role )
 1519  
         throws ComponentLookupException, PluginManagerException
 1520  
     {
 1521  0
         PluginDescriptor pluginDescriptor = pluginCollector.getPluginDescriptor( plugin );
 1522  
 
 1523  0
         PlexusContainer pluginContainer = getPluginContainer( pluginDescriptor );
 1524  
 
 1525  0
         return pluginContainer.lookupMap( role );
 1526  
     }
 1527  
 }