diff --git a/maven-build-context/pom.xml b/maven-build-context/pom.xml new file mode 100644 index 0000000000..9fc5ba3127 --- /dev/null +++ b/maven-build-context/pom.xml @@ -0,0 +1,25 @@ + + 4.0.0 + + + maven + org.apache.maven + 2.1-SNAPSHOT + + + maven-build-context + Maven Build Context + + + + org.codehaus.plexus + plexus-container-default + + + junit + junit + 3.8.1 + test + + + diff --git a/maven-build-context/src/main/java/org/apache/maven/context/BuildContext.java b/maven-build-context/src/main/java/org/apache/maven/context/BuildContext.java new file mode 100644 index 0000000000..6c9cc36d3a --- /dev/null +++ b/maven-build-context/src/main/java/org/apache/maven/context/BuildContext.java @@ -0,0 +1,34 @@ +package org.apache.maven.context; + +/** + * Basic data bus for Maven builds, through which the various subsystems can communicate with one + * another without causing bloat in the APIs. + * + * @author jdcasey + * + */ +public interface BuildContext +{ + + /** + * Add a new piece of data to the build context. + */ + void put( Object key, Object value ); + + /** + * Retrieve something previously stored in the build context, or null if the key doesn't exist. + */ + Object get( Object key ); + + /** + * Remove a mapped data element from the build context, returning the Object removed, if any. + */ + Object delete( Object key ); + + /** + * Add a new piece of managed build data to the build context. Managed data elements supply their + * own storage key. + */ + void put( ManagedBuildData managedData ); + +} diff --git a/maven-build-context/src/main/java/org/apache/maven/context/BuildContextManager.java b/maven-build-context/src/main/java/org/apache/maven/context/BuildContextManager.java new file mode 100644 index 0000000000..1567ec096e --- /dev/null +++ b/maven-build-context/src/main/java/org/apache/maven/context/BuildContextManager.java @@ -0,0 +1,34 @@ +package org.apache.maven.context; + +/** + * Manager interface used to store, read, and clear the BuildContext out of the container. + * + * @author jdcasey + */ +public interface BuildContextManager +{ + + String ROLE = BuildContextManager.class.getName(); + + /** + * Create a new instance of BuildContext + */ + BuildContext newUnstoredInstance(); + + /** + * Read the BuildContext from the container. If it doesn't already exist, optionally create it. + */ + BuildContext readBuildContext( boolean create ); + + /** + * Store the BuildContext in the container context. + */ + void storeBuildContext( BuildContext context ); + + /** + * Clear the contents of the BuildContext, both in the current instance, and in the container + * context. + */ + void clearBuildContext(); + +} diff --git a/maven-build-context/src/main/java/org/apache/maven/context/DefaultBuildContext.java b/maven-build-context/src/main/java/org/apache/maven/context/DefaultBuildContext.java new file mode 100644 index 0000000000..f8834f6816 --- /dev/null +++ b/maven-build-context/src/main/java/org/apache/maven/context/DefaultBuildContext.java @@ -0,0 +1,85 @@ +package org.apache.maven.context; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * Default implementation of BuildContext, for use with the DefaultBuildContextManager. This + * implementation uses a Map for its backing store, and if constructed with no parameters, will use + * a LinkedHashMap. + * + * @author jdcasey + * + */ +public class DefaultBuildContext + implements BuildContext +{ + + private final Map contextMap; + + /** + * Construct a new build context, using the supplied map as the backing store. NOTE: The + * supplied map will be copied. + */ + public DefaultBuildContext( Map contextMap ) + { + if ( contextMap == null ) + { + throw new NullPointerException( "DefaultBuildContext requires a non-null contextMap parameter, or no parameter at all." ); + } + + this.contextMap = contextMap; + } + + /** + * Construct a new build context, using a new instance of LinkedHashMap. + */ + public DefaultBuildContext() + { + this.contextMap = new LinkedHashMap(); + } + + /** + * Remove the object mapped to 'key' from the build context. If there was such a mapping, return + * the value mapped to the key. + */ + public Object delete( Object key ) + { + return contextMap.remove( key ); + } + + /** + * Retrieve the object mapped to 'key', or null if the mapping doesn't exist. Mapping 'key' to + * null should also be possible, but will be indistinguishable from a missing mapping. + */ + public Object get( Object key ) + { + return contextMap.get( key ); + } + + /** + * Add a new data mapping to the build context. + */ + public void put( Object key, Object value ) + { + contextMap.put( key, value ); + } + + /** + * Return the Map used to store data elements, for storage by the DefaultBuildContextManager. + */ + Object getContextMap() + { + return contextMap; + } + + /** + * Add a new piece of managed data to the build context, using the key supplied by + * managedData.getStorageKey(). + */ + public void put( ManagedBuildData managedData ) + { + contextMap.put( managedData.getStorageKey(), managedData ); + } + +} diff --git a/maven-build-context/src/main/java/org/apache/maven/context/DefaultBuildContextManager.java b/maven-build-context/src/main/java/org/apache/maven/context/DefaultBuildContextManager.java new file mode 100644 index 0000000000..ee2fd2ed81 --- /dev/null +++ b/maven-build-context/src/main/java/org/apache/maven/context/DefaultBuildContextManager.java @@ -0,0 +1,121 @@ +package org.apache.maven.context; + +import org.codehaus.plexus.context.Context; +import org.codehaus.plexus.context.ContextException; +import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable; + +import java.util.HashMap; +import java.util.Map; + +/** + * Default implementation of the BuildContextManager, which handles instances of DefaultBuildContext. + * + * @plexus.component role="org.apache.maven.context.BuildContextManager" role-hint="default" + * @author jdcasey + */ +public class DefaultBuildContextManager + implements BuildContextManager, Contextualizable +{ + public static final String ROLE_HINT = "default"; + + protected static final String BUILD_CONTEXT_MAP_KEY = "org.apache.maven.context:DefaultBuildContextManager:contextMap"; + + private Context context; + + /** + * Create a new instance of DefaultBuildContext, and return it. Each method call creates a brand + * new instance. + */ + public BuildContext newUnstoredInstance() + { + return new DefaultBuildContext(); + } + + /** + * Clear the contents of the build context inside the container context. + */ + public void clearBuildContext() + { + clearContextContainerMap(); + } + + /** + * Retrieve the current BuildContext out of the container context. + * + * @param create Whether to create the BuildContext if it doesn't exist in the container + */ + public BuildContext readBuildContext( boolean create ) + { + Map contextMap = getContextContainerMap( create ); + + if ( !create && contextMap == null ) + { + return null; + } + else + { + return new DefaultBuildContext( contextMap ); + } + } + + /** + * Store the given BuildContext inside the container. + */ + public void storeBuildContext( BuildContext context ) + { + if ( context instanceof DefaultBuildContext ) + { + this.context.put( BUILD_CONTEXT_MAP_KEY, ((DefaultBuildContext)context).getContextMap() ); + } + else + { + throw new IllegalArgumentException( this.getClass().getName() + " does not know how to store a context of type: " + context.getClass().getName() ); + } + } + + protected Map getContextContainerMap( boolean create ) + { + Map containerMap = null; + + if ( context.contains( BUILD_CONTEXT_MAP_KEY ) ) + { + try + { + containerMap = (Map) context.get( BUILD_CONTEXT_MAP_KEY ); + } + catch ( ContextException e ) + { + throw new IllegalStateException( "Failed to retrieve BuildAdvisor " + + "serialization map from context, though the context claims it exists. Error: " + + e.getMessage() ); + } + } + else if ( create ) + { + containerMap = new HashMap(); + context.put( BUILD_CONTEXT_MAP_KEY, containerMap ); + } + + return containerMap; + } + + protected void clearContextContainerMap() + { + Map containerMap = getContextContainerMap( false ); + + if ( containerMap != null ) + { + containerMap.clear(); + } + } + + /** + * Retrieve the container context for storing the BuildContext data. + */ + public void contextualize( Context context ) + throws ContextException + { + this.context = context; + } + +} diff --git a/maven-build-context/src/main/java/org/apache/maven/context/ManagedBuildData.java b/maven-build-context/src/main/java/org/apache/maven/context/ManagedBuildData.java new file mode 100644 index 0000000000..bd6fbc438b --- /dev/null +++ b/maven-build-context/src/main/java/org/apache/maven/context/ManagedBuildData.java @@ -0,0 +1,21 @@ +package org.apache.maven.context; + +/** + * Management interface for things that are meant to be stored/retrieved from the Maven BuildContext + * natively. Such things need to give the BuildContextManager a key for mapping it into the context. + * + * @author jdcasey + * + */ +public interface ManagedBuildData +{ + + /** + * Retrieve the context key under which this instance of managed data should be stored in the + * BuildContext instance. + * + * @return The BuildContext mapping key. + */ + String getStorageKey(); + +} diff --git a/maven-build-context/src/main/java/org/apache/maven/context/SystemBuildContext.java b/maven-build-context/src/main/java/org/apache/maven/context/SystemBuildContext.java new file mode 100644 index 0000000000..a24b370172 --- /dev/null +++ b/maven-build-context/src/main/java/org/apache/maven/context/SystemBuildContext.java @@ -0,0 +1,76 @@ +package org.apache.maven.context; + +import java.util.Properties; + +public class SystemBuildContext + implements ManagedBuildData +{ + + public static final String BUILD_CONTEXT_KEY = SystemBuildContext.class.getName(); + + private Properties systemProperties; + private Properties envars; + + public SystemBuildContext() + { + this.systemProperties = System.getProperties(); + } + + public void setEnvironmentVariables( Properties envars ) + { + this.envars = envars; + } + + public Properties getEnvironmentVariables() + { + return envars; + } + + public void setSystemProperties( Properties systemProperties ) + { + this.systemProperties = systemProperties; + } + + public Properties getSystemProperties() + { + return systemProperties; + } + + public String getSystemProperty( String name ) + { + return systemProperties == null ? null : systemProperties.getProperty( name ); + } + + public String getStorageKey() + { + return BUILD_CONTEXT_KEY; + } + + public static SystemBuildContext getSystemBuildContext( BuildContextManager buildContextManager, boolean create ) + { + BuildContext buildContext = buildContextManager.readBuildContext( false ); + + SystemBuildContext systemContext = null; + + if ( buildContext != null ) + { + systemContext = (SystemBuildContext) buildContext.get( BUILD_CONTEXT_KEY ); + } + + if ( create && systemContext == null ) + { + systemContext = new SystemBuildContext(); + } + + return systemContext; + } + + public void store( BuildContextManager buildContextManager ) + { + BuildContext buildContext = buildContextManager.readBuildContext( true ); + + buildContext.put( this ); + + buildContextManager.storeBuildContext( buildContext ); + } +} diff --git a/maven-build-context/src/main/resources/META-INF/plexus/components.xml b/maven-build-context/src/main/resources/META-INF/plexus/components.xml new file mode 100644 index 0000000000..657f19d564 --- /dev/null +++ b/maven-build-context/src/main/resources/META-INF/plexus/components.xml @@ -0,0 +1,9 @@ + + + + org.apache.maven.context.BuildContextManager + default + org.apache.maven.context.DefaultBuildContextManager + + + \ No newline at end of file diff --git a/maven-build-context/src/test/java/org/apache/maven/context/AbstractBuildContextManagerTest.java b/maven-build-context/src/test/java/org/apache/maven/context/AbstractBuildContextManagerTest.java new file mode 100644 index 0000000000..3fd59657e0 --- /dev/null +++ b/maven-build-context/src/test/java/org/apache/maven/context/AbstractBuildContextManagerTest.java @@ -0,0 +1,93 @@ +package org.apache.maven.context; + +import org.codehaus.plexus.PlexusTestCase; + +public abstract class AbstractBuildContextManagerTest + extends PlexusTestCase +{ + private BuildContextManager mgr; + + protected abstract String getRoleHintBeforeSetUp(); + + protected BuildContextManager getBuildContextManager() + { + return mgr; + } + + public void setUp() throws Exception + { + super.setUp(); + + mgr = (BuildContextManager) lookup( BuildContextManager.ROLE, getRoleHintBeforeSetUp() ); + } + + public void testNewUnstoredInstance_ShouldReturnValidContextInstance() + { + BuildContext context = mgr.newUnstoredInstance(); + + assertNotNull( context ); + + String key = "key"; + String value = "value"; + + context.put( key, value ); + + assertEquals( value, context.get( key ) ); + + context.delete( key ); + + assertNull( context.get( key ) ); + } + + public void testNewUnstoredInstance_SuccessiveCallsShouldReturnDistinctContextInstances() + { + BuildContext context = mgr.newUnstoredInstance(); + BuildContext context2 = mgr.newUnstoredInstance(); + + assertNotNull( context ); + assertNotNull( context2 ); + assertNotSame( context, context2 ); + } + + public void testStoreAndRead_ShouldRetrieveStoredValueAfterRead() + { + BuildContext ctx = mgr.newUnstoredInstance(); + + String key = "key"; + String value = "value"; + + ctx.put( key, value ); + + mgr.storeBuildContext( ctx ); + + BuildContext ctx2 = mgr.readBuildContext( false ); + + assertNotNull( ctx2 ); + assertEquals( value, ctx2.get( key ) ); + } + + public void testStoreAndClear_ShouldNotRetrieveStoredValueAfterClear() + { + BuildContext ctx = mgr.newUnstoredInstance(); + + String key = "key"; + String value = "value"; + + ctx.put( key, value ); + + mgr.storeBuildContext( ctx ); + + // verify that we can get the value back out. + BuildContext ctx2 = mgr.readBuildContext( false ); + + assertNotNull( ctx2 ); + assertEquals( value, ctx2.get( key ) ); + + mgr.clearBuildContext(); + + BuildContext ctx3 = mgr.readBuildContext( false ); + + assertNull( ctx3.get( key ) ); + } + +} diff --git a/maven-build-context/src/test/java/org/apache/maven/context/AbstractBuildContextTest.java b/maven-build-context/src/test/java/org/apache/maven/context/AbstractBuildContextTest.java new file mode 100644 index 0000000000..4727d241bb --- /dev/null +++ b/maven-build-context/src/test/java/org/apache/maven/context/AbstractBuildContextTest.java @@ -0,0 +1,61 @@ +package org.apache.maven.context; + +import java.util.HashMap; +import java.util.Map; + +import junit.framework.TestCase; + +public abstract class AbstractBuildContextTest + extends TestCase +{ + + protected abstract BuildContext newContext(); + + public void testPutAndGet_ShouldStoreAndRetrieveKeyValuePairOfStrings() + { + BuildContext ctx = newContext(); + + String key = "key"; + String value = "value"; + + ctx.put( key, value ); + + assertEquals( value, ctx.get( key ) ); + } + + public void testPutAndGet_ShouldStoreAndRetrieveStringKeyWithMapValue() + { + BuildContext ctx = newContext(); + + String key = "key"; + Map value = new HashMap(); + + String key2 = "key2"; + String value2 = "value"; + + value.put( key2, value2 ); + + ctx.put( key, value ); + + assertSame( value, ctx.get( key ) ); + + assertEquals( value2, ((Map) ctx.get( key )).get( key2 ) ); + } + + public void testPutDeleteAndGet_ShouldStoreKeyValuePairDeleteThemAndRetrieveNull() + { + BuildContext ctx = newContext(); + + String key = "key"; + String value = "value"; + + ctx.put( key, value ); + + assertEquals( value, ctx.get( key ) ); + + ctx.delete( key ); + + assertNull( ctx.get( key ) ); + } + +} diff --git a/maven-build-context/src/test/java/org/apache/maven/context/DefaultBuildContextManagerTest.java b/maven-build-context/src/test/java/org/apache/maven/context/DefaultBuildContextManagerTest.java new file mode 100644 index 0000000000..fa32d6b64d --- /dev/null +++ b/maven-build-context/src/test/java/org/apache/maven/context/DefaultBuildContextManagerTest.java @@ -0,0 +1,12 @@ +package org.apache.maven.context; + +public class DefaultBuildContextManagerTest + extends AbstractBuildContextManagerTest +{ + + protected String getRoleHintBeforeSetUp() + { + return DefaultBuildContextManager.ROLE_HINT; + } + +} diff --git a/maven-build-context/src/test/java/org/apache/maven/context/DefaultBuildContextTest.java b/maven-build-context/src/test/java/org/apache/maven/context/DefaultBuildContextTest.java new file mode 100644 index 0000000000..98c7a49cdb --- /dev/null +++ b/maven-build-context/src/test/java/org/apache/maven/context/DefaultBuildContextTest.java @@ -0,0 +1,40 @@ +package org.apache.maven.context; + +import java.util.Collections; +import java.util.Map; + +public class DefaultBuildContextTest + extends AbstractBuildContextTest +{ + + protected BuildContext newContext() + { + return new DefaultBuildContext(); + } + + public void testConstructor_ShouldThrowNPEWhenContextMapParameterIsNull() + { + try + { + new DefaultBuildContext( null ); + + fail( "Should throw NPE when contextMap parameter is null." ); + } + catch( NullPointerException e ) + { + // should happen. + } + } + + public void testConstructor_ShouldRetrieveValueFromPreExistingContextMap() + { + String key = "key"; + String value = "value"; + + Map contextMap = Collections.singletonMap( key, value ); + BuildContext ctx = new DefaultBuildContext( contextMap ); + + assertEquals( value, ctx.get( key ) ); + } + +} diff --git a/maven-core/pom.xml b/maven-core/pom.xml index c78dff3166..45f00ab94a 100644 --- a/maven-core/pom.xml +++ b/maven-core/pom.xml @@ -27,6 +27,11 @@ maven-core Maven Core + + org.apache.maven + maven-build-context + 2.1-SNAPSHOT + org.apache.maven maven-settings diff --git a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java index ef1a798b5c..85919fcf27 100644 --- a/maven-core/src/main/java/org/apache/maven/DefaultMaven.java +++ b/maven-core/src/main/java/org/apache/maven/DefaultMaven.java @@ -20,8 +20,11 @@ package org.apache.maven; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.resolver.ArtifactResolutionException; import org.apache.maven.artifact.versioning.DefaultArtifactVersion; +import org.apache.maven.context.BuildContextManager; +import org.apache.maven.context.SystemBuildContext; import org.apache.maven.execution.BuildFailure; import org.apache.maven.execution.DefaultMavenExecutionResult; +import org.apache.maven.execution.ExecutionBuildContext; import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenExecutionResult; import org.apache.maven.execution.MavenSession; @@ -74,6 +77,8 @@ public class DefaultMaven // Components // ---------------------------------------------------------------------- + protected BuildContextManager buildContextManager; + protected MavenProjectBuilder projectBuilder; protected LifecycleExecutor lifecycleExecutor; @@ -97,6 +102,8 @@ public class DefaultMaven public MavenExecutionResult execute( MavenExecutionRequest request ) { request.setStartTime( new Date() ); + + initializeBuildContext( request ); EventDispatcher dispatcher = new DefaultEventDispatcher( request.getEventMonitors() ); @@ -166,6 +173,21 @@ public class DefaultMaven return new DefaultMavenExecutionResult( result.getReactorManager() ); } + /** + * Initialize some context objects to be stored in the container's context map for reference by + * other Maven components (including custom components that need more information about the + * build than is supplied to them by the APIs). + */ + private void initializeBuildContext( MavenExecutionRequest request ) + { + new ExecutionBuildContext( request ).store( buildContextManager ); + + SystemBuildContext systemContext = SystemBuildContext.getSystemBuildContext( buildContextManager, true ); + + systemContext.setSystemProperties( request.getProperties() ); + systemContext.store( buildContextManager ); + } + private void logErrors( ReactorManager rm, boolean showErrors ) { @@ -304,17 +326,22 @@ public class DefaultMaven throws MavenExecutionException, BuildFailureException { List projects; + + List files; try { - List files = getProjectFiles( request ); - - projects = collectProjects( files, request.getLocalRepository(), request.isRecursive(), - request.getSettings(), globalProfileManager, !request.useReactor() ); - + files = getProjectFiles( request ); } catch ( IOException e ) { - throw new MavenExecutionException( "Error processing projects for the reactor: " + e.getMessage(), e ); + throw new MavenExecutionException( "Error selecting project files for the reactor: " + e.getMessage(), e ); + } + + try + { + projects = collectProjects( files, request.getLocalRepository(), request.isRecursive(), + request.getSettings(), globalProfileManager, !request.useReactor() ); + } catch ( ArtifactResolutionException e ) { diff --git a/maven-core/src/main/java/org/apache/maven/execution/ExecutionBuildContext.java b/maven-core/src/main/java/org/apache/maven/execution/ExecutionBuildContext.java new file mode 100644 index 0000000000..a75ab19e04 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/execution/ExecutionBuildContext.java @@ -0,0 +1,216 @@ +package org.apache.maven.execution; + +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.context.BuildContext; +import org.apache.maven.context.BuildContextManager; +import org.apache.maven.context.ManagedBuildData; +import org.apache.maven.settings.Settings; +import org.apache.maven.wagon.events.TransferListener; + +import java.io.File; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Properties; + +/* + * Copyright 2001-2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Build context object that supplies information about how Maven was invoked, including all of the + * information available in the MavenExecutionRequest (in read-only form). + */ +public class ExecutionBuildContext + implements ManagedBuildData +{ + + public static final String BUILD_CONTEXT_KEY = ExecutionBuildContext.class.getName(); + + private final MavenExecutionRequest request; + + public ExecutionBuildContext( MavenExecutionRequest request ) + { + this.request = request; + } + + public List getActiveProfiles() + { + return Collections.unmodifiableList( request.getActiveProfiles() ); + } + + public String getBaseDirectory() + { + return request.getBaseDirectory(); + } + + public String getGlobalChecksumPolicy() + { + return request.getGlobalChecksumPolicy(); + } + + public List getGoals() + { + return Collections.unmodifiableList( request.getGoals() ); + } + + public List getInactiveProfiles() + { + return Collections.unmodifiableList( request.getInactiveProfiles() ); + } + + public ArtifactRepository getLocalRepository() + { + return request.getLocalRepository(); + } + + public File getLocalRepositoryPath() + { + return request.getLocalRepositoryPath(); + } + + public int getLoggingLevel() + { + return request.getLoggingLevel(); + } + + public List getMirrors() + { + return Collections.unmodifiableList( request.getMirrors() ); + } + + public List getPluginGroups() + { + return Collections.unmodifiableList( request.getPluginGroups() ); + } + + public String getPomFile() + { + return request.getPomFile(); + } + + public List getProfiles() + { + return Collections.unmodifiableList( request.getProfiles() ); + } + + public Properties getProperties() + { + return new Properties( request.getProperties() ); + } + + public List getProxies() + { + return Collections.unmodifiableList( request.getProxies() ); + } + + public String getReactorFailureBehavior() + { + return request.getReactorFailureBehavior(); + } + + public List getServers() + { + return Collections.unmodifiableList( request.getServers() ); + } + + public Settings getSettings() + { + return request.getSettings(); + } + + public String getSettingsFile() + { + return request.getSettingsFile(); + } + + public Date getStartTime() + { + return request.getStartTime(); + } + + public TransferListener getTransferListener() + { + return request.getTransferListener(); + } + + public boolean isInteractiveMode() + { + return request.isInteractiveMode(); + } + + public boolean isNoSnapshotUpdates() + { + return request.isNoSnapshotUpdates(); + } + + public boolean isOffline() + { + return request.isOffline(); + } + + public boolean isRecursive() + { + return request.isRecursive(); + } + + public boolean isShowErrors() + { + return request.isShowErrors(); + } + + public boolean isUpdateSnapshots() + { + return request.isUpdateSnapshots(); + } + + public boolean isUsePluginRegistry() + { + return request.isUsePluginRegistry(); + } + + public boolean isUsePluginUpdateOverride() + { + return request.isUsePluginUpdateOverride(); + } + + public String getStorageKey() + { + return BUILD_CONTEXT_KEY; + } + + public static ExecutionBuildContext readExecutionBuildContext( BuildContextManager buildContextManager ) + { + BuildContext buildContext = buildContextManager.readBuildContext( false ); + + ExecutionBuildContext executionContext = null; + + if ( buildContext != null ) + { + executionContext = (ExecutionBuildContext) buildContext.get( BUILD_CONTEXT_KEY ); + } + + return executionContext; + } + + public void store( BuildContextManager buildContextManager ) + { + BuildContext buildContext = buildContextManager.readBuildContext( true ); + + buildContext.put( this ); + + buildContextManager.storeBuildContext( buildContext ); + } +} diff --git a/maven-core/src/main/resources/META-INF/plexus/components.xml b/maven-core/src/main/resources/META-INF/plexus/components.xml index 41bbd7e5c0..93dca1de8f 100644 --- a/maven-core/src/main/resources/META-INF/plexus/components.xml +++ b/maven-core/src/main/resources/META-INF/plexus/components.xml @@ -80,6 +80,10 @@ org.apache.maven.Maven org.apache.maven.DefaultMaven + + org.apache.maven.context.BuildContextManager + default + org.apache.maven.project.MavenProjectBuilder diff --git a/maven-model/maven.mdo b/maven-model/maven.mdo index c78a8d293d..40c2665b2e 100644 --- a/maven-model/maven.mdo +++ b/maven-model/maven.mdo @@ -2629,6 +2629,16 @@ ActivationFile + + custom + 4.0.0 + + Describes a custom profile activation trigger, brought in via build extension. + + + ActivationCustom + + @@ -2714,6 +2724,32 @@ + + ActivationCustom + 4.0.0 + + + + configuration + 4.0.0 + DOM + + + + type + 4.0.0 + String + + + + ReportPlugin diff --git a/maven-project/pom.xml b/maven-project/pom.xml index 31c0135ae6..c0e582df17 100755 --- a/maven-project/pom.xml +++ b/maven-project/pom.xml @@ -29,6 +29,11 @@ This library is used to not only read Maven project object model files, but to assemble inheritence and to retrieve remote models as required. + + org.apache.maven + maven-build-context + 2.1-SNAPSHOT + org.apache.maven maven-artifact-test diff --git a/maven-project/src/main/java/org/apache/maven/profiles/activation/CustomActivator.java b/maven-project/src/main/java/org/apache/maven/profiles/activation/CustomActivator.java new file mode 100644 index 0000000000..94cfb1a6f2 --- /dev/null +++ b/maven-project/src/main/java/org/apache/maven/profiles/activation/CustomActivator.java @@ -0,0 +1,137 @@ +package org.apache.maven.profiles.activation; + +import org.apache.maven.model.Activation; +import org.apache.maven.model.ActivationCustom; +import org.apache.maven.model.Profile; +import org.codehaus.plexus.PlexusConstants; +import org.codehaus.plexus.PlexusContainer; +import org.codehaus.plexus.component.configurator.BasicComponentConfigurator; +import org.codehaus.plexus.component.configurator.ComponentConfigurationException; +import org.codehaus.plexus.component.configurator.ComponentConfigurator; +import org.codehaus.plexus.component.repository.exception.ComponentLookupException; +import org.codehaus.plexus.configuration.PlexusConfiguration; +import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration; +import org.codehaus.plexus.context.Context; +import org.codehaus.plexus.context.ContextException; +import org.codehaus.plexus.logging.LogEnabled; +import org.codehaus.plexus.logging.Logger; +import org.codehaus.plexus.logging.console.ConsoleLogger; +import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable; +import org.codehaus.plexus.util.xml.Xpp3Dom; + +/* + * Copyright 2001-2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Profile activator that allows the use of custom third-party activators, by specifying a type - + * or role-hint - for the activator, along with a configuration (in the form of a DOM) to be used + * in configuring the activator. This activator will lookup/configure custom activators on-the-fly, + * without caching any of the lookups from the container. + */ +public class CustomActivator + implements ProfileActivator, Contextualizable, LogEnabled +{ + + private PlexusContainer container; + + private Logger logger; + + public boolean canDetermineActivation( Profile profile ) + { + Activation activation = profile.getActivation(); + + if ( activation != null ) + { + ActivationCustom custom = activation.getCustom(); + + if ( custom != null ) + { + ProfileActivator activator = loadProfileActivator( custom ); + + return activator.canDetermineActivation( profile ); + } + } + + return false; + } + + private ProfileActivator loadProfileActivator( ActivationCustom custom ) + { + String type = custom.getType(); + + ProfileActivator activator; + try + { + activator = (ProfileActivator) container.lookup( ProfileActivator.ROLE, type ); + } + catch ( ComponentLookupException e ) + { + getLogger().debug( "Failed to lookup ProfileActivator \'" + type + "\'", e ); + + throw new IllegalArgumentException( "Cannot find ProfileActivator with role-hint: " + type + + ". \nPerhaps you're missing a build extension? \nSee debug output for more information." ); + } + + PlexusConfiguration configuration = new XmlPlexusConfiguration( (Xpp3Dom) custom.getConfiguration() ); + + ComponentConfigurator configurator = new BasicComponentConfigurator(); + + try + { + configurator.configureComponent( activator, configuration, container.getContainerRealm() ); + } + catch ( ComponentConfigurationException e ) + { + getLogger().debug( "Failed to configure ProfileActivator \'" + type + "\'", e ); + + throw new IllegalArgumentException( "Failed to configure ProfileActivator with role-hint: " + type + + ". Turn on debug mode for more information." ); + } + + return activator; + } + + public boolean isActive( Profile profile ) + { + ActivationCustom custom = profile.getActivation().getCustom(); + + ProfileActivator activator = loadProfileActivator( custom ); + + return activator.isActive( profile ); + } + + public void contextualize( Context context ) + throws ContextException + { + this.container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY ); + } + + private Logger getLogger() + { + if ( logger == null ) + { + logger = new ConsoleLogger( Logger.LEVEL_DEBUG, "CustomActivator-instantiated" ); + } + + return logger; + } + + public void enableLogging( Logger logger ) + { + this.logger = logger; + } + +} diff --git a/maven-project/src/main/java/org/apache/maven/profiles/activation/CustomActivatorExpressionEvaluator.java b/maven-project/src/main/java/org/apache/maven/profiles/activation/CustomActivatorExpressionEvaluator.java new file mode 100644 index 0000000000..fc29826cbb --- /dev/null +++ b/maven-project/src/main/java/org/apache/maven/profiles/activation/CustomActivatorExpressionEvaluator.java @@ -0,0 +1,25 @@ +package org.apache.maven.profiles.activation; + +import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException; +import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator; + +import java.io.File; + +public class CustomActivatorExpressionEvaluator + implements ExpressionEvaluator +{ + + public File alignToBaseDirectory( File file ) + { + // TODO Auto-generated method stub + return null; + } + + public Object evaluate( String expression ) + throws ExpressionEvaluationException + { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/maven-project/src/main/java/org/apache/maven/profiles/activation/DetectedProfileActivator.java b/maven-project/src/main/java/org/apache/maven/profiles/activation/DetectedProfileActivator.java index a52b5ba65f..b8abb3d133 100644 --- a/maven-project/src/main/java/org/apache/maven/profiles/activation/DetectedProfileActivator.java +++ b/maven-project/src/main/java/org/apache/maven/profiles/activation/DetectedProfileActivator.java @@ -1,5 +1,6 @@ package org.apache.maven.profiles.activation; +import org.apache.maven.context.BuildContextManager; import org.apache.maven.model.Profile; /* @@ -21,11 +22,18 @@ import org.apache.maven.model.Profile; public abstract class DetectedProfileActivator implements ProfileActivator { + private BuildContextManager buildContextManager; + public boolean canDetermineActivation( Profile profile ) { return canDetectActivation( profile ); } protected abstract boolean canDetectActivation( Profile profile ); + + protected BuildContextManager getBuildContextManager() + { + return buildContextManager; + } } diff --git a/maven-project/src/main/java/org/apache/maven/profiles/activation/FileProfileActivator.java b/maven-project/src/main/java/org/apache/maven/profiles/activation/FileProfileActivator.java index 55a9939cfd..a4a2034ed6 100644 --- a/maven-project/src/main/java/org/apache/maven/profiles/activation/FileProfileActivator.java +++ b/maven-project/src/main/java/org/apache/maven/profiles/activation/FileProfileActivator.java @@ -22,13 +22,14 @@ import org.codehaus.plexus.util.FileUtils; */ public class FileProfileActivator - extends DetectedProfileActivator + implements ProfileActivator { - protected boolean canDetectActivation( Profile profile ) + + public boolean canDetermineActivation( Profile profile ) { return profile.getActivation() != null && profile.getActivation().getFile() != null; } - + public boolean isActive( Profile profile ) { Activation activation = profile.getActivation(); @@ -56,4 +57,5 @@ public class FileProfileActivator return false; } + } diff --git a/maven-project/src/main/java/org/apache/maven/profiles/activation/JdkPrefixProfileActivator.java b/maven-project/src/main/java/org/apache/maven/profiles/activation/JdkPrefixProfileActivator.java index b5abaed151..f8202eedf9 100644 --- a/maven-project/src/main/java/org/apache/maven/profiles/activation/JdkPrefixProfileActivator.java +++ b/maven-project/src/main/java/org/apache/maven/profiles/activation/JdkPrefixProfileActivator.java @@ -1,5 +1,6 @@ package org.apache.maven.profiles.activation; +import org.apache.maven.context.SystemBuildContext; import org.apache.maven.model.Activation; import org.apache.maven.model.Profile; import org.codehaus.plexus.util.StringUtils; @@ -23,7 +24,8 @@ import org.codehaus.plexus.util.StringUtils; public class JdkPrefixProfileActivator extends DetectedProfileActivator { - private static final String JDK_VERSION = System.getProperty( "java.version" ); + + public static final String JDK_VERSION = "java.version"; public boolean isActive( Profile profile ) { @@ -38,9 +40,12 @@ public class JdkPrefixProfileActivator reverse = true; jdk = jdk.substring( 1 ); } + + SystemBuildContext systemContext = SystemBuildContext.getSystemBuildContext( getBuildContextManager(), true ); + String javaVersion = systemContext.getSystemProperty( JDK_VERSION ); // null case is covered by canDetermineActivation(), so we can do a straight startsWith() here. - boolean result = JDK_VERSION.startsWith( jdk ); + boolean result = javaVersion.startsWith( jdk ); if ( reverse ) { diff --git a/maven-project/src/main/java/org/apache/maven/profiles/activation/SystemPropertyProfileActivator.java b/maven-project/src/main/java/org/apache/maven/profiles/activation/SystemPropertyProfileActivator.java index 3f33f3ff9f..6381362fe3 100644 --- a/maven-project/src/main/java/org/apache/maven/profiles/activation/SystemPropertyProfileActivator.java +++ b/maven-project/src/main/java/org/apache/maven/profiles/activation/SystemPropertyProfileActivator.java @@ -1,15 +1,12 @@ package org.apache.maven.profiles.activation; -import java.util.Properties; +import org.apache.maven.context.SystemBuildContext; import org.apache.maven.model.Activation; import org.apache.maven.model.ActivationProperty; import org.apache.maven.model.Profile; -import org.codehaus.plexus.context.Context; -import org.codehaus.plexus.context.ContextException; import org.codehaus.plexus.logging.LogEnabled; import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.logging.console.ConsoleLogger; -import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable; import org.codehaus.plexus.util.StringUtils; /* @@ -29,16 +26,11 @@ import org.codehaus.plexus.util.StringUtils; */ public class SystemPropertyProfileActivator - extends DetectedProfileActivator implements Contextualizable, LogEnabled + extends DetectedProfileActivator + implements LogEnabled { - private Context context; private Logger logger; - public void contextualize(Context context) throws ContextException - { - this.context = context; - } - protected boolean canDetectActivation( Profile profile ) { return profile.getActivation() != null && profile.getActivation().getProperty() != null; @@ -46,30 +38,14 @@ public class SystemPropertyProfileActivator public boolean isActive( Profile profile ) { - Properties properties = null; - if ( context.contains( "SystemProperties" ) ) - { - try - { - properties = (Properties) context.get("SystemProperties"); - } - catch ( ContextException e ) - { - getLogger().debug( "Failed to get system properties cache from context.", e ); - } - } - - if ( properties == null ) - { - properties = System.getProperties(); - } - Activation activation = profile.getActivation(); ActivationProperty property = activation.getProperty(); if ( property != null ) { + SystemBuildContext systemBuildContext = SystemBuildContext.getSystemBuildContext( getBuildContextManager(), true ); + String name = property.getName(); boolean reverseName = false; @@ -79,7 +55,7 @@ public class SystemPropertyProfileActivator name = name.substring( 1 ); } - String sysValue = properties != null ? properties.getProperty( name ) : null; + String sysValue = systemBuildContext.getSystemProperty( name ); String propValue = property.getValue(); if ( StringUtils.isNotEmpty( propValue ) ) diff --git a/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java b/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java index ee9e0ce86a..32d66e24b8 100644 --- a/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java +++ b/maven-project/src/main/java/org/apache/maven/project/DefaultMavenProjectBuilder.java @@ -33,6 +33,7 @@ import org.apache.maven.artifact.resolver.ArtifactResolutionResult; import org.apache.maven.artifact.resolver.ArtifactResolver; import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.artifact.versioning.VersionRange; +import org.apache.maven.context.BuildContextManager; import org.apache.maven.model.Build; import org.apache.maven.model.Dependency; import org.apache.maven.model.DependencyManagement; @@ -40,16 +41,14 @@ import org.apache.maven.model.DistributionManagement; import org.apache.maven.model.Extension; import org.apache.maven.model.Model; import org.apache.maven.model.Plugin; -import org.apache.maven.model.Profile; import org.apache.maven.model.ReportPlugin; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.profiles.DefaultProfileManager; import org.apache.maven.profiles.MavenProfilesBuilder; import org.apache.maven.profiles.ProfileManager; -import org.apache.maven.profiles.ProfilesConversionUtils; -import org.apache.maven.profiles.ProfilesRoot; import org.apache.maven.profiles.activation.ProfileActivationException; import org.apache.maven.project.artifact.InvalidDependencyVersionException; +import org.apache.maven.project.build.ProjectBuildContext; import org.apache.maven.project.build.model.DefaultModelLineage; import org.apache.maven.project.build.model.ModelLineage; import org.apache.maven.project.build.model.ModelLineageBuilder; @@ -150,8 +149,6 @@ public class DefaultMavenProjectBuilder private ModelInheritanceAssembler modelInheritanceAssembler; - private ProfileInjector profileInjector; - private ModelValidator validator; private Map processedProjectCache = new HashMap(); @@ -167,11 +164,11 @@ public class DefaultMavenProjectBuilder private ModelInterpolator modelInterpolator; - private ArtifactRepositoryFactory artifactRepositoryFactory; - private ModelLineageBuilder modelLineageBuilder; private ProfileAdvisor profileAdvisor; + + private BuildContextManager buildContextManager; private MavenTools mavenTools; @@ -263,18 +260,31 @@ public class DefaultMavenProjectBuilder superModel.setVersion( STANDALONE_SUPERPOM_VERSION ); - - List activeProfiles; - - profileManager.addProfiles( superModel.getProfiles() ); - + MavenProject project = new MavenProject( superModel ); + + ProjectBuildContext projectContext = ProjectBuildContext.getProjectBuildContext( buildContextManager, true ); + + projectContext.setCurrentProject( project ); + projectContext.store( buildContextManager ); + String projectId = safeVersionlessKey( STANDALONE_SUPERPOM_GROUPID, STANDALONE_SUPERPOM_ARTIFACTID ); - activeProfiles = injectActiveProfiles( profileManager, superModel ); + List activeProfiles = profileAdvisor.applyActivatedProfiles( superModel, null, profileManager.getExplicitlyActivatedIds(), profileManager.getExplicitlyDeactivatedIds() ); + List activeExternalProfiles = profileAdvisor.applyActivatedExternalProfiles( superModel, null, profileManager ); + + LinkedHashSet profiles = new LinkedHashSet(); + + if ( activeProfiles != null && !activeProfiles.isEmpty() ) + { + profiles.addAll( activeProfiles ); + } + + if ( activeExternalProfiles != null && !activeExternalProfiles.isEmpty() ) + { + profiles.addAll( activeExternalProfiles ); + } - MavenProject project = new MavenProject( superModel ); - - project.setActiveProfiles( activeProfiles ); + project.setActiveProfiles( new ArrayList( profiles ) ); project.setOriginalModel( superModel ); @@ -296,6 +306,7 @@ public class DefaultMavenProjectBuilder } } + public MavenProject buildWithDependencies( File projectDescriptor, ArtifactRepository localRepository, ProfileManager profileManager ) @@ -1001,6 +1012,11 @@ public class DefaultMavenProjectBuilder modelLineageBuilder.resumeBuildingModelLineage( modelLineage, localRepository, externalProfileManager, cachedPomFilesByModelId ); + ProjectBuildContext projectContext = ProjectBuildContext.getProjectBuildContext( buildContextManager, true ); + + projectContext.setModelLineage( modelLineage ); + projectContext.store( buildContextManager ); + List explicitlyActive; List explicitlyInactive; @@ -1026,6 +1042,9 @@ public class DefaultMavenProjectBuilder MavenProject project = new MavenProject( currentModel ); project.setFile( currentPom ); + + projectContext.setCurrentProject( project ); + projectContext.store( buildContextManager ); project.setActiveProfiles( profileAdvisor.applyActivatedProfiles( model, projectDir, explicitlyActive, explicitlyInactive ) ); @@ -1061,80 +1080,6 @@ public class DefaultMavenProjectBuilder return result; } - private List injectActiveProfiles( ProfileManager profileManager, Model model ) - throws ProjectBuildingException - { - List activeProfiles; - - if ( profileManager != null ) - { - try - { - activeProfiles = profileManager.getActiveProfiles(); - } - catch ( ProfileActivationException e ) - { - String projectId = safeVersionlessKey( model.getGroupId(), model.getArtifactId() ); - - throw new ProjectBuildingException( projectId, e.getMessage(), e ); - } - - for ( Iterator it = activeProfiles.iterator(); it.hasNext(); ) - { - Profile profile = (Profile) it.next(); - - profileInjector.inject( profile, model ); - } - } - else - { - activeProfiles = Collections.EMPTY_LIST; - } - - return activeProfiles; - } - - private void loadProjectExternalProfiles( ProfileManager profileManager, File projectDir ) - throws ProfileActivationException - { - if ( projectDir != null ) - { - try - { - ProfilesRoot root = profilesBuilder.buildProfiles( projectDir ); - - if ( root != null ) - { - List active = root.getActiveProfiles(); - - if ( active != null && !active.isEmpty() ) - { - profileManager.explicitlyActivate( root.getActiveProfiles() ); - } - - for ( Iterator it = root.getProfiles().iterator(); it.hasNext(); ) - { - org.apache.maven.profiles.Profile rawProfile = (org.apache.maven.profiles.Profile) it.next(); - - Profile converted = ProfilesConversionUtils.convertFromProfileXmlProfile( rawProfile ); - - profileManager.addProfile( converted ); - } - } - } - catch ( IOException e ) - { - throw new ProfileActivationException( "Cannot read profiles.xml resource from directory: " + projectDir, - e ); - } - catch ( XmlPullParserException e ) - { - throw new ProfileActivationException( - "Cannot parse profiles.xml resource from directory: " + projectDir, e ); - } - } - } - private Model readModel( String projectId, File file, boolean strict ) throws ProjectBuildingException { diff --git a/maven-project/src/main/java/org/apache/maven/project/build/ProjectBuildContext.java b/maven-project/src/main/java/org/apache/maven/project/build/ProjectBuildContext.java new file mode 100644 index 0000000000..e2825832be --- /dev/null +++ b/maven-project/src/main/java/org/apache/maven/project/build/ProjectBuildContext.java @@ -0,0 +1,98 @@ +package org.apache.maven.project.build; + +import org.apache.maven.context.BuildContext; +import org.apache.maven.context.BuildContextManager; +import org.apache.maven.context.ManagedBuildData; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.build.model.ModelLineage; + +/* + * Copyright 2001-2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Build context information available for use during profile activation, which supplies information + * about the current project and lineage from the current project back through parent poms to the + * POM that declared that profile (where the activator is used). Lineage may not be accessible in + * all cases, and will usually be incomplete (not stretching all the way back to the common super-POM). + * This could enable custom profile activators that trigger based on model properties, etc. + */ +public class ProjectBuildContext + implements ManagedBuildData +{ + + public static final String BUILD_CONTEXT_KEY = ProjectBuildContext.class.getName(); + + private ModelLineage modelLineage; + + private MavenProject currentProject; + + public ProjectBuildContext() + { + } + + public ModelLineage getModelLineage() + { + return modelLineage; + } + + public void setModelLineage( ModelLineage modelLineage ) + { + this.modelLineage = modelLineage; + } + + public MavenProject getCurrentProject() + { + return currentProject; + } + + public void setCurrentProject( MavenProject currentProject ) + { + this.currentProject = currentProject; + } + + public String getStorageKey() + { + return BUILD_CONTEXT_KEY; + } + + public static ProjectBuildContext getProjectBuildContext( BuildContextManager buildContextManager, boolean create ) + { + BuildContext buildContext = buildContextManager.readBuildContext( false ); + + ProjectBuildContext projectContext = null; + + if ( buildContext != null ) + { + projectContext = (ProjectBuildContext) buildContext.get( BUILD_CONTEXT_KEY ); + } + + if ( create && projectContext == null ) + { + projectContext = new ProjectBuildContext(); + } + + return projectContext; + } + + public void store( BuildContextManager buildContextManager ) + { + BuildContext buildContext = buildContextManager.readBuildContext( true ); + + buildContext.put( this ); + + buildContextManager.storeBuildContext( buildContext ); + } +} diff --git a/maven-project/src/main/java/org/apache/maven/project/build/model/DefaultModelLineage.java b/maven-project/src/main/java/org/apache/maven/project/build/model/DefaultModelLineage.java index 815c894525..fa6158f11a 100644 --- a/maven-project/src/main/java/org/apache/maven/project/build/model/DefaultModelLineage.java +++ b/maven-project/src/main/java/org/apache/maven/project/build/model/DefaultModelLineage.java @@ -328,4 +328,44 @@ public class DefaultModelLineage } } + public ModelLineageIterator lineageIterator() + { + return new ModelLineageIterator() + { + + private int idx = -1; + + public boolean hasNext() + { + return tuples.size() > idx + 1; + } + + public Object next() + { + return ( (ModelLineageTuple) tuples.get( ( ++idx ) ) ).model; + } + + public void remove() + { + tuples.remove( idx ); + } + + public List getArtifactRepositories() + { + return ( (ModelLineageTuple) tuples.get( idx ) ).remoteRepositories; + } + + public Model getModel() + { + return ( (ModelLineageTuple) tuples.get( idx ) ).model; + } + + public File getPOMFile() + { + return ( (ModelLineageTuple) tuples.get( idx ) ).file; + } + + }; + } + } diff --git a/maven-project/src/main/java/org/apache/maven/project/build/model/ModelLineage.java b/maven-project/src/main/java/org/apache/maven/project/build/model/ModelLineage.java index 4ba773159d..de0f765aa3 100644 --- a/maven-project/src/main/java/org/apache/maven/project/build/model/ModelLineage.java +++ b/maven-project/src/main/java/org/apache/maven/project/build/model/ModelLineage.java @@ -88,6 +88,14 @@ public interface ModelLineage * that of the deepest parent at the zero index, and that of the current POM at the last index. */ List getArtifactRepositoryListsInDescendingOrder(); + + /** + * Retrieve an Iterator derivative that functions in the simplest sense just like the return + * value of the modelIterator() method. However, the ModelLineageIterator also gives access to + * the current POM file and current remote ArtifactRepository instances used to resolve the + * current Model...along with a method to give explicit access to the current Model instance. + */ + ModelLineageIterator lineageIterator(); /** * Iterate over the lineage of Model instances, starting with the child (current) Model, diff --git a/maven-project/src/main/java/org/apache/maven/project/build/model/ModelLineageIterator.java b/maven-project/src/main/java/org/apache/maven/project/build/model/ModelLineageIterator.java new file mode 100644 index 0000000000..70c06aa11c --- /dev/null +++ b/maven-project/src/main/java/org/apache/maven/project/build/model/ModelLineageIterator.java @@ -0,0 +1,37 @@ +package org.apache.maven.project.build.model; + +import org.apache.maven.model.Model; + +import java.io.File; +import java.util.Iterator; +import java.util.List; + +/** + * Iterator that gives access to all information associated with each model in a ModelLineage. + * The result of the next() method is the Model instance itself, but you can also retrieve this + * Model instance using getModel() below. + * + * @author jdcasey + */ +public interface ModelLineageIterator + extends Iterator +{ + + /** + * Retrieve the Model instance associated with the current position in the ModelLineage. + * This is the same return value as the next() method. + */ + Model getModel(); + + /** + * Retrieve the POM File associated with the current position in the ModelLineage + */ + File getPOMFile(); + + /** + * Retrieve the remote ArtifactRepository instances associated with the current position + * in the ModelLineage. + */ + List getArtifactRepositories(); + +} diff --git a/maven-project/src/main/resources/META-INF/plexus/components.xml b/maven-project/src/main/resources/META-INF/plexus/components.xml index 3418f25c58..195ff5a184 100644 --- a/maven-project/src/main/resources/META-INF/plexus/components.xml +++ b/maven-project/src/main/resources/META-INF/plexus/components.xml @@ -101,9 +101,6 @@ org.apache.maven.profiles.MavenProfilesBuilder - - org.apache.maven.project.injection.ProfileInjector - org.apache.maven.project.injection.ModelDefaultsInjector @@ -126,7 +123,8 @@ org.apache.maven.artifact.resolver.ArtifactResolver - org.apache.maven.artifact.repository.ArtifactRepositoryFactory + org.apache.maven.context.BuildContextManager + default org.apache.maven.artifact.manager.WagonManager @@ -155,6 +153,12 @@ org.apache.maven.profiles.activation.ProfileActivator jdk-prefix org.apache.maven.profiles.activation.JdkPrefixProfileActivator + + + org.apache.maven.context.BuildContextManager + default + + + + org.apache.maven.profiles.activation.ProfileActivator + custom + org.apache.maven.profiles.activation.CustomActivator + - 4.0.0 @@ -149,6 +148,7 @@ maven-artifact maven-artifact-manager maven-artifact-test + maven-build-context maven-core maven-error-diagnostics maven-model