Merge: sisbell-plugin-manager. MNG-3631 - Get plugin config, including mojo descriptor info.

git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@739970 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Britton Isbell 2009-02-02 12:02:44 +00:00
parent 7397cc69d6
commit d1124333ad
13 changed files with 406 additions and 25 deletions

View File

@ -0,0 +1,58 @@
package org.apache.maven.plugin;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import java.util.List;
import java.io.StringReader;
@Component( role = PluginRepository.class)
public class DefaultPluginRepository implements PluginRepository
{
@Requirement
protected MavenPluginCollector pluginCollector;
public Plugin findPluginById(String id, String mojoId) throws Exception
{
if(pluginCollector == null)
{
throw new IllegalArgumentException("pluginCollector: null");
}
if(id == null)
{
throw new IllegalArgumentException("id: null");
}
String[] token = id.split(":");
if(token.length != 3)
{
throw new IllegalArgumentException("id: does not include complete id");
}
Plugin plugin = new Plugin();
plugin.setGroupId(token[0]);
plugin.setArtifactId(token[1]);
plugin.setVersion(token[2]);
PluginDescriptor descriptor = pluginCollector.getPluginDescriptor(plugin);
if(descriptor == null)
{
return null;
}
for(MojoDescriptor mojo : (List<MojoDescriptor>) descriptor.getMojos())
{
if(mojo.getId().equals(id + ":"+ mojoId) && mojo.getMojoConfiguration() != null)
{
plugin.setConfiguration(Xpp3DomBuilder.build( new StringReader( mojo.getMojoConfiguration().toString() ) ));
}
}
return plugin;
}
}

View File

@ -0,0 +1,10 @@
package org.apache.maven.plugin;
import org.apache.maven.model.Plugin;
import org.codehaus.plexus.configuration.PlexusConfigurationException;
public interface PluginRepository {
Plugin findPluginById(String pluginId, String mojoId) throws Exception;
}

View File

@ -26,6 +26,16 @@ use a configuration source to pull in the lifecycle information.
--> -->
<component-set> <component-set>
<components> <components>
<component>
<role>org.apache.maven.plugin.PluginRepository</role>
<role-hint>default</role-hint>
<implementation>org.apache.maven.plugin.DefaultPluginRepository</implementation>
<requirements>
<requirement>
<role>org.apache.maven.plugin.MavenPluginCollector</role>
</requirement>
</requirements>
</component>
<component> <component>
<role>org.apache.maven.lifecycle.binding.LifecycleBindingManager</role> <role>org.apache.maven.lifecycle.binding.LifecycleBindingManager</role>
<role-hint>default</role-hint> <role-hint>default</role-hint>

View File

@ -58,18 +58,16 @@
import org.apache.maven.model.io.xpp3.MavenXpp3Writer; import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.apache.maven.monitor.event.DefaultEventDispatcher; import org.apache.maven.monitor.event.DefaultEventDispatcher;
import org.apache.maven.monitor.event.EventDispatcher; import org.apache.maven.monitor.event.EventDispatcher;
import org.apache.maven.plugin.InvalidPluginException; import org.apache.maven.plugin.*;
import org.apache.maven.plugin.MavenPluginCollector;
import org.apache.maven.plugin.MavenPluginDiscoverer;
import org.apache.maven.plugin.PluginManager;
import org.apache.maven.plugin.PluginManagerException;
import org.apache.maven.plugin.PluginNotFoundException;
import org.apache.maven.plugin.version.PluginVersionNotFoundException; import org.apache.maven.plugin.version.PluginVersionNotFoundException;
import org.apache.maven.plugin.version.PluginVersionResolutionException; import org.apache.maven.plugin.version.PluginVersionResolutionException;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder; import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.MavenProjectBuildingResult; import org.apache.maven.project.MavenProjectBuildingResult;
import org.apache.maven.project.ProjectBuildingException; import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.builder.ProjectBuilder;
import org.apache.maven.project.builder.Mixer;
import org.apache.maven.plugin.PluginRepository;
import org.apache.maven.reactor.MavenExecutionException; import org.apache.maven.reactor.MavenExecutionException;
import org.apache.maven.reactor.MissingModuleException; import org.apache.maven.reactor.MissingModuleException;
import org.apache.maven.settings.Settings; import org.apache.maven.settings.Settings;
@ -92,6 +90,7 @@
import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.component.repository.exception.ComponentRepositoryException; import org.codehaus.plexus.component.repository.exception.ComponentRepositoryException;
import org.codehaus.plexus.configuration.PlexusConfigurationException; import org.codehaus.plexus.configuration.PlexusConfigurationException;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.logging.LoggerManager; import org.codehaus.plexus.logging.LoggerManager;
import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory; import org.codehaus.plexus.util.ReaderFactory;
@ -147,6 +146,10 @@ public class MavenEmbedder
private MavenExecutionRequestPopulator populator; private MavenExecutionRequestPopulator populator;
private BuildPlanner buildPlanner; private BuildPlanner buildPlanner;
private PluginRepository pluginRepository;
private Mixer mixer;
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// Configuration // Configuration
@ -246,6 +249,15 @@ public void writeModel( Writer writer,
modelWriter.write( writer, model ); modelWriter.write( writer, model );
} }
public PlexusConfiguration getPluginConfiguration(String pluginId, String mojoId, Model model) throws Exception
{
try {
return mixer.mixPluginAndReturnConfig(pluginRepository.findPluginById(pluginId, mojoId), model);
} catch (PlexusConfigurationException e) {
throw new IOException(e.getMessage());
}
}
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// Settings // Settings
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@ -656,6 +668,10 @@ private void start( Configuration configuration )
artifactHandlerManager = container.lookup( ArtifactHandlerManager.class ); artifactHandlerManager = container.lookup( ArtifactHandlerManager.class );
pluginRepository = container.lookup( PluginRepository.class );
mixer = (Mixer) container.lookup( ProjectBuilder.class );
// This is temporary as we can probably cache a single request and use it for default values and // This is temporary as we can probably cache a single request and use it for default values and
// simply cascade values in from requests used for individual executions. // simply cascade values in from requests used for individual executions.
request = new DefaultMavenExecutionRequest(); request = new DefaultMavenExecutionRequest();

View File

@ -162,8 +162,7 @@ public PomTransformer(DomainModelFactory factory)
ProjectUri.Build.Resources.Resource.directory, ProjectUri.Build.Resources.Resource.directory,
ProjectUri.Build.TestResources.TestResource.directory, ProjectUri.Build.TestResources.TestResource.directory,
ProjectUri.Build.Filters.filter, ProjectUri.Build.Filters.filter,
ProjectUri.Reporting.outputDirectory ) ) ); ProjectUri.Reporting.outputDirectory ) ) );
/** /**
* @see ModelTransformer#transformToDomainModel(java.util.List, java.util.List) * @see ModelTransformer#transformToDomainModel(java.util.List, java.util.List)
*/ */

View File

@ -0,0 +1,17 @@
package org.apache.maven.project.builder;
import org.apache.maven.project.MavenProject;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.Model;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import java.io.IOException;
public interface Mixer
{
Model mixPlugin(Plugin plugin, Model model) throws IOException;
PlexusConfiguration mixPluginAndReturnConfig(Plugin plugin, Model model) throws IOException;
}

View File

@ -0,0 +1,116 @@
package org.apache.maven.project.builder;
import org.apache.maven.shared.model.InputStreamDomainModel;
import org.apache.maven.shared.model.ModelProperty;
import org.apache.maven.shared.model.ModelMarshaller;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.Model;
import org.apache.maven.model.Build;
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.codehaus.plexus.util.WriterFactory;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import java.io.*;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.ArrayList;
public class PluginMixin implements InputStreamDomainModel {
/**
* Bytes containing the underlying model
*/
private byte[] inputBytes;
/**
* History of joins and deletes of model properties
*/
private String eventHistory;
private List<ModelProperty> modelProperties;
public PluginMixin(Plugin plugin)
throws IOException
{
if(plugin == null)
{
throw new IllegalArgumentException("plugin: null");
}
Model model = new Model();
Build build = new Build();
build.addPlugin(plugin);
model.setBuild(build);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Writer out = null;
MavenXpp3Writer writer = new MavenXpp3Writer();
try
{
out = WriterFactory.newXmlWriter( baos );
writer.write( out, model );
}
finally
{
if ( out != null )
{
out.close();
}
}
inputBytes = baos.toByteArray();
}
public InputStream getInputStream() {
byte[] copy = new byte[inputBytes.length];
System.arraycopy( inputBytes, 0, copy, 0, inputBytes.length );
return new ByteArrayInputStream( copy );
}
public List<ModelProperty> getModelProperties() throws IOException {
if(modelProperties == null)
{
Set<String> s = new HashSet<String>();
//TODO: Should add all collections from ProjectUri
s.addAll(PomTransformer.URIS);
s.add(ProjectUri.Build.PluginManagement.Plugins.Plugin.Executions.xUri);
s.add(ProjectUri.DependencyManagement.Dependencies.Dependency.Exclusions.xUri);
s.add(ProjectUri.Dependencies.Dependency.Exclusions.xUri);
s.add(ProjectUri.Build.Plugins.Plugin.Executions.xUri);
s.add(ProjectUri.Build.Plugins.Plugin.Executions.Execution.Goals.xURI);
s.add(ProjectUri.Reporting.Plugins.Plugin.ReportSets.xUri);
s.add(ProjectUri.Reporting.Plugins.Plugin.ReportSets.ReportSet.configuration);
s.add(ProjectUri.Build.Plugins.Plugin.Executions.Execution.configuration);
modelProperties = ModelMarshaller.marshallXmlToModelProperties(
getInputStream(), ProjectUri.baseUri, s );
}
return new ArrayList<ModelProperty>(modelProperties);
}
public String getEventHistory() {
return eventHistory;
}
public void setEventHistory(String eventHistory) {
this.eventHistory = eventHistory;
}
/**
* Returns XML model as string
*
* @return XML model as string
*/
public String asString()
{
try
{
return IOUtil.toString( ReaderFactory.newXmlReader( new ByteArrayInputStream( inputBytes ) ) );
}
catch ( IOException ioe )
{
// should not occur: everything is in-memory
return "";
}
}
}

View File

@ -44,6 +44,10 @@ public void interpolateModelProperties(List<ModelProperty> modelProperties,
DomainModel domainModel) DomainModel domainModel)
throws IOException throws IOException
{ {
if(! ( domainModel instanceof PomClassicDomainModel ) )
{
return;
}
Interpolator.interpolateModelProperties( modelProperties, interpolatorProperties, (PomClassicDomainModel) domainModel); Interpolator.interpolateModelProperties( modelProperties, interpolatorProperties, (PomClassicDomainModel) domainModel);
} }
} }

View File

@ -23,7 +23,6 @@
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -34,34 +33,29 @@
import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.model.Model; import org.apache.maven.model.Model;
import org.apache.maven.model.Parent; import org.apache.maven.model.Parent;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuilderConfiguration; import org.apache.maven.project.ProjectBuilderConfiguration;
import org.apache.maven.project.builder.ArtifactModelContainerFactory; import org.apache.maven.project.builder.*;
import org.apache.maven.project.builder.IdModelContainerFactory; import org.apache.maven.shared.model.*;
import org.apache.maven.project.builder.PomArtifactResolver; import org.apache.maven.shared.model.impl.DefaultModelDataSource;
import org.apache.maven.project.builder.PomClassicDomainModel;
import org.apache.maven.project.builder.PomClassicDomainModelFactory;
import org.apache.maven.project.builder.PomClassicTransformer;
import org.apache.maven.project.builder.PomTransformer;
import org.apache.maven.project.builder.ProjectBuilder;
import org.apache.maven.shared.model.DomainModel;
import org.apache.maven.shared.model.InterpolatorProperty;
import org.apache.maven.shared.model.ModelEventListener;
import org.apache.maven.shared.model.ModelTransformerContext;
import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.LogEnabled; import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory; import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
import org.apache.maven.shared.model.ModelMarshaller;
/** /**
* Default implementation of the project builder. * Default implementation of the project builder.
*/ */
@Component(role = ProjectBuilder.class) @Component(role = ProjectBuilder.class)
public class DefaultProjectBuilder public class DefaultProjectBuilder
implements ProjectBuilder, LogEnabled implements ProjectBuilder, Mixer, LogEnabled
{ {
@Requirement @Requirement
private ArtifactFactory artifactFactory; private ArtifactFactory artifactFactory;
@ -371,5 +365,85 @@ public Model getSuperModel()
} }
return superModel; return superModel;
} }
public Model mixPlugin(Plugin plugin, Model model) throws IOException
{
//TODO - interpolation
List<DomainModel> domainModels = new ArrayList<DomainModel>();
domainModels.add( new PluginMixin(plugin) );
domainModels.add( new PomClassicDomainModel(model) );
PomClassicTransformer transformer = new PomClassicTransformer( new PomClassicDomainModelFactory() );
ModelTransformerContext ctx = new ModelTransformerContext(PomTransformer.MODEL_CONTAINER_INFOS );
PomClassicDomainModel transformedDomainModel = ( (PomClassicDomainModel) ctx.transform( domainModels,
transformer,
transformer,
Collections.EMPTY_LIST,
null,
listeners ) );
return transformedDomainModel.getModel();
// List<ModelProperty> pluginProperties = ModelMarshaller.marshallXmlToModelProperties(
// (new PluginMixin(plugin)).getInputStream(), ProjectUri.Build.Plugins.xUri, null);
}
public PlexusConfiguration mixPluginAndReturnConfig(Plugin plugin, Model model) throws IOException
{
List<DomainModel> domainModels = new ArrayList<DomainModel>();
domainModels.add( new PluginMixin(plugin) );
domainModels.add( new PomClassicDomainModel(model) );
PomClassicTransformer transformer = new PomClassicTransformer( new PomClassicDomainModelFactory() );
ModelTransformerContext ctx = new ModelTransformerContext(PomTransformer.MODEL_CONTAINER_INFOS );
PomClassicDomainModel transformedDomainModel = ( (PomClassicDomainModel) ctx.transform( domainModels,
transformer,
transformer,
Collections.EMPTY_LIST,
null,
listeners ) );
ModelDataSource source =
new DefaultModelDataSource(transformedDomainModel.getModelProperties(), PomTransformer.MODEL_CONTAINER_FACTORIES);
for(ModelContainer pluginContainer : source.queryFor(ProjectUri.Build.Plugins.Plugin.xUri))
{
if(matchesIdOfPlugin(pluginContainer, plugin))
{
List<ModelProperty> config = new ArrayList<ModelProperty>();
for(ModelProperty mp : pluginContainer.getProperties())
{
if(mp.getUri().startsWith(ProjectUri.Build.Plugins.Plugin.configuration))
{
config.add(mp);
}
}
return new XmlPlexusConfiguration(ModelMarshaller.unmarshalModelPropertiesToXml(config, ProjectUri.Build.Plugins.Plugin.xUri));
}
}
return null;
}
private static boolean matchesIdOfPlugin(ModelContainer mc, Plugin plugin)
{
List<ModelProperty> props = mc.getProperties();
return getValueByUri(ProjectUri.Build.Plugins.Plugin.groupId, props).equals(plugin.getGroupId())
&& getValueByUri(ProjectUri.Build.Plugins.Plugin.artifactId, props).equals(plugin.getArtifactId())
&& getValueByUri(ProjectUri.Build.Plugins.Plugin.version, props).equals(plugin.getVersion());
}
private static String getValueByUri(String uri, List<ModelProperty> modelProperties)
{
for(ModelProperty mp : modelProperties)
{
if(mp.getUri().equals(uri))
{
return mp.getResolvedValue();
}
}
return "";
}
} }

View File

@ -0,0 +1,4 @@
package org.apache.maven.project.builder;
public class PluginBuilderTest {
}

View File

@ -21,34 +21,51 @@
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.FileInputStream;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.maven.MavenTools; import org.apache.maven.MavenTools;
import org.apache.maven.model.Model;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.Artifact;
import org.apache.maven.project.harness.PomTestWrapper; import org.apache.maven.project.harness.PomTestWrapper;
import org.codehaus.plexus.PlexusTestCase; import org.codehaus.plexus.PlexusTestCase;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
public class PomConstructionTest public class PomConstructionTest
extends PlexusTestCase extends PlexusTestCase
{ {
private static String BASE_POM_DIR = "src/test/resources-project-builder"; private static String BASE_DIR = "src/test";
private static String BASE_POM_DIR = BASE_DIR + "/resources-project-builder";
private static String BASE_MIXIN_DIR = BASE_DIR + "/resources-mixins";
private ProjectBuilder projectBuilder; private ProjectBuilder projectBuilder;
private Mixer mixer;
private MavenTools mavenTools; private MavenTools mavenTools;
private PomArtifactResolver pomArtifactResolver; private PomArtifactResolver pomArtifactResolver;
private File testDirectory; private File testDirectory;
private File testMixinDirectory;
protected void setUp() protected void setUp()
throws Exception throws Exception
{ {
testDirectory = new File( getBasedir(), BASE_POM_DIR ); testDirectory = new File( getBasedir(), BASE_POM_DIR );
testMixinDirectory = new File( getBasedir(), BASE_MIXIN_DIR );
projectBuilder = lookup( ProjectBuilder.class ); projectBuilder = lookup( ProjectBuilder.class );
mixer = (Mixer) projectBuilder;
mavenTools = lookup( MavenTools.class ); mavenTools = lookup( MavenTools.class );
pomArtifactResolver = new PomArtifactResolver() pomArtifactResolver = new PomArtifactResolver()
{ {
@ -62,6 +79,18 @@ public void resolve( Artifact artifact )
}; };
} }
public void testPluginMergeSimple()
throws Exception
{
Model model = buildPom( "plugin-merge-simple" ).getDomainModel().getModel();
Model plugin = buildMixin("plugins/simple");
model = mixer.mixPlugin((Plugin) plugin.getBuild().getPlugins().get(0), model);
PomTestWrapper pom = new PomTestWrapper( model );
assertEquals( "FAILED", pom.getValue( "build/plugins[1]/configuration[1]/propertiesFile" ) );
}
// Some better conventions for the test poms needs to be created and each of these tests // Some better conventions for the test poms needs to be created and each of these tests
// that represent a verification of a specification item needs to be a couple lines at most. // that represent a verification of a specification item needs to be a couple lines at most.
// The expressions help a lot, but we need a clean to pick up a directory of POMs, automatically load // The expressions help a lot, but we need a clean to pick up a directory of POMs, automatically load
@ -731,11 +760,24 @@ private PomTestWrapper buildPom( String pomPath )
return new PomTestWrapper( pomFile, projectBuilder.buildModel( pomFile, null, pomArtifactResolver ) ); return new PomTestWrapper( pomFile, projectBuilder.buildModel( pomFile, null, pomArtifactResolver ) );
} }
private Model buildMixin( String mixinPath )
throws IOException, XmlPullParserException
{
File mixinFile = new File( testMixinDirectory , mixinPath );
if ( mixinFile.isDirectory() )
{
mixinFile = new File( mixinFile, "mixin.xml" );
}
FileInputStream pluginStream = new FileInputStream( mixinFile );
MavenXpp3Reader reader = new MavenXpp3Reader();
return reader.read(pluginStream, false);
}
protected void assertModelEquals( PomTestWrapper pom, Object expected, String expression ) protected void assertModelEquals( PomTestWrapper pom, Object expected, String expression )
{ {
assertEquals( expected, pom.getValue( expression ) ); assertEquals( expected, pom.getValue( expression ) );
} }
// Need to get this to walk around a directory and automatically build up the artifact set. If we // Need to get this to walk around a directory and automatically build up the artifact set. If we
// follow some standard conventions this can be simple. // follow some standard conventions this can be simple.
class FileBasedPomArtifactResolver class FileBasedPomArtifactResolver

View File

@ -0,0 +1,14 @@
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.its.plugins</groupId>
<artifactId>maven-it-plugin-configuration</artifactId>
<version>2.1-SNAPSHOT</version>
<configuration>
<propertiesFile>FAILED</propertiesFile>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,17 @@
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.nexus</groupId>
<artifactId>nexus-indexer</artifactId>
<version>1.1.3-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.its.plugins</groupId>
<artifactId>maven-it-plugin-configuration</artifactId>
<version>2.1-SNAPSHOT</version>
</plugin>
</plugins>
</build>
</project>