335711 read lifecycle mapping metadata from maven-plugin artifact
When calculating buildi lifecycle mapping, m2e will check if main
maven-plugin artifact has META-INF/m2e/lifecycle-mapping-metadata.xml
and will use this resource as additional metadata source. New
lifecycle mapping metadata sources priorities
1. this pom embedded, this pom referenced, parent embedded,
parent referenced, grand parent embedded...
2. sources contributed by eclipse extensions
3. maven-plugin embedded metadata
4. default source, if present
Signed-off-by: Igor Fedorenko <igor@ifedorenko.com>
diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenImpl.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenImpl.java
index d593d08..d0360be 100644
--- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenImpl.java
+++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/embedder/MavenImpl.java
@@ -598,6 +598,11 @@
Artifact artifact = lookup(RepositorySystem.class).createArtifactWithClassifier(groupId, artifactId, version, type,
classifier);
+ return resolve(artifact, remoteRepositories, monitor);
+ }
+
+ public Artifact resolve(Artifact artifact, List<ArtifactRepository> remoteRepositories,
+ IProgressMonitor monitor) throws CoreException {
if(remoteRepositories == null) {
try {
remoteRepositories = getArtifactRepositories();
@@ -652,6 +657,12 @@
return artifact;
}
+ public Artifact resolvePluginArtifact(Plugin plugin, List<ArtifactRepository> remoteRepositories,
+ IProgressMonitor monitor) throws CoreException {
+ Artifact artifact = lookup(RepositorySystem.class).createPluginArtifact(plugin);
+ return resolve(artifact, remoteRepositories, monitor);
+ }
+
public String getArtifactPath(ArtifactRepository repository, String groupId, String artifactId, String version,
String type, String classifier) throws CoreException {
Artifact artifact = lookup(RepositorySystem.class).createArtifactWithClassifier(groupId, artifactId, version, type,
diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/lifecyclemapping/LifecycleMappingFactory.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/lifecyclemapping/LifecycleMappingFactory.java
index 85da707..5663071 100644
--- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/lifecyclemapping/LifecycleMappingFactory.java
+++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/lifecyclemapping/LifecycleMappingFactory.java
@@ -11,8 +11,10 @@
package org.eclipse.m2e.core.internal.lifecyclemapping;
+import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
@@ -26,6 +28,8 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
import org.osgi.framework.Bundle;
import org.slf4j.Logger;
@@ -199,8 +203,8 @@
List<MappingMetadataSource> metadataSources;
try {
- metadataSources = getProjectMetadataSources(templateRequest, mavenProject, getBundleMetadataSources(), true,
- monitor);
+ metadataSources = getProjectMetadataSources(templateRequest, mavenProject, getBundleMetadataSources(),
+ mojoExecutions, true, monitor);
} catch(LifecycleMappingConfigurationException e) {
// could not read/parse/interpret mapping metadata configured in the pom or inherited from parent pom.
// record the problem and return
@@ -213,20 +217,26 @@
}
public static List<MappingMetadataSource> getProjectMetadataSources(MavenExecutionRequest templateRequest,
- MavenProject mavenProject, List<LifecycleMappingMetadataSource> bundleMetadataSources, boolean includeDefault,
- IProgressMonitor monitor) throws CoreException, LifecycleMappingConfigurationException {
+ MavenProject mavenProject, List<LifecycleMappingMetadataSource> bundleMetadataSources,
+ List<MojoExecution> mojoExecutions, boolean includeDefault, IProgressMonitor monitor) throws CoreException,
+ LifecycleMappingConfigurationException {
List<MappingMetadataSource> metadataSources = new ArrayList<MappingMetadataSource>();
// List order
// 1. this pom embedded, this pom referenced, parent embedded, parent referenced, grand parent embedded...
// 2. sources contributed by eclipse extensions
- // 3. default source, if present
+ // 3. maven-plugin embedded metadata
+ // 4. default source, if present
// TODO validate metadata and replace invalid entries with error mapping
for(LifecycleMappingMetadataSource source : getPomMappingMetadataSources(mavenProject, templateRequest, monitor)) {
metadataSources.add(new SimpleMappingMetadataSource(source));
}
// TODO filter out invalid metadata from sources contributed by eclipse extensions and the default source
metadataSources.add(new SimpleMappingMetadataSource(bundleMetadataSources));
+ for(LifecycleMappingMetadataSource source : getMavenPluginEmbeddedMetadataSources(mojoExecutions,
+ mavenProject.getPluginArtifactRepositories(), monitor)) {
+ metadataSources.add(new SimpleMappingMetadataSource(source));
+ }
if(includeDefault) {
LifecycleMappingMetadataSource defaultSource = getDefaultLifecycleMappingMetadataSource();
if(defaultSource != null) {
@@ -237,6 +247,81 @@
return metadataSources;
}
+ private static List<LifecycleMappingMetadataSource> getMavenPluginEmbeddedMetadataSources(
+ List<MojoExecution> mojoExecutions, List<ArtifactRepository> remoteRepositories, IProgressMonitor monitor) {
+ Map<File, LifecycleMappingMetadataSource> result = new LinkedHashMap<File, LifecycleMappingMetadataSource>();
+
+ MavenImpl maven = (MavenImpl) MavenPlugin.getMaven();
+
+ for(MojoExecution execution : mojoExecutions) {
+ Artifact artifact;
+ try {
+ artifact = maven.resolvePluginArtifact(execution.getPlugin(), remoteRepositories, monitor);
+ } catch(CoreException e) {
+ // skip this plugin, it won't run anyways
+ continue;
+ }
+
+ File file = artifact.getFile();
+ if(file == null || result.containsKey(file) || !file.canRead()) {
+ continue;
+ }
+ LifecycleMappingMetadataSource metadata = readMavenPluginEmbeddedMetadata(artifact);
+ if(metadata != null) {
+ result.put(file, metadata);
+ }
+ }
+
+ return new ArrayList<LifecycleMappingMetadataSource>(result.values());
+ }
+
+ private static LifecycleMappingMetadataSource readMavenPluginEmbeddedMetadata(Artifact artifact) {
+ File file = artifact.getFile();
+ try {
+ if(file.isFile()) {
+ JarFile jar = new JarFile(file);
+ try {
+ ZipEntry entry = jar.getEntry("META-INF/m2e/lifecycle-mapping-metadata.xml");
+ if(entry == null) {
+ return null;
+ }
+ InputStream is = jar.getInputStream(entry);
+ return readMavenPluginEmbeddedMetadata(artifact, is);
+ } finally {
+ try {
+ jar.close();
+ } catch(IOException e) {
+ // too bad
+ }
+ }
+ } else if(file.isDirectory()) {
+ try {
+ InputStream is = new BufferedInputStream(new FileInputStream(new File(file,
+ "META-INF/m2e/lifecycle-mapping-metadata.xml")));
+ try {
+ return readMavenPluginEmbeddedMetadata(artifact, is);
+ } finally {
+ IOUtil.close(is);
+ }
+ } catch(FileNotFoundException e) {
+ // expected and tolerated
+ }
+ }
+ } catch(XmlPullParserException e) {
+ throw new LifecycleMappingConfigurationException("Cannot read lifecycle mapping metadata for artifact "
+ + artifact, e);
+ } catch(IOException e) {
+ throw new LifecycleMappingConfigurationException("Cannot read lifecycle mapping metadata for artifact "
+ + artifact, e);
+ }
+ return null;
+ }
+
+ private static LifecycleMappingMetadataSource readMavenPluginEmbeddedMetadata(Artifact artifact, InputStream is)
+ throws IOException, XmlPullParserException {
+ return new LifecycleMappingMetadataSourceXpp3Reader().read(is);
+ }
+
public static void calculateEffectiveLifecycleMappingMetadata(LifecycleMappingResult result,
MavenExecutionRequest templateRequest, List<MappingMetadataSource> metadataSources, MavenProject mavenProject,
List<MojoExecution> mojoExecutions, boolean applyDefaultStrategy) {
diff --git a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/lifecyclemapping/discovery/LifecycleMappingConfiguration.java b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/lifecyclemapping/discovery/LifecycleMappingConfiguration.java
index 61858d6..74bd7b5 100644
--- a/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/lifecyclemapping/discovery/LifecycleMappingConfiguration.java
+++ b/org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/lifecyclemapping/discovery/LifecycleMappingConfiguration.java
@@ -323,7 +323,7 @@
List<MappingMetadataSource> metadataSources;
try {
metadataSources = LifecycleMappingFactory.getProjectMetadataSources(request, mavenProject,
- LifecycleMappingFactory.getBundleMetadataSources(), true, monitor);
+ LifecycleMappingFactory.getBundleMetadataSources(), mojoExecutions, true, monitor);
} catch(LifecycleMappingConfigurationException e) {
// could not read/parse/interpret mapping metadata configured in the pom or inherited from parent pom.
// record the problem and continue
diff --git a/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/MavenDiscoveryService.java b/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/MavenDiscoveryService.java
index 658fbda..153eb80 100644
--- a/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/MavenDiscoveryService.java
+++ b/org.eclipse.m2e.discovery/src/org/eclipse/m2e/internal/discovery/MavenDiscoveryService.java
@@ -181,7 +181,7 @@
}
List<MappingMetadataSource> metadataSources = LifecycleMappingFactory.getProjectMetadataSources(request,
- mavenProject, sources, false, monitor);
+ mavenProject, sources, mojoExecutions, false, monitor);
LifecycleMappingFactory.calculateEffectiveLifecycleMappingMetadata(mappingResult, request, metadataSources,
mavenProject, mojoExecutions, false);
diff --git a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/SourcesGenerationProjectConfigurator.java b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/SourcesGenerationProjectConfigurator.java
index 6999452..64d0ece 100644
--- a/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/SourcesGenerationProjectConfigurator.java
+++ b/org.eclipse.m2e.jdt/src/org/eclipse/m2e/jdt/internal/SourcesGenerationProjectConfigurator.java
@@ -161,7 +161,7 @@
}
protected boolean shouldRunOnIncrementalBuild(MavenSession session, MojoExecution execution) throws CoreException {
- Boolean runOnIncremental = getConfiguratorParameterValue("sourceDirectory", Boolean.class, session, execution);
+ Boolean runOnIncremental = getConfiguratorParameterValue("runOnIncremental", Boolean.class, session, execution);
if(Boolean.FALSE.equals(runOnIncremental)) {
// we are explicitly told NOT to run on incremental build