From 0d32e6cc4a5b2fea5eff579840762fde38adca8d Mon Sep 17 00:00:00 2001 From: John Dennis Casey Date: Fri, 19 Oct 2007 17:13:20 +0000 Subject: [PATCH] some documentation for new extension and project-level session stuff, and trying a fix for the extension manager test that may help things on windows where forceDelete(..) fails. git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@586543 13f79535-47bb-0310-9956-ffa450edef68 --- .../maven/execution/MavenProjectSession.java | 43 ++++++++++++++++++- .../extension/DefaultExtensionManager.java | 21 +++++++++ .../DefaultExtensionManagerTest.java | 7 ++- 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/execution/MavenProjectSession.java b/maven-core/src/main/java/org/apache/maven/execution/MavenProjectSession.java index 7a99be0f8c..70cf4bfe77 100644 --- a/maven-core/src/main/java/org/apache/maven/execution/MavenProjectSession.java +++ b/maven-core/src/main/java/org/apache/maven/execution/MavenProjectSession.java @@ -14,6 +14,26 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +/** + * Project-level session that stores extension and plugin realms for the project + * with the specified projectId (groupId, artifactId, and version). The projectId + * is the key here, not the project instance, since this session may be constructed + * before the MavenProject instance has been created, in order to pre-scan for + * extensions that may alter the project instance when it is constructed (using + * custom profile activators, for instance). + * + * The {@link MavenProjectSession#getProjectRealm()} method is used in many cases + * as the lookup realm when the project associated with this session is active, + * as in the lifecycle executor. In other cases, where a plugin itself is being + * executed, the {@link MavenProjectSession#getPluginRealm(Plugin)} and + * {@link MavenProjectSession#getPluginRealm(PluginDescriptor)} methods allow for + * retrieval of the {@link ClassRealm} instance - linked to this project - which + * contains the plugin classes...in these cases, the plugin realm is used as + * the lookupRealm. + * + * @author jdcasey + * + */ public class MavenProjectSession { @@ -50,7 +70,7 @@ public class MavenProjectSession return componentRealms.containsKey( id ); } - public boolean containsRealm( Plugin plugin ) + public boolean containsPluginRealm( Plugin plugin ) { String realmId = createPluginRealmId( ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() ) ); @@ -62,6 +82,17 @@ public class MavenProjectSession return projectRealm; } + /** + * Creates a new ClassRealm for the given extension artifact. This realm + * will be a child realm of the container passed to this instance in the + * constructor, and does not inherit from the project realm. This is important, + * since the project realm will eventually import certain extension + * component classes from the realm resulting from this call. + * + * @param extensionArtifact + * @return + * @throws DuplicateRealmException + */ public ClassRealm createExtensionRealm( Artifact extensionArtifact ) throws DuplicateRealmException { @@ -73,6 +104,16 @@ public class MavenProjectSession return extRealm; } + /** + * Create a projectId for use in the {@link MavenProjectSession} constructor + * and lookup (from inside {@link MavenSession} currently). This method provides + * a standard way of forming that id. + * + * @param groupId + * @param artifactId + * @param version + * @return + */ public static String createProjectId( String groupId, String artifactId, String version ) diff --git a/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java b/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java index 3ada793d25..ea8f68ba16 100644 --- a/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java +++ b/maven-core/src/main/java/org/apache/maven/extension/DefaultExtensionManager.java @@ -188,6 +188,10 @@ public class DefaultExtensionManager { getLogger().debug( "Starting extension-addition process for: " + extensionArtifact ); + // create a new MavenProjectSession instance for the current project. + // This session instance will house the plugin and extension realms that + // pertain to this specific project, along with containing the project-level + // realm to use as a lookupRealm in the lifecycle executor and plugin manager. MavenProjectSession projectSession = (MavenProjectSession) projectSessions.get( projectId ); if ( projectSession == null ) { @@ -288,6 +292,9 @@ public class DefaultExtensionManager { String projectId = projectSession.getProjectId(); + // 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( new ClassWorld(), "discovery", Thread.currentThread().getContextClassLoader() ); try { @@ -304,12 +311,16 @@ public class DefaultExtensionManager ClassRealm projectRealm = projectSession.getProjectRealm(); 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(); @@ -317,9 +328,19 @@ public class DefaultExtensionManager { getLogger().debug( "Importing: " + implementation + "\nwith role: " + comp.getRole() + "\nand hint: " + comp.getRoleHint() + "\nfrom extension realm: " + extensionRealm.getId() + "\nto project realm: " + projectRealm.getId() ); + // Import the extension component's implementation class into the project-level + // realm. projectRealm.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( projectRealm.getId() ); + + // Finally, add the extension component's descriptor (with projectRealm + // set as the lookup realm) to the container. container.addComponentDescriptor( comp ); } catch ( NoSuchRealmException e ) diff --git a/maven-core/src/test/java/org/apache/maven/extension/DefaultExtensionManagerTest.java b/maven-core/src/test/java/org/apache/maven/extension/DefaultExtensionManagerTest.java index bcd3a89a41..32a393b506 100644 --- a/maven-core/src/test/java/org/apache/maven/extension/DefaultExtensionManagerTest.java +++ b/maven-core/src/test/java/org/apache/maven/extension/DefaultExtensionManagerTest.java @@ -81,7 +81,12 @@ public class DefaultExtensionManagerTest if ( f.exists() ) { - FileUtils.forceDelete( f ); + File f2 = File.createTempFile( "preDeleteRename.", "" ); + + f2.delete(); + f.renameTo( f2 ); + + FileUtils.forceDelete( f2 ); } } }