You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by jd...@apache.org on 2007/11/02 17:44:06 UTC

svn commit: r591391 [1/3] - in /maven/components/trunk: ./ maven-core/src/main/aspect/org/apache/maven/compat/plugin/ maven-core/src/main/java/org/apache/maven/ maven-core/src/main/java/org/apache/maven/execution/ maven-core/src/main/java/org/apache/ma...

Author: jdcasey
Date: Fri Nov  2 09:44:00 2007
New Revision: 591391

URL: http://svn.apache.org/viewvc?rev=591391&view=rev
Log:
Switching back to selectively import extensions into a project-specific ClassRealm, except this time extension realms will be shared (the origin of the aforementioned imports) to conserve memory tied up by classloading. Similarly, plugin realms are managed using a key produced from g:a:v of the plugin, plus the hashcode of all g:a:v of the plugin-level dependencies aggregated into one string, to distinguish the deploy plugin 2.0 with no deps from the deploy plugin 2.0 with a plugin-level dep on wagon-webdav. Plugin realms have their parent realms managed by the pluginManager now prior to lookup or execution of the mojo instance, and PluginDescriptor.(classRealm|artifacts) attributes are set for each execution. Likewise, the MavenPluginCollector now tracks plugin descriptors with their version information included, instead of just using g:a.

Had to bump the plexus-container-default version up to alpha-36 to fix a problem in ClassicSingletonComponentManager. All realms for extensions, plugins, and projects (which contain only imports from extensions) are now managed by the MavenRealmManager.

Added:
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenRealmManager.java   (with props)
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/MavenRealmManager.java   (with props)
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/RealmManagementException.java   (with props)
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/RealmUtils.java   (with props)
Removed:
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/MavenProjectSession.java
    maven/components/trunk/maven-core/src/test/java/org/apache/maven/execution/MavenProjectSessionTest.java
Modified:
    maven/components/trunk/build.properties
    maven/components/trunk/maven-core/src/main/aspect/org/apache/maven/compat/plugin/Maven20xCompatAspect.aj
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/BuildExtensionScanner.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/DefaultBuildExtensionScanner.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/ExtensionManager.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/ExtensionManagerException.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/DefaultLifecycleExecutor.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/lifecycle/binding/DefaultLifecycleBindingManager.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/DefaultPluginManager.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/MavenPluginCollector.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/PluginContainerException.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/PluginManager.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/PluginManagerException.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/loader/DefaultPluginLoader.java
    maven/components/trunk/maven-core/src/main/java/org/apache/maven/plugin/loader/PluginLoader.java
    maven/components/trunk/maven-core/src/test/java/org/apache/maven/extension/DefaultExtensionManagerTest.java
    maven/components/trunk/maven-embedder/src/main/java/org/apache/maven/embedder/Configuration.java
    maven/components/trunk/maven-embedder/src/main/java/org/apache/maven/embedder/DefaultConfiguration.java
    maven/components/trunk/maven-embedder/src/main/java/org/apache/maven/embedder/MavenEmbedder.java
    maven/components/trunk/maven-embedder/src/main/java/org/apache/maven/embedder/execution/DefaultMavenExecutionRequestPopulator.java
    maven/components/trunk/maven-project/src/main/java/org/apache/maven/project/MavenProject.java
    maven/components/trunk/pom.xml

Modified: maven/components/trunk/build.properties
URL: http://svn.apache.org/viewvc/maven/components/trunk/build.properties?rev=591391&r1=591390&r2=591391&view=diff
==============================================================================
--- maven/components/trunk/build.properties (original)
+++ maven/components/trunk/build.properties Fri Nov  2 09:44:00 2007
@@ -16,7 +16,7 @@
 # under the License.
 
 classworlds.version=1.2-alpha-10
-plexus.version=1.0-alpha-35
+plexus.version=1.0-alpha-36
 plexus-utils.version=1.4.5
 maven-artifact.version=3.0-SNAPSHOT
 commons-cli.version=1.0

Modified: maven/components/trunk/maven-core/src/main/aspect/org/apache/maven/compat/plugin/Maven20xCompatAspect.aj
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/aspect/org/apache/maven/compat/plugin/Maven20xCompatAspect.aj?rev=591391&r1=591390&r2=591391&view=diff
==============================================================================
--- maven/components/trunk/maven-core/src/main/aspect/org/apache/maven/compat/plugin/Maven20xCompatAspect.aj (original)
+++ maven/components/trunk/maven-core/src/main/aspect/org/apache/maven/compat/plugin/Maven20xCompatAspect.aj Fri Nov  2 09:44:00 2007
@@ -4,6 +4,7 @@
 import org.apache.maven.execution.MavenExecutionResult;
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.extension.DefaultExtensionManager;
+import org.apache.maven.execution.MavenRealmManager;
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.factory.ArtifactFactory;
 import org.apache.maven.artifact.metadata.ResolutionGroup;
@@ -24,12 +25,21 @@
 import org.apache.maven.plugin.version.PluginVersionResolutionException;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.settings.MavenSettingsBuilder;
+import org.apache.maven.settings.DefaultMavenSettingsBuilder;
 import org.apache.maven.settings.Settings;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.context.Context;
+import org.codehaus.plexus.context.ContextException;
 
 import java.io.IOException;
 import java.io.PrintStream;
 import java.util.Iterator;
+import java.util.Collection;
 import java.util.Set;
 
 public privileged aspect Maven20xCompatAspect
@@ -38,54 +48,23 @@
     // pointcut to avoid recursive matching on behavior injected by this aspect.
     private pointcut notHere(): !within( Maven20xCompatAspect );
 
-    private pointcut showVersion( PrintStream stream, String string):
-        cflow( execution( void org.apache.maven.cli.CLIReportingUtils.showVersion() ) )
-        && call( void PrintStream.println( String ) )
-        && args( string )
-        && target( stream )
-        && notHere();
-
-    void around( PrintStream stream, String string ): showVersion( stream, string )
-    {
-        if ( stream == System.out && string != null && string.startsWith( "Maven version:" ) )
-        {
-            System.out.println( string + " (compat enabled)" );
-        }
-        else
-        {
-            proceed( stream, string );
-        }
-    }
-
-    // GRAB Session and Request.
+    // GRAB Session as soon as it's constructed.
     private MavenSession session;
-    private MavenExecutionRequest request;
 
     private pointcut sessionCreation( MavenSession session ):
-        execution( public MavenSession.new(..) )
+        execution( public MavenSession+.new(..) )
         && this( session )
         && notHere();
 
-    // capture the session instance in play.
+    // capture the session instance.
     after( MavenSession session ): sessionCreation( session )
     {
         this.session = session;
     }
 
-    private pointcut methodsTakingRequest( MavenExecutionRequest request ):
-        execution( MavenExecutionResult *.*( MavenExecutionRequest ) )
-        && args( request )
-        && notHere();
-
-    // capture the request instance in play.
-    before( MavenExecutionRequest request ): methodsTakingRequest( request )
-    {
-        this.request = request;
-    }
-
     // USE Session to compensate for old verifyPlugin(..) API.
     private pointcut verifyPlugin( Plugin plugin, MavenProject project, PluginManager manager ):
-        call( public PluginDescriptor PluginManager+.verifyPlugin( Plugin, MavenProject, Settings, ArtifactRepository ) )
+        execution( public PluginDescriptor PluginManager+.verifyPlugin( Plugin, MavenProject, Settings, ArtifactRepository ) )
         && args( plugin, project, .. )
         && target( manager )
         && notHere();
@@ -112,10 +91,41 @@
         return null;
     }
 
+    public PluginDescriptor DefaultPluginManager.verifyPlugin( Plugin plugin,
+                                                        MavenProject project,
+                                                        Settings settings,
+                                                        ArtifactRepository localRepository )
+    {
+        // this will always be diverted, so no need to do anything.
+        return null;
+    }
+
+    private pointcut getPluginDescriptorForPrefix( String prefix, PluginManager manager ):
+        execution( public PluginDescriptor PluginManager+.getPluginDescriptorForPrefix( String ) )
+        && args( prefix )
+        && target( manager )
+        && notHere();
+
+    PluginDescriptor around( String prefix, PluginManager manager ): getPluginDescriptorForPrefix( prefix, manager )
+    {
+        // TODO: Implement Me!
+        return null;
+    }
+
+    public PluginDescriptor PluginManager.getPluginDescriptorForPrefix( String prefix )
+    {
+        return null;
+    }
+
+    public PluginDescriptor DefaultPluginManager.getPluginDescriptorForPrefix( String prefix )
+    {
+        return null;
+    }
+
     // Intercept retrieval of artifact dependencies of an extension, inject plexus-utils if it's not there.
     private pointcut extDepArtifactsResolved( DefaultExtensionManager mgr ):
-        call( public Set ResolutionGroup.getArtifacts() )
-        && within( DefaultExtensionManager )
+        call( public Set ResolutionGroup+.getArtifacts() )
+        && within( DefaultExtensionManager+ )
         && this( mgr )
         && notHere();
 
@@ -130,8 +140,8 @@
 
     // Intercept retrieval of artifact dependencies of a plugin, inject plexus-utils if it's not there.
     private pointcut pluginDepArtifactsResolved( DefaultPluginManager mgr ):
-        call( public Set ResolutionGroup.getArtifacts() )
-        && cflow( execution( Set DefaultPluginManager.getPluginArtifacts(..) ) )
+        call( public Set ResolutionGroup+.getArtifacts() )
+        && cflow( execution( Set DefaultPluginManager+.getPluginArtifacts(..) ) )
         && this( mgr )
         && notHere();
 
@@ -144,6 +154,20 @@
         return result;
     }
 
+    // GRAB the request when it's passed into a method that returns a corresponding result.
+    private MavenExecutionRequest request;
+
+    private pointcut methodsTakingRequest( MavenExecutionRequest request ):
+        execution( MavenExecutionResult *.*( MavenExecutionRequest ) )
+        && args( request )
+        && notHere();
+
+    // capture the request instance before it's passed into any method that returns a corresponding MavenExecutionResult.
+    before( MavenExecutionRequest request ): methodsTakingRequest( request )
+    {
+        this.request = request;
+    }
+
     // USE Request to compensate for old buildSettings() API.
     private pointcut buildSettings( MavenSettingsBuilder builder ):
         execution( public Settings MavenSettingsBuilder+.buildSettings() )
@@ -163,6 +187,61 @@
         throws IOException, XmlPullParserException
     {
         return null;
+    }
+
+    public Settings DefaultMavenSettingsBuilder.buildSettings()
+    throws IOException, XmlPullParserException
+    {
+        return null;
+    }
+
+    // container used in the plugin manager.
+    private PlexusContainer container;
+
+    private pointcut pluginManagerContextualized( Context context ):
+        execution( void DefaultPluginManager+.contextualize( Context ) )
+        && args( context );
+
+    // capture the container when the DefaultPluginManager is contextualized.
+    void around( Context context ) throws ContextException: pluginManagerContextualized( context )
+    {
+        proceed( context );
+        container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
+    }
+
+    private pointcut pluginRealmCreation( Plugin plugin ):
+        call( ClassRealm MavenRealmManager+.createPluginRealm( Plugin, Artifact, Collection ) )
+        && withincode( void DefaultPluginManager.addPlugin(..) )
+        && args( plugin, .. );
+
+    // Add various imports for Xpp3 stuff back into the core realm every time a plugin realm is created.
+    ClassRealm around( Plugin plugin ): pluginRealmCreation( plugin )
+    {
+        ClassRealm pluginRealm = proceed( plugin );
+
+        try
+        {
+            String parentRealmId = container.getContainerRealm().getId();
+
+            // adding for MNG-3012 to try to work around problems with Xpp3Dom (from plexus-utils)
+            // spawning a ClassCastException when a mojo calls plugin.getConfiguration() from maven-model...
+            pluginRealm.importFrom( parentRealmId, Xpp3Dom.class.getName() );
+            pluginRealm.importFrom( parentRealmId, "org.codehaus.plexus.util.xml.pull" );
+
+            // Adding for MNG-2878, since maven-reporting-impl was removed from the
+            // internal list of artifacts managed by maven, the classloader is different
+            // between maven-reporting-impl and maven-reporting-api...so this resource
+            // is not available from the AbstractMavenReport since it uses:
+            // getClass().getResourceAsStream( "/default-report.xml" )
+            // (maven-reporting-impl version 2.0; line 134; affects: checkstyle plugin, and probably others)
+            pluginRealm.importFrom( parentRealmId, "/default-report.xml" );
+        }
+        catch ( NoSuchRealmException e )
+        {
+            // can't happen here. All realms are concretely resolved by now.
+        }
+
+        return pluginRealm;
     }
 
     // --------------------------

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/DefaultMaven.java?rev=591391&r1=591390&r2=591391&view=diff
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/DefaultMaven.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/DefaultMaven.java Fri Nov  2 09:44:00 2007
@@ -279,7 +279,7 @@
         // instances just-in-time.
         try
         {
-            buildExtensionScanner.scanForBuildExtensions( files, request.getLocalRepository(), request.getProfileManager() );
+            buildExtensionScanner.scanForBuildExtensions( files, request );
         }
         catch ( ExtensionScanningException e )
         {

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java?rev=591391&r1=591390&r2=591391&view=diff
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java Fri Nov  2 09:44:00 2007
@@ -116,6 +116,8 @@
      */
     private boolean noSnapshotUpdates;
 
+    private MavenRealmManager realmManager;
+
     public String getBaseDirectory()
     {
         if ( basedir == null )
@@ -602,5 +604,16 @@
     public List getRemoteRepositories()
     {
         return remoteRepositories;
+    }
+
+    public MavenExecutionRequest setRealmManager( MavenRealmManager realmManager )
+    {
+        this.realmManager = realmManager;
+        return this;
+    }
+
+    public MavenRealmManager getRealmManager()
+    {
+        return realmManager;
     }
 }

Added: maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenRealmManager.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenRealmManager.java?rev=591391&view=auto
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenRealmManager.java (added)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenRealmManager.java Fri Nov  2 09:44:00 2007
@@ -0,0 +1,355 @@
+package org.apache.maven.execution;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.Plugin;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.classworlds.ClassWorld;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
+import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
+import org.codehaus.plexus.component.discovery.ComponentDiscoverer;
+import org.codehaus.plexus.component.discovery.ComponentDiscovererManager;
+import org.codehaus.plexus.component.discovery.ComponentDiscoveryEvent;
+import org.codehaus.plexus.component.discovery.ComponentDiscoveryListener;
+import org.codehaus.plexus.component.discovery.DefaultComponentDiscoverer;
+import org.codehaus.plexus.component.repository.ComponentDescriptor;
+import org.codehaus.plexus.component.repository.ComponentSetDescriptor;
+import org.codehaus.plexus.component.repository.exception.ComponentRepositoryException;
+import org.codehaus.plexus.configuration.PlexusConfigurationException;
+import org.codehaus.plexus.logging.Logger;
+
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+public class DefaultMavenRealmManager
+    implements MavenRealmManager
+{
+
+    private Map extensionComponents = new HashMap();
+    private Map pluginArtifacts = new HashMap();
+
+    private final ClassWorld world;
+    private final PlexusContainer container;
+    private final Logger logger;
+
+    public DefaultMavenRealmManager( PlexusContainer container,
+                                     Logger logger )
+    {
+        world = container.getContainerRealm().getWorld();
+        this.container = container;
+        this.logger = logger;
+    }
+
+    public void clear()
+    {
+        extensionComponents.clear();
+        pluginArtifacts.clear();
+    }
+
+    public boolean hasExtensionRealm( Artifact extensionArtifact )
+    {
+        String id = RealmUtils.createExtensionRealmId( extensionArtifact );
+        try
+        {
+            return world.getRealm( id ) != null;
+        }
+        catch ( NoSuchRealmException e )
+        {
+            return false;
+        }
+    }
+
+    public ClassRealm createExtensionRealm( Artifact extensionArtifact,
+                                            Collection artifacts )
+        throws RealmManagementException
+    {
+        String id = RealmUtils.createExtensionRealmId( extensionArtifact );
+        ClassRealm realm;
+        try
+        {
+            realm = container.getContainerRealm().createChildRealm( id );
+        }
+        catch ( DuplicateRealmException e )
+        {
+            throw new RealmManagementException( id, "Extension realm: " + id + " already exists.",
+                                                e );
+        }
+
+        populateRealm( id, realm, extensionArtifact, artifacts );
+
+        return realm;
+    }
+
+    public void importExtensionsIntoProjectRealm( String projectGroupId,
+                                                  String projectArtifactId,
+                                                  String projectVersion,
+                                                  Artifact extensionArtifact )
+        throws RealmManagementException
+    {
+        String extensionRealmId = RealmUtils.createExtensionRealmId( extensionArtifact );
+        List componentSetDescriptors = (List) extensionComponents.get( extensionRealmId );
+
+        // don't re-discover components once this is done once.
+        if ( componentSetDescriptors == null )
+        {
+            ClassWorld discoveryWorld = new ClassWorld();
+            try
+            {
+                // Create an entire new ClassWorld, ClassRealm for discovering
+                // the immediate components of the extension artifact, so we don't pollute the
+                // container with component descriptors or realms that don't have any meaning beyond discovery.
+                ClassRealm discoveryRealm = new ClassRealm( discoveryWorld, "discovery" );
+                try
+                {
+                    discoveryRealm.addURL( extensionArtifact.getFile().toURL() );
+                }
+                catch ( MalformedURLException e )
+                {
+                    throw new RealmManagementException( extensionRealmId, extensionArtifact, "Unable to generate URL from extension artifact file: " + extensionArtifact.getFile() + " for local-component discovery.", e );
+                }
+
+                ComponentDiscoverer discoverer = new DefaultComponentDiscoverer();
+                discoverer.setManager( new DummyDiscovererManager() );
+
+                try
+                {
+                    // Find the extension component descriptors that exist ONLY in the immediate extension
+                    // artifact...this prevents us from adding plexus-archiver components to the mix, for instance,
+                    // when the extension uses that dependency.
+                    componentSetDescriptors = discoverer.findComponents( container.getContext(), discoveryRealm );
+                    extensionComponents.put( extensionRealmId, componentSetDescriptors );
+                }
+                catch ( PlexusConfigurationException e )
+                {
+                    throw new RealmManagementException( extensionRealmId, "Unable to discover components in extension artifact: " + extensionArtifact.getId(), e );
+                }
+            }
+            finally
+            {
+                Collection realms = discoveryWorld.getRealms();
+                for ( Iterator it = realms.iterator(); it.hasNext(); )
+                {
+                    ClassRealm realm = (ClassRealm) it.next();
+                    try
+                    {
+                        discoveryWorld.disposeRealm( realm.getId() );
+                    }
+                    catch ( NoSuchRealmException e )
+                    {
+                    }
+                }
+            }
+        }
+
+        ClassRealm realm = getProjectRealm( projectGroupId, projectArtifactId, projectVersion, true );
+
+        for ( Iterator it = componentSetDescriptors.iterator(); it.hasNext(); )
+        {
+            ComponentSetDescriptor compSet = (ComponentSetDescriptor) it.next();
+            for ( Iterator compIt = compSet.getComponents().iterator(); compIt.hasNext(); )
+            {
+                // For each component in the extension artifact:
+                ComponentDescriptor comp = (ComponentDescriptor) compIt.next();
+                String implementation = comp.getImplementation();
+
+                try
+                {
+                    logger.debug( "Importing: " + implementation + "\nwith role: " + comp.getRole() + "\nand hint: " + comp.getRoleHint() + "\nfrom extension realm: " + extensionRealmId + "\nto project realm: " + realm.getId() );
+
+                    // Import the extension component's implementation class into the project-level
+                    // realm.
+                    realm.importFrom( extensionRealmId, implementation );
+
+                    // Set the realmId to be used in looking up this extension component to the
+                    // project-level realm, since we now have a restricted import
+                    // that allows most of the extension to stay hidden, and the
+                    // specific local extension components are still accessible
+                    // from the project-level realm.
+                    comp.setRealmId( realm.getId() );
+
+                    // Finally, add the extension component's descriptor (with projectRealm
+                    // set as the lookup realm) to the container.
+                    container.addComponentDescriptor( comp );
+                }
+                catch ( NoSuchRealmException e )
+                {
+                    throw new RealmManagementException( extensionRealmId, "Failed to create import for component: " + implementation + " from extension realm: " + extensionRealmId + " to project realm: " + realm.getId(), e );
+                }
+                catch ( ComponentRepositoryException e )
+                {
+                    String projectId = RealmUtils.createProjectId( projectGroupId, projectArtifactId, projectVersion );
+                    throw new RealmManagementException( extensionRealmId, "Unable to discover components from imports to project: " + projectId + " from extension artifact: " + extensionArtifact.getId(), e );
+                }
+            }
+        }
+    }
+
+    public ClassRealm getProjectRealm( String projectGroupId, String projectArtifactId, String projectVersion )
+    {
+        return getProjectRealm( projectGroupId, projectArtifactId, projectVersion, false );
+    }
+
+    private ClassRealm getProjectRealm( String projectGroupId, String projectArtifactId, String projectVersion, boolean create )
+    {
+        String id = RealmUtils.createProjectId( projectGroupId, projectArtifactId, projectVersion );
+
+        ClassRealm realm = null;
+        try
+        {
+            realm = world.getRealm( id );
+        }
+        catch ( NoSuchRealmException e )
+        {
+            if ( create )
+            {
+                try
+                {
+                    realm = container.getContainerRealm().createChildRealm( id );
+                }
+                catch ( DuplicateRealmException duplicateError )
+                {
+                    // won't happen.
+                }
+            }
+        }
+
+        return realm;
+    }
+
+    private static final class DummyDiscovererManager implements ComponentDiscovererManager
+    {
+
+        public void fireComponentDiscoveryEvent( ComponentDiscoveryEvent arg0 )
+        {
+        }
+
+        public List getComponentDiscoverers()
+        {
+            return null;
+        }
+
+        public Map getComponentDiscoveryListeners()
+        {
+            return null;
+        }
+
+        public List getListeners()
+        {
+            return null;
+        }
+
+        public void initialize()
+        {
+        }
+
+        public void registerComponentDiscoveryListener( ComponentDiscoveryListener l )
+        {
+        }
+
+        public void removeComponentDiscoveryListener( ComponentDiscoveryListener l )
+        {
+        }
+
+    }
+
+    public ClassRealm getPluginRealm( Plugin plugin )
+    {
+        String id = RealmUtils.createPluginRealmId( plugin );
+
+        logger.debug( "Retrieving realm for plugin with id: " + id );
+
+        try
+        {
+            return world.getRealm( id );
+        }
+        catch ( NoSuchRealmException e )
+        {
+            return null;
+        }
+    }
+
+    public ClassRealm createPluginRealm( Plugin plugin,
+                                          Artifact pluginArtifact,
+                                          Collection artifacts )
+        throws RealmManagementException
+    {
+        String id = RealmUtils.createPluginRealmId( plugin );
+
+        logger.debug( "Creating realm for plugin with id: " + id );
+
+        ClassRealm realm;
+        try
+        {
+            realm = world.newRealm( id );
+        }
+        catch ( DuplicateRealmException e )
+        {
+            throw new RealmManagementException( id, "Plugin realm: " + id + " already exists.",
+                                                e );
+        }
+
+        populateRealm( id, realm, pluginArtifact, artifacts );
+        pluginArtifacts.put( id, artifacts );
+
+        return realm;
+    }
+
+    private void populateRealm( String id,
+                                ClassRealm realm,
+                                Artifact mainArtifact,
+                                Collection artifacts )
+        throws RealmManagementException
+    {
+        if ( !artifacts.contains( mainArtifact ) )
+        {
+            try
+            {
+                realm.addURL( mainArtifact.getFile().toURI().toURL() );
+            }
+            catch ( MalformedURLException e )
+            {
+                throw new RealmManagementException( id, mainArtifact, "Invalid URL for artifact file: "
+                                                                  + mainArtifact.getFile()
+                                                                  + " to be used in realm: " + id
+                                                                  + ".", e );
+            }
+        }
+
+        for ( Iterator it = artifacts.iterator(); it.hasNext(); )
+        {
+            Artifact artifact = (Artifact) it.next();
+            try
+            {
+                realm.addURL( artifact.getFile().toURI().toURL() );
+            }
+            catch ( MalformedURLException e )
+            {
+                throw new RealmManagementException( id, artifact, "Invalid URL for artifact file: "
+                                                                  + artifact.getFile()
+                                                                  + " to be used in realm: " + id
+                                                                  + ".", e );
+            }
+        }
+    }
+
+    public List getPluginArtifacts( Plugin plugin )
+    {
+        String id = RealmUtils.createPluginRealmId( plugin );
+
+        logger.debug( "Getting artifacts used in realm for plugin with id: " + id );
+
+        Collection artifacts = (Collection) pluginArtifacts.get( id );
+
+        if ( artifacts != null )
+        {
+            return new ArrayList( artifacts );
+        }
+
+        return null;
+    }
+}

Propchange: maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenRealmManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenRealmManager.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java?rev=591391&r1=591390&r2=591391&view=diff
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java Fri Nov  2 09:44:00 2007
@@ -202,4 +202,7 @@
 
     MavenExecutionRequest addRemoteRepository( ArtifactRepository repository );
     List getRemoteRepositories();
+
+    MavenExecutionRequest setRealmManager( MavenRealmManager realmManager );
+    MavenRealmManager getRealmManager();
 }

Added: maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/MavenRealmManager.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/MavenRealmManager.java?rev=591391&view=auto
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/MavenRealmManager.java (added)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/MavenRealmManager.java Fri Nov  2 09:44:00 2007
@@ -0,0 +1,39 @@
+package org.apache.maven.execution;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.Plugin;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+
+import java.util.Collection;
+import java.util.List;
+
+public interface MavenRealmManager
+{
+
+    void clear();
+
+    boolean hasExtensionRealm( Artifact extensionArtifact );
+
+    ClassRealm createExtensionRealm( Artifact extensionArtifact,
+                                     Collection artifacts )
+        throws RealmManagementException;
+
+    void importExtensionsIntoProjectRealm( String projectGroupId,
+                                           String projectArtifactId,
+                                           String projectVersion,
+                                           Artifact extensionArtifact )
+        throws RealmManagementException;
+
+    ClassRealm getProjectRealm( String groupId,
+                                String artifactId,
+                                String version );
+
+    ClassRealm getPluginRealm( Plugin plugin );
+
+    List getPluginArtifacts( Plugin plugin );
+
+    ClassRealm createPluginRealm( Plugin plugin,
+                                  Artifact pluginArtifact,
+                                  Collection artifacts )
+        throws RealmManagementException;
+}

Propchange: maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/MavenRealmManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/MavenRealmManager.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java?rev=591391&r1=591390&r2=591391&view=diff
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/MavenSession.java Fri Nov  2 09:44:00 2007
@@ -65,6 +65,11 @@
         this.reactorManager = reactorManager;
     }
 
+    public MavenRealmManager getRealmManager()
+    {
+        return request.getRealmManager();
+    }
+
     public Map getPluginContext( PluginDescriptor pluginDescriptor,
                                  MavenProject project )
     {

Added: maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/RealmManagementException.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/RealmManagementException.java?rev=591391&view=auto
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/RealmManagementException.java (added)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/RealmManagementException.java Fri Nov  2 09:44:00 2007
@@ -0,0 +1,79 @@
+package org.apache.maven.execution;
+
+import org.apache.maven.artifact.Artifact;
+import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
+import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
+import org.codehaus.plexus.component.repository.exception.ComponentRepositoryException;
+import org.codehaus.plexus.configuration.PlexusConfigurationException;
+
+import java.net.MalformedURLException;
+
+public class RealmManagementException
+    extends Exception
+{
+
+    private final String realmId;
+    private String offendingGroupId;
+    private String offendingArtifactId;
+    private String offendingVersion;
+
+    public RealmManagementException( String realmId, String message, DuplicateRealmException cause )
+    {
+        super( message, cause );
+        this.realmId = realmId;
+    }
+
+    public RealmManagementException( String realmId, Artifact offendingArtifact, String message, MalformedURLException cause )
+    {
+        super( message, cause );
+        this.realmId = realmId;
+        offendingGroupId = offendingArtifact.getGroupId();
+        offendingArtifactId = offendingArtifact.getArtifactId();
+        offendingVersion = offendingArtifact.getVersion();
+    }
+
+    public RealmManagementException( String realmId,
+                                     String message,
+                                     NoSuchRealmException cause )
+    {
+        super( message, cause );
+        this.realmId = realmId;
+    }
+
+    public RealmManagementException( String realmId,
+                                     String message,
+                                     ComponentRepositoryException cause )
+    {
+        super( message, cause );
+        this.realmId = realmId;
+    }
+
+    public RealmManagementException( String realmId,
+                                     String message,
+                                     PlexusConfigurationException cause )
+    {
+        super( message, cause );
+        this.realmId = realmId;
+    }
+
+    public String getRealmId()
+    {
+        return realmId;
+    }
+
+    public String getOffendingGroupId()
+    {
+        return offendingGroupId;
+    }
+
+    public String getOffendingArtifactId()
+    {
+        return offendingArtifactId;
+    }
+
+    public String getOffendingVersion()
+    {
+        return offendingVersion;
+    }
+
+}

Propchange: maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/RealmManagementException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/RealmManagementException.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Added: maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/RealmUtils.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/RealmUtils.java?rev=591391&view=auto
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/RealmUtils.java (added)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/RealmUtils.java Fri Nov  2 09:44:00 2007
@@ -0,0 +1,73 @@
+package org.apache.maven.execution;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Plugin;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+
+public final class RealmUtils
+{
+
+    private RealmUtils()
+    {
+    }
+
+    public static String createExtensionRealmId( Artifact extensionArtifact )
+    {
+        return "/extensions/" + extensionArtifact.getGroupId() + ":"
+               + extensionArtifact.getArtifactId() + ":" + extensionArtifact.getVersion();
+    }
+
+    public static String createProjectId( String projectGroupId,
+                                          String projectArtifactId,
+                                          String projectVersion )
+    {
+        return "/projects/" + projectGroupId + ":" + projectArtifactId + ":" + projectVersion;
+    }
+
+    public static String createPluginRealmId( Plugin plugin )
+    {
+        StringBuffer id = new StringBuffer().append( "/plugins/" )
+                                            .append( plugin.getGroupId() )
+                                            .append( ':' )
+                                            .append( plugin.getArtifactId() )
+                                            .append( ':' )
+                                            .append( plugin.getVersion() );
+
+        StringBuffer depId = new StringBuffer();
+
+        Collection dependencies = plugin.getDependencies();
+        if ( ( dependencies != null ) && !dependencies.isEmpty() )
+        {
+            dependencies = new LinkedHashSet( dependencies );
+
+            for ( Iterator it = dependencies.iterator(); it.hasNext(); )
+            {
+                Dependency dep = (Dependency) it.next();
+
+                depId.append( dep.getGroupId() )
+                     .append( ':' )
+                     .append( dep.getArtifactId() )
+                     .append( ';' )
+                     .append( dep.getVersion() );
+
+                if ( it.hasNext() )
+                {
+                    depId.append( ',' );
+                }
+            }
+        }
+        else
+        {
+            depId.append( '0' );
+        }
+
+        id.append( '@' ).append( depId.toString().hashCode() );
+
+        return id.toString();
+    }
+
+}

Propchange: maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/RealmUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/components/trunk/maven-core/src/main/java/org/apache/maven/execution/RealmUtils.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/BuildExtensionScanner.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/BuildExtensionScanner.java?rev=591391&r1=591390&r2=591391&view=diff
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/BuildExtensionScanner.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/BuildExtensionScanner.java Fri Nov  2 09:44:00 2007
@@ -19,8 +19,7 @@
  * under the License.
  */
 
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.profiles.ProfileManager;
+import org.apache.maven.execution.MavenExecutionRequest;
 
 import java.io.File;
 import java.util.List;
@@ -31,13 +30,11 @@
     String ROLE = BuildExtensionScanner.class.getName();
 
     void scanForBuildExtensions( List files,
-                                 ArtifactRepository localRepository,
-                                 ProfileManager globalProfileManager )
+                                 MavenExecutionRequest request )
         throws ExtensionScanningException;
 
     void scanForBuildExtensions( File pom,
-                                 ArtifactRepository localRepository,
-                                 ProfileManager globalProfileManager )
+                                 MavenExecutionRequest request )
         throws ExtensionScanningException;
 
 }

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/DefaultBuildExtensionScanner.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/DefaultBuildExtensionScanner.java?rev=591391&r1=591390&r2=591391&view=diff
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/DefaultBuildExtensionScanner.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/DefaultBuildExtensionScanner.java Fri Nov  2 09:44:00 2007
@@ -20,14 +20,13 @@
  */
 
 import org.apache.maven.artifact.ArtifactUtils;
-import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.context.BuildContextManager;
+import org.apache.maven.execution.MavenExecutionRequest;
 import org.apache.maven.model.Build;
 import org.apache.maven.model.Extension;
 import org.apache.maven.model.Model;
 import org.apache.maven.model.Parent;
 import org.apache.maven.plugin.loader.PluginLoader;
-import org.apache.maven.profiles.ProfileManager;
 import org.apache.maven.profiles.activation.CustomActivatorAdvice;
 import org.apache.maven.project.MavenProject;
 import org.apache.maven.project.MavenProjectBuilder;
@@ -70,8 +69,7 @@
     private PluginLoader pluginLoader;
 
     public void scanForBuildExtensions( List files,
-                                        ArtifactRepository localRepository,
-                                        ProfileManager globalProfileManager )
+                                        MavenExecutionRequest request )
         throws ExtensionScanningException
     {
         List visited = new ArrayList();
@@ -80,23 +78,21 @@
         {
             File pom = (File) it.next();
 
-            scanInternal( pom, localRepository, globalProfileManager, visited, files );
+            scanInternal( pom, request, visited, files );
         }
     }
 
     public void scanForBuildExtensions( File pom,
-                                        ArtifactRepository localRepository,
-                                        ProfileManager globalProfileManager )
+                                        MavenExecutionRequest request )
         throws ExtensionScanningException
     {
-        scanInternal( pom, localRepository, globalProfileManager, new ArrayList(), Collections.singletonList( pom ) );
+        scanInternal( pom, request, new ArrayList(), Collections.singletonList( pom ) );
     }
 
     // TODO: Use a build-context cache object for visitedModelIdx and reactorFiles,
     //       once we move to just-in-time project scanning.
     private void scanInternal( File pom,
-                               ArtifactRepository localRepository,
-                               ProfileManager globalProfileManager,
+                               MavenExecutionRequest request,
                                List visitedModelIds,
                                List reactorFiles )
         throws ExtensionScanningException
@@ -114,8 +110,7 @@
 
             getLogger().debug( "Pre-scanning POM lineage of: " + pom + " for build extensions." );
 
-            ModelLineage lineage = buildModelLineage( pom, localRepository, originalRemoteRepositories,
-                                                      globalProfileManager );
+            ModelLineage lineage = buildModelLineage( pom, request, originalRemoteRepositories );
 
             Map inheritedInterpolationValues = new HashMap();
 
@@ -155,7 +150,7 @@
 
                 model = modelInterpolator.interpolate( model, inheritedInterpolationValues, false );
 
-                checkModelBuildForExtensions( model, localRepository, inheritedRemoteRepositories );
+                checkModelBuildForExtensions( model, request, inheritedRemoteRepositories );
 
                 if ( !reactorFiles.contains( modelPom ) )
                 {
@@ -167,9 +162,8 @@
                 {
                     checkModulesForExtensions( modelPom,
                                                model,
-                                               localRepository,
+                                               request,
                                                originalRemoteRepositories,
-                                               globalProfileManager,
                                                visitedModelIds,
                                                reactorFiles );
                 }
@@ -214,9 +208,8 @@
 
     private void checkModulesForExtensions( File containingPom,
                                             Model model,
-                                            ArtifactRepository localRepository,
+                                            MavenExecutionRequest request,
                                             List originalRemoteRepositories,
-                                            ProfileManager globalProfileManager,
                                             List visitedModelIds,
                                             List reactorFiles )
         throws ExtensionScanningException
@@ -284,12 +277,12 @@
                     continue;
                 }
 
-                scanInternal( modulePomDirectory, localRepository, globalProfileManager, visitedModelIds, reactorFiles );
+                scanInternal( modulePomDirectory, request, visitedModelIds, reactorFiles );
             }
         }
     }
 
-    private void checkModelBuildForExtensions( Model model, ArtifactRepository localRepository, List remoteRepositories )
+    private void checkModelBuildForExtensions( Model model, MavenExecutionRequest request, List remoteRepositories )
         throws ExtensionScanningException
     {
         Build build = model.getBuild();
@@ -313,7 +306,7 @@
 
                     try
                     {
-                        extensionManager.addExtension( extension, model, remoteRepositories, localRepository );
+                        extensionManager.addExtension( extension, model, remoteRepositories, request );
                     }
                     catch ( ExtensionManagerException e )
                     {
@@ -325,8 +318,8 @@
         }
     }
 
-    private ModelLineage buildModelLineage( File pom, ArtifactRepository localRepository,
-                                            List originalRemoteRepositories, ProfileManager globalProfileManager )
+    private ModelLineage buildModelLineage( File pom, MavenExecutionRequest request,
+                                            List originalRemoteRepositories )
         throws ExtensionScanningException
     {
         ModelLineage lineage;
@@ -338,8 +331,8 @@
             // not for POMs from the repository...otherwise, we would need to be more careful with
             // the last parameter here and determine whether it's appropriate for the POM to have
             // an accompanying profiles.xml file.
-            lineage = modelLineageBuilder.buildModelLineage( pom, localRepository, originalRemoteRepositories,
-                                                             globalProfileManager, false, true );
+            lineage = modelLineageBuilder.buildModelLineage( pom, request.getLocalRepository(), originalRemoteRepositories,
+                                                             request.getProfileManager(), false, true );
         }
         catch ( ProjectBuildingException e )
         {

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java?rev=591391&r1=591390&r2=591391&view=diff
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java Fri Nov  2 09:44:00 2007
@@ -28,6 +28,8 @@
 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
 import org.apache.maven.artifact.metadata.ResolutionGroup;
 import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
 import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
 import org.apache.maven.artifact.resolver.ArtifactResolver;
@@ -35,37 +37,35 @@
 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
 import org.apache.maven.artifact.versioning.VersionRange;
-import org.apache.maven.execution.MavenProjectSession;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenRealmManager;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.execution.RealmManagementException;
+import org.apache.maven.execution.RealmUtils;
 import org.apache.maven.model.Extension;
 import org.apache.maven.model.Model;
 import org.apache.maven.model.Parent;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.monitor.event.DefaultEventDispatcher;
+import org.apache.maven.monitor.event.EventDispatcher;
+import org.apache.maven.plugin.InvalidPluginException;
+import org.apache.maven.plugin.PluginManager;
+import org.apache.maven.plugin.PluginManagerException;
+import org.apache.maven.plugin.PluginNotFoundException;
+import org.apache.maven.plugin.descriptor.PluginDescriptor;
+import org.apache.maven.plugin.version.PluginVersionNotFoundException;
+import org.apache.maven.plugin.version.PluginVersionResolutionException;
 import org.apache.maven.project.MavenProject;
 import org.codehaus.plexus.MutablePlexusContainer;
 import org.codehaus.plexus.PlexusConstants;
-import org.codehaus.plexus.classworlds.ClassWorld;
-import org.codehaus.plexus.classworlds.realm.ClassRealm;
-import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
-import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
-import org.codehaus.plexus.component.discovery.ComponentDiscoverer;
-import org.codehaus.plexus.component.discovery.ComponentDiscovererManager;
-import org.codehaus.plexus.component.discovery.ComponentDiscoveryEvent;
-import org.codehaus.plexus.component.discovery.ComponentDiscoveryListener;
-import org.codehaus.plexus.component.discovery.DefaultComponentDiscoverer;
-import org.codehaus.plexus.component.repository.ComponentDescriptor;
-import org.codehaus.plexus.component.repository.ComponentSetDescriptor;
-import org.codehaus.plexus.component.repository.exception.ComponentRepositoryException;
-import org.codehaus.plexus.configuration.PlexusConfigurationException;
 import org.codehaus.plexus.context.Context;
 import org.codehaus.plexus.context.ContextException;
 import org.codehaus.plexus.logging.AbstractLogEnabled;
 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
 
-import java.net.MalformedURLException;
-import java.util.Collection;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 /**
@@ -91,6 +91,8 @@
 
     private WagonManager wagonManager;
 
+    private PluginManager pluginManager;
+
     // used for unit testing.
     protected DefaultExtensionManager( ArtifactFactory artifactFactory,
                                     ArtifactResolver artifactResolver,
@@ -115,7 +117,7 @@
     public void addExtension( Extension extension,
                               Model originatingModel,
                               List remoteRepositories,
-                              ArtifactRepository localRepository )
+                              MavenExecutionRequest request )
         throws ExtensionManagerException
     {
         Artifact extensionArtifact = artifactFactory.createBuildArtifact( extension.getGroupId(),
@@ -145,14 +147,119 @@
         addExtension( extensionArtifact,
                       projectArtifact,
                       remoteRepositories,
-                      localRepository,
+                      request,
                       null,
-                      MavenProjectSession.createProjectId( groupId, artifactId, version ) );
+                      groupId,
+                      artifactId,
+                      version );
+    }
+
+    public void addPluginAsExtension( Plugin plugin,
+                              Model originatingModel,
+                              List remoteRepositories,
+                              MavenExecutionRequest request )
+        throws ExtensionManagerException
+    {
+        Parent originatingParent = originatingModel.getParent();
+
+        String groupId = originatingModel.getGroupId();
+
+        if ( ( groupId == null ) && ( originatingParent != null ) )
+        {
+            groupId = originatingParent.getGroupId();
+        }
+
+        String artifactId = originatingModel.getArtifactId();
+
+        String version = originatingModel.getVersion();
+
+        if ( ( version == null ) && ( originatingParent != null ) )
+        {
+            version = originatingParent.getVersion();
+        }
+
+        Artifact pluginArtifact = artifactFactory.createBuildArtifact( plugin.getGroupId(),
+                                                                       plugin.getArtifactId(),
+                                                                       plugin.getVersion(), "maven-plugin" );
+
+        getLogger().debug( "Starting extension-addition process for: " + pluginArtifact );
+
+        ArtifactFilter coreFilter = artifactFilterManager.getArtifactFilter();
+        MavenRealmManager realmManager = request.getRealmManager();
+
+        // if the extension is null,
+        // or if it's excluded by the core filter,
+        //
+        // skip it.
+        if ( ( pluginArtifact != null )
+             && coreFilter.include( pluginArtifact ) )
+        {
+            if ( !realmManager.hasExtensionRealm( pluginArtifact ) )
+            {
+                MavenProject dummyProject = new MavenProject( originatingModel );
+                EventDispatcher dispatcher = new DefaultEventDispatcher( request.getEventMonitors() );
+                MavenSession session = new MavenSession( container, request, dispatcher, null );
+
+                PluginDescriptor pd;
+                try
+                {
+                    pd = pluginManager.verifyPlugin( plugin, dummyProject, session );
+                    pluginArtifact = pd.getPluginArtifact();
+                }
+                catch ( ArtifactResolutionException e )
+                {
+                    throw new ExtensionManagerException( "Failed to resolve extension plugin: " + pluginArtifact, pluginArtifact, groupId, artifactId, version, e );
+                }
+                catch ( ArtifactNotFoundException e )
+                {
+                    throw new ExtensionManagerException( "Failed to resolve extension plugin: " + pluginArtifact, pluginArtifact, groupId, artifactId, version, e );
+                }
+                catch ( PluginNotFoundException e )
+                {
+                    throw new ExtensionManagerException( "Failed to resolve extension plugin: " + pluginArtifact, pluginArtifact, groupId, artifactId, version, e );
+                }
+                catch ( PluginVersionResolutionException e )
+                {
+                    throw new ExtensionManagerException( "Failed to resolve extension plugin: " + pluginArtifact, pluginArtifact, groupId, artifactId, version, e );
+                }
+                catch ( InvalidPluginException e )
+                {
+                    throw new ExtensionManagerException( "Failed to resolve extension plugin: " + pluginArtifact, pluginArtifact, groupId, artifactId, version, e );
+                }
+                catch ( PluginManagerException e )
+                {
+                    throw new ExtensionManagerException( "Failed to resolve extension plugin: " + pluginArtifact, pluginArtifact, groupId, artifactId, version, e );
+                }
+                catch ( PluginVersionNotFoundException e )
+                {
+                    throw new ExtensionManagerException( "Failed to resolve extension plugin: " + pluginArtifact, pluginArtifact, groupId, artifactId, version, e );
+                }
+
+                try
+                {
+                    realmManager.createExtensionRealm( pluginArtifact, pd.getArtifacts() );
+                }
+                catch ( RealmManagementException e )
+                {
+                    String projectId = RealmUtils.createProjectId( groupId, artifactId, version );
+                    throw new ExtensionManagerException( "Unable to create extension ClassRealm for extension: " + pluginArtifact.getId() + " within session for project: " + projectId, pluginArtifact, groupId, artifactId, version, e );
+                }
+            }
+
+            try
+            {
+                realmManager.importExtensionsIntoProjectRealm( groupId, artifactId, version, pluginArtifact );
+            }
+            catch ( RealmManagementException e )
+            {
+                throw new ExtensionManagerException( "Unable to import extension components into project realm.", pluginArtifact, groupId, artifactId, version, e );
+            }
+        }
     }
 
     public void addExtension( Extension extension,
                               MavenProject project,
-                              ArtifactRepository localRepository )
+                              MavenExecutionRequest request )
         throws ExtensionManagerException
     {
         String extensionId = ArtifactUtils.versionlessKey( extension.getGroupId(), extension.getArtifactId() );
@@ -164,219 +271,118 @@
         addExtension( artifact,
                       project.getArtifact(),
                       project.getRemoteArtifactRepositories(),
-                      localRepository,
+                      request,
                       new ActiveArtifactResolver( project ),
-                      MavenProjectSession.createProjectId( project.getGroupId(), project.getArtifactId(), project.getVersion() )  );
-    }
-
-    private String createExtensionRealmId( Artifact realmArtifact )
-    {
-        return "/extensions/" + ArtifactUtils.versionlessKey( realmArtifact );
+                      project.getGroupId(),
+                      project.getArtifactId(),
+                      project.getVersion() );
     }
 
     private void addExtension( Artifact extensionArtifact,
                                Artifact projectArtifact,
                                List remoteRepositories,
-                               ArtifactRepository localRepository,
+                               MavenExecutionRequest request,
                                ActiveArtifactResolver activeArtifactResolver,
-                               String projectId )
+                               String projectGroupId,
+                               String projectArtifactId,
+                               String projectVersion )
         throws ExtensionManagerException
     {
         getLogger().debug( "Starting extension-addition process for: " + extensionArtifact );
 
         ArtifactFilter coreFilter = artifactFilterManager.getArtifactFilter();
+        MavenRealmManager realmManager = request.getRealmManager();
 
         // if the extension is null,
-        // if it's already been added to the current project-session,
         // or if it's excluded by the core filter,
         //
         // skip it.
         if ( ( extensionArtifact != null )
              && coreFilter.include( extensionArtifact ) )
         {
-            String realmId = createExtensionRealmId( extensionArtifact );
-            try
+            if ( !realmManager.hasExtensionRealm( extensionArtifact ) )
             {
-                container.getClassWorld().getRealm( realmId );
+                ArtifactFilter filter =
+                    new ProjectArtifactExceptionFilter( coreFilter, projectArtifact );
 
-                // if we find the realm, we don't need to proceed, we've already added this extension.
-                return;
-            }
-            catch ( NoSuchRealmException e )
-            {
-                // proceed.
-            }
+                ResolutionGroup resolutionGroup;
 
-            ArtifactFilter filter =
-                new ProjectArtifactExceptionFilter( coreFilter, projectArtifact );
+                ArtifactRepository localRepository = request.getLocalRepository();
 
-            ResolutionGroup resolutionGroup;
-
-            try
-            {
-                resolutionGroup = artifactMetadataSource.retrieve( extensionArtifact, localRepository, remoteRepositories );
-            }
-            catch ( ArtifactMetadataRetrievalException e )
-            {
-                throw new ExtensionManagerException( "Unable to download metadata from repository for extension artifact '" +
-                    extensionArtifact.getId() + "': " + e.getMessage(), extensionArtifact, projectId, e );
-            }
+                try
+                {
+                    resolutionGroup = artifactMetadataSource.retrieve( extensionArtifact, localRepository, remoteRepositories );
+                }
+                catch ( ArtifactMetadataRetrievalException e )
+                {
+                    throw new ExtensionManagerException( "Unable to download metadata from repository for extension artifact '" +
+                        extensionArtifact.getId() + "': " + e.getMessage(), extensionArtifact, projectGroupId, projectArtifactId, projectVersion, e );
+                }
 
-            // We use the same hack here to make sure that plexus 1.1 is available for extensions that do
-            // not declare plexus-utils but need it. MNG-2900
-//            DefaultPluginManager.checkPlexusUtils( resolutionGroup, artifactFactory );
-
-            Set dependencies = new LinkedHashSet();
-
-            dependencies.add( extensionArtifact );
-            dependencies.addAll( resolutionGroup.getArtifacts() );
-
-            ArtifactResolutionRequest dependencyReq = new ArtifactResolutionRequest().setArtifact( projectArtifact )
-                                                                           .setArtifactDependencies( dependencies )
-                                                                           .setFilter( filter )
-                                                                           .setLocalRepository( localRepository )
-                                                                           .setRemoteRepostories( remoteRepositories )
-                                                                           .setMetadataSource( artifactMetadataSource );
+                // We use the same hack here to make sure that plexus 1.1 is available for extensions that do
+                // not declare plexus-utils but need it. MNG-2900
+//                DefaultPluginManager.checkPlexusUtils( resolutionGroup, artifactFactory );
+
+                Set dependencies = new LinkedHashSet();
+
+                dependencies.add( extensionArtifact );
+                dependencies.addAll( resolutionGroup.getArtifacts() );
+
+                ArtifactResolutionRequest dependencyReq = new ArtifactResolutionRequest().setArtifact( projectArtifact )
+                                                                               .setArtifactDependencies( dependencies )
+                                                                               .setFilter( filter )
+                                                                               .setLocalRepository( localRepository )
+                                                                               .setRemoteRepostories( remoteRepositories )
+                                                                               .setMetadataSource( artifactMetadataSource );
 
-            // TODO: Make this work with managed dependencies, or an analogous management section in the POM.
-            ArtifactResolutionResult result = artifactResolver.resolve( dependencyReq );
+                // TODO: Make this work with managed dependencies, or an analogous management section in the POM.
+                ArtifactResolutionResult result = artifactResolver.resolve( dependencyReq );
 
-            if ( result.hasCircularDependencyExceptions() || result.hasErrorArtifactExceptions()
-                 || result.hasMetadataResolutionExceptions() || result.hasVersionRangeViolations() )
-            {
-                throw new ExtensionManagerException( "Failed to resolve extension: " + extensionArtifact, extensionArtifact, projectId, result );
-            }
+                if ( result.hasCircularDependencyExceptions() || result.hasErrorArtifactExceptions()
+                     || result.hasMetadataResolutionExceptions() || result.hasVersionRangeViolations() )
+                {
+                    throw new ExtensionManagerException( "Failed to resolve extension: " + extensionArtifact, extensionArtifact, projectGroupId, projectArtifactId, projectVersion, result );
+                }
 
-            Set resultArtifacts = result.getArtifacts();
+                Set resultArtifacts = new LinkedHashSet();
+                for ( Iterator iterator = result.getArtifacts().iterator(); iterator.hasNext(); )
+                {
+                    Artifact a = (Artifact) iterator.next();
 
-            if ( !extensionArtifact.isResolved() || ( extensionArtifact.getFile() == null ) )
-            {
-                throw new ExtensionManagerException( "Extension artifact was not resolved, or has no file associated with it.", extensionArtifact, projectId );
-            }
 
-            ClassRealm extensionRealm;
-            try
-            {
-                extensionRealm = container.getContainerRealm().createChildRealm( realmId );
-            }
-            catch ( DuplicateRealmException e )
-            {
-                throw new ExtensionManagerException( "Unable to create extension ClassRealm for extension: " + extensionArtifact.getId() + " within session for project: " + projectId, extensionArtifact, projectId, e );
-            }
+                    if ( activeArtifactResolver != null )
+                    {
+                        a = activeArtifactResolver.replaceWithActiveArtifact( a );
+                    }
 
-            for ( Iterator i = resultArtifacts.iterator(); i.hasNext(); )
-            {
-                Artifact a = (Artifact) i.next();
+                    getLogger().debug( "Adding: " + a.getFile() + " to classpath for extension: " + extensionArtifact.getId() );
+                    resultArtifacts.add( a );
+                }
 
-                if ( activeArtifactResolver != null )
+                // TODO: This shouldn't be required, now that we're checking the core filter before getting here.
+                if ( !extensionArtifact.isResolved() || ( extensionArtifact.getFile() == null ) )
                 {
-                    a = activeArtifactResolver.replaceWithActiveArtifact( a );
+                    throw new ExtensionManagerException( "Extension artifact was not resolved, or has no file associated with it.", extensionArtifact, projectGroupId, projectArtifactId, projectVersion );
                 }
 
-                getLogger().debug( "Adding to extension classpath: " + a.getFile() + " in classRealm: " + extensionRealm.getId() );
-
                 try
                 {
-                    extensionRealm.addURL( a.getFile().toURL() );
+                    realmManager.createExtensionRealm( extensionArtifact, resultArtifacts );
                 }
-                catch ( MalformedURLException e )
+                catch ( RealmManagementException e )
                 {
-                    throw new ExtensionManagerException( "Unable to generate URL from extension artifact file: " + a.getFile(), extensionArtifact, projectId, e );
+                    String projectId = RealmUtils.createProjectId( projectGroupId, projectArtifactId, projectVersion );
+                    throw new ExtensionManagerException( "Unable to create extension ClassRealm for extension: " + extensionArtifact.getId() + " within session for project: " + projectId, extensionArtifact, projectGroupId, projectArtifactId, projectVersion, e );
                 }
             }
 
-            importLocalExtensionComponents( extensionRealm, projectId, extensionArtifact );
-        }
-    }
-
-    private void importLocalExtensionComponents( ClassRealm extensionRealm,
-                                                 String projectId,
-                                                 Artifact extensionArtifact )
-        throws ExtensionManagerException
-    {
-        ClassWorld discoveryWorld = new ClassWorld();
-        try
-        {
-            // Create an entire new ClassWorld, ClassRealm for discovering
-            // the immediate components of the extension artifact, so we don't pollute the
-            // container with component descriptors or realms that don't have any meaning beyond discovery.
-            ClassRealm discoveryRealm = new ClassRealm( discoveryWorld, "discovery", Thread.currentThread().getContextClassLoader() );
             try
             {
-                discoveryRealm.addURL( extensionArtifact.getFile().toURL() );
-            }
-            catch ( MalformedURLException e )
-            {
-                throw new ExtensionManagerException( "Unable to generate URL from extension artifact for local-component discovery: " + extensionArtifact.getFile(), extensionArtifact, projectId, e );
-            }
-
-            ComponentDiscoverer discoverer = new DefaultComponentDiscoverer();
-            discoverer.setManager( new DummyDiscovererManager() );
-
-            ClassRealm realm = container.getContainerRealm();
-            try
-            {
-                // Find the extension component descriptors that exist ONLY in the immediate extension
-                // artifact...this prevents us from adding plexus-archiver components to the mix, for instance,
-                // when the extension uses that dependency.
-                List componentSetDescriptors = discoverer.findComponents( container.getContext(), discoveryRealm );
-                for ( Iterator it = componentSetDescriptors.iterator(); it.hasNext(); )
-                {
-                    ComponentSetDescriptor compSet = (ComponentSetDescriptor) it.next();
-                    for ( Iterator compIt = compSet.getComponents().iterator(); compIt.hasNext(); )
-                    {
-                        // For each component in the extension artifact:
-                        ComponentDescriptor comp = (ComponentDescriptor) compIt.next();
-                        String implementation = comp.getImplementation();
-
-                        try
-                        {
-                            getLogger().debug( "Importing: " + implementation + "\nwith role: " + comp.getRole() + "\nand hint: " + comp.getRoleHint() + "\nfrom extension realm: " + extensionRealm.getId() + "\nto container realm: " + realm.getId() );
-
-                            // Import the extension component's implementation class into the project-level
-                            // realm.
-                            realm.importFrom( extensionRealm.getId(), implementation );
-
-                            // Set the realmId to be used in looking up this extension component to the
-                            // project-level realm, since we now have a restricted import
-                            // that allows most of the extension to stay hidden, and the
-                            // specific local extension components are still accessible
-                            // from the project-level realm.
-                            comp.setRealmId( realm.getId() );
-
-                            // Finally, add the extension component's descriptor (with projectRealm
-                            // set as the lookup realm) to the container.
-                            container.addComponentDescriptor( comp );
-                        }
-                        catch ( NoSuchRealmException e )
-                        {
-                            throw new ExtensionManagerException( "Failed to create import for component: " + implementation + " from extension realm: " + extensionRealm.getId() + " to project realm: " + realm.getId(), extensionArtifact, projectId, e );
-                        }
-                    }
-                }
-            }
-            catch ( PlexusConfigurationException e )
-            {
-                throw new ExtensionManagerException( "Unable to discover extension components.", extensionArtifact, projectId, e );
+                realmManager.importExtensionsIntoProjectRealm( projectGroupId, projectArtifactId, projectVersion, extensionArtifact );
             }
-            catch ( ComponentRepositoryException e )
+            catch ( RealmManagementException e )
             {
-                throw new ExtensionManagerException( "Unable to discover extension components from imports added to project-session realm.", extensionArtifact, projectId, e );
-            }
-        }
-        finally
-        {
-            Collection realms = discoveryWorld.getRealms();
-            for ( Iterator it = realms.iterator(); it.hasNext(); )
-            {
-                ClassRealm realm = (ClassRealm) it.next();
-                try
-                {
-                    discoveryWorld.disposeRealm( realm.getId() );
-                }
-                catch ( NoSuchRealmException e )
-                {
-                }
+                throw new ExtensionManagerException( "Unable to import extension components into project realm.", extensionArtifact, projectGroupId, projectArtifactId, projectVersion, e );
             }
         }
     }
@@ -477,41 +483,5 @@
                                                                                 "plexus-utils", "1.1",
                                                                                 Artifact.SCOPE_RUNTIME, "jar" ) );
         }
-    }
-
-    private static final class DummyDiscovererManager implements ComponentDiscovererManager
-    {
-
-        public void fireComponentDiscoveryEvent( ComponentDiscoveryEvent arg0 )
-        {
-        }
-
-        public List getComponentDiscoverers()
-        {
-            return null;
-        }
-
-        public Map getComponentDiscoveryListeners()
-        {
-            return null;
-        }
-
-        public List getListeners()
-        {
-            return null;
-        }
-
-        public void initialize()
-        {
-        }
-
-        public void registerComponentDiscoveryListener( ComponentDiscoveryListener arg0 )
-        {
-        }
-
-        public void removeComponentDiscoveryListener( ComponentDiscoveryListener arg0 )
-        {
-        }
-
     }
 }

Modified: maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/ExtensionManager.java
URL: http://svn.apache.org/viewvc/maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/ExtensionManager.java?rev=591391&r1=591390&r2=591391&view=diff
==============================================================================
--- maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/ExtensionManager.java (original)
+++ maven/components/trunk/maven-core/src/main/java/org/apache/maven/extension/ExtensionManager.java Fri Nov  2 09:44:00 2007
@@ -19,7 +19,7 @@
  * under the License.
  */
 
-import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.execution.MavenExecutionRequest;
 import org.apache.maven.model.Extension;
 import org.apache.maven.model.Model;
 import org.apache.maven.project.MavenProject;
@@ -34,12 +34,12 @@
  */
 public interface ExtensionManager
 {
-    void addExtension( Extension extension, MavenProject project, ArtifactRepository localRepository )
+    void addExtension( Extension extension, MavenProject project, MavenExecutionRequest request )
         throws ExtensionManagerException;
 
     void registerWagons();
 
     void addExtension( Extension extension, Model originatingModel, List remoteRepositories,
-                       ArtifactRepository localRepository )
+                       MavenExecutionRequest request )
         throws ExtensionManagerException;
 }