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>
<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>
<role>org.apache.maven.lifecycle.binding.LifecycleBindingManager</role>
<role-hint>default</role-hint>

View File

@ -58,18 +58,16 @@ import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
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.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.*;
import org.apache.maven.plugin.version.PluginVersionNotFoundException;
import org.apache.maven.plugin.version.PluginVersionResolutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.MavenProjectBuildingResult;
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.MissingModuleException;
import org.apache.maven.settings.Settings;
@ -92,6 +90,7 @@ import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.component.repository.exception.ComponentRepositoryException;
import org.codehaus.plexus.configuration.PlexusConfigurationException;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.logging.LoggerManager;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
@ -148,6 +147,10 @@ public class MavenEmbedder
private BuildPlanner buildPlanner;
private PluginRepository pluginRepository;
private Mixer mixer;
// ----------------------------------------------------------------------
// Configuration
// ----------------------------------------------------------------------
@ -246,6 +249,15 @@ public class MavenEmbedder
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
// ----------------------------------------------------------------------
@ -656,6 +668,10 @@ public class MavenEmbedder
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
// simply cascade values in from requests used for individual executions.
request = new DefaultMavenExecutionRequest();

View File

@ -163,7 +163,6 @@ public class PomTransformer
ProjectUri.Build.TestResources.TestResource.directory,
ProjectUri.Build.Filters.filter,
ProjectUri.Reporting.outputDirectory ) ) );
/**
* @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 final class PomClassicTransformer
DomainModel domainModel)
throws IOException
{
if(! ( domainModel instanceof PomClassicDomainModel ) )
{
return;
}
Interpolator.interpolateModelProperties( modelProperties, interpolatorProperties, (PomClassicDomainModel) domainModel);
}
}

View File

@ -23,7 +23,6 @@ import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@ -34,34 +33,29 @@ import org.apache.maven.artifact.InvalidRepositoryException;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.model.Model;
import org.apache.maven.model.Parent;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuilderConfiguration;
import org.apache.maven.project.builder.ArtifactModelContainerFactory;
import org.apache.maven.project.builder.IdModelContainerFactory;
import org.apache.maven.project.builder.PomArtifactResolver;
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.apache.maven.project.builder.*;
import org.apache.maven.shared.model.*;
import org.apache.maven.shared.model.impl.DefaultModelDataSource;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.util.IOUtil;
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.
*/
@Component(role = ProjectBuilder.class)
public class DefaultProjectBuilder
implements ProjectBuilder, LogEnabled
implements ProjectBuilder, Mixer, LogEnabled
{
@Requirement
private ArtifactFactory artifactFactory;
@ -372,4 +366,84 @@ public class DefaultProjectBuilder
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 @@ package org.apache.maven.project.builder;
import java.io.File;
import java.io.IOException;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.project.harness.PomTestWrapper;
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
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 Mixer mixer;
private MavenTools mavenTools;
private PomArtifactResolver pomArtifactResolver;
private File testDirectory;
private File testMixinDirectory;
protected void setUp()
throws Exception
{
testDirectory = new File( getBasedir(), BASE_POM_DIR );
testMixinDirectory = new File( getBasedir(), BASE_MIXIN_DIR );
projectBuilder = lookup( ProjectBuilder.class );
mixer = (Mixer) projectBuilder;
mavenTools = lookup( MavenTools.class );
pomArtifactResolver = new PomArtifactResolver()
{
@ -62,6 +79,18 @@ public class PomConstructionTest
};
}
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
// 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
@ -731,6 +760,19 @@ public class PomConstructionTest
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 )
{
assertEquals( expected, pom.getValue( expression ) );

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>