diff --git a/org.eclipse.m2e.pde.connector/META-INF/MANIFEST.MF b/org.eclipse.m2e.pde.connector/META-INF/MANIFEST.MF
index b391b693ce..6fed4b6ade 100644
--- a/org.eclipse.m2e.pde.connector/META-INF/MANIFEST.MF
+++ b/org.eclipse.m2e.pde.connector/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: M2E PDE Connector
Bundle-SymbolicName: org.eclipse.m2e.pde.connector;singleton:=true
-Bundle-Version: 2.0.1.qualifier
+Bundle-Version: 2.1.0.qualifier
Automatic-Module-Name: org.eclipse.m2e.pde.connector
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-Vendor: Eclipse.org - m2e
@@ -13,5 +13,7 @@ Require-Bundle: org.eclipse.m2e.core;bundle-version="[2.0.0,3.0.0)",
org.eclipse.core.resources;bundle-version="3.16.0",
org.eclipse.m2e.maven.runtime;bundle-version="[3.8.6,4.0.0)",
org.eclipse.pde.core,
- org.eclipse.jdt.core
+ org.eclipse.jdt.core,
+ org.eclipse.pde.ds.annotations,
+ org.eclipse.equinox.preferences
Bundle-Activator: org.eclipse.m2e.pde.connector.Activator
diff --git a/org.eclipse.m2e.pde.connector/lifecycle-mapping-metadata.xml b/org.eclipse.m2e.pde.connector/lifecycle-mapping-metadata.xml
index dff31e9b33..a4a4f51ccc 100644
--- a/org.eclipse.m2e.pde.connector/lifecycle-mapping-metadata.xml
+++ b/org.eclipse.m2e.pde.connector/lifecycle-mapping-metadata.xml
@@ -51,6 +51,37 @@
+
+
+ org.eclipse.tycho
+ tycho-packaging-plugin
+ [1.0.0,)
+
+ package-plugin
+ package-feature
+
+
+
+
+ org.apache.m2e.pde.connector.configurator.tycho
+
+
+
+
+
+ org.eclipse.tycho
+ tycho-surefire-plugin
+ [1.0.0,)
+
+ test
+
+
+
+
+ org.apache.m2e.pde.connector.configurator.tycho
+
+
+
diff --git a/org.eclipse.m2e.pde.connector/plugin.xml b/org.eclipse.m2e.pde.connector/plugin.xml
index 98133496a7..f8c318529a 100644
--- a/org.eclipse.m2e.pde.connector/plugin.xml
+++ b/org.eclipse.m2e.pde.connector/plugin.xml
@@ -6,9 +6,15 @@
+ name="PDE integration for Maven bundle plugin projects">
+
+
+
diff --git a/org.eclipse.m2e.pde.connector/src/org/eclipse/m2e/pde/connector/PDEMavenBundlePluginConfigurator.java b/org.eclipse.m2e.pde.connector/src/org/eclipse/m2e/pde/connector/PDEMavenBundlePluginConfigurator.java
index 111505b23a..fa0a3c1d85 100644
--- a/org.eclipse.m2e.pde.connector/src/org/eclipse/m2e/pde/connector/PDEMavenBundlePluginConfigurator.java
+++ b/org.eclipse.m2e.pde.connector/src/org/eclipse/m2e/pde/connector/PDEMavenBundlePluginConfigurator.java
@@ -23,11 +23,13 @@
import org.eclipse.m2e.core.MavenPlugin;
import org.eclipse.m2e.core.embedder.IMaven;
import org.eclipse.m2e.core.internal.IMavenConstants;
+import org.eclipse.m2e.core.internal.markers.IMavenMarkerManager;
import org.eclipse.m2e.core.internal.markers.MavenProblemInfo;
import org.eclipse.m2e.core.internal.markers.SourceLocation;
import org.eclipse.m2e.core.internal.markers.SourceLocationHelper;
import org.eclipse.m2e.core.lifecyclemapping.model.IPluginExecutionMetadata;
import org.eclipse.m2e.core.project.IMavenProjectFacade;
+import org.eclipse.m2e.core.project.IMavenProjectRegistry;
import org.eclipse.m2e.core.project.configurator.AbstractBuildParticipant;
import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator;
import org.eclipse.m2e.core.project.configurator.ILifecycleMappingConfiguration;
@@ -92,6 +94,11 @@ public void configure(ProjectConfigurationRequest request, IProgressMonitor moni
private void createWarningMarker(ProjectConfigurationRequest request, MojoExecution execution, String attribute,
String message) {
+ createWarningMarker(projectManager, markerManager, request, execution, attribute, message);
+ }
+
+ static void createWarningMarker(IMavenProjectRegistry projectManager, IMavenMarkerManager markerManager,
+ ProjectConfigurationRequest request, MojoExecution execution, String attribute, String message) {
SourceLocation location = SourceLocationHelper.findLocation(execution.getPlugin(), attribute);
String[] gav = location.getResourceId().split(":");
diff --git a/org.eclipse.m2e.pde.connector/src/org/eclipse/m2e/pde/connector/PDEProjectHelper.java b/org.eclipse.m2e.pde.connector/src/org/eclipse/m2e/pde/connector/PDEProjectHelper.java
index 4a6e650532..0ac78d8b64 100644
--- a/org.eclipse.m2e.pde.connector/src/org/eclipse/m2e/pde/connector/PDEProjectHelper.java
+++ b/org.eclipse.m2e.pde.connector/src/org/eclipse/m2e/pde/connector/PDEProjectHelper.java
@@ -86,7 +86,7 @@ public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
}
@SuppressWarnings("restriction")
- public void configurePDEBundleProject(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
+ public static void configurePDEBundleProject(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
throws CoreException {
// see org.eclipse.pde.internal.ui.wizards.plugin.NewProjectCreationOperation
@@ -118,7 +118,7 @@ public void configurePDEBundleProject(IProject project, MavenProject mavenProjec
}
@SuppressWarnings("restriction")
- private void addProjectForUpdateClasspath(IProject project) {
+ private static void addProjectForUpdateClasspath(IProject project) {
synchronized (PROJECTS_FOR_UPDATE_CLASSPATH) {
PROJECTS_FOR_UPDATE_CLASSPATH.add(project);
if (!isListeningForPluginModelChanges) {
@@ -129,7 +129,7 @@ private void addProjectForUpdateClasspath(IProject project) {
}
}
- private IPath getOutputLocation(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
+ private static IPath getOutputLocation(IProject project, MavenProject mavenProject, IProgressMonitor monitor)
throws CoreException {
File outputDirectory = new File(mavenProject.getBuild().getOutputDirectory());
outputDirectory.mkdirs();
diff --git a/org.eclipse.m2e.pde.connector/src/org/eclipse/m2e/pde/connector/TychoPackagingsConfigurator.java b/org.eclipse.m2e.pde.connector/src/org/eclipse/m2e/pde/connector/TychoPackagingsConfigurator.java
new file mode 100644
index 0000000000..ef941525d5
--- /dev/null
+++ b/org.eclipse.m2e.pde.connector/src/org/eclipse/m2e/pde/connector/TychoPackagingsConfigurator.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2022 Konrad Windszus
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Konrad Windszus
+ *******************************************************************************/
+package org.eclipse.m2e.pde.connector;
+
+import java.util.List;
+
+import org.apache.maven.plugin.MojoExecution;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.m2e.core.internal.markers.SourceLocationHelper;
+import org.eclipse.m2e.core.project.configurator.AbstractProjectConfigurator;
+import org.eclipse.m2e.core.project.configurator.ProjectConfigurationRequest;
+import org.eclipse.pde.ds.internal.annotations.DSAnnotationVersion;
+import org.eclipse.pde.internal.core.natures.PDE;
+import org.osgi.framework.Version;
+
+@SuppressWarnings("restriction")
+public class TychoPackagingsConfigurator extends AbstractProjectConfigurator {
+
+ private static final String TYCHO_GROUP_ID = "org.eclipse.tycho";
+ private static final String TYCHO_DS_PLUGIN_ARTIFACT_ID = "tycho-ds-plugin";
+ private static final String GOAL_DECLARATIVE_SERVICES = "declarative-services";
+
+ @Override
+ public void configure(ProjectConfigurationRequest request, IProgressMonitor monitor) throws CoreException {
+ MavenProject mavenProject = request.mavenProject();
+ IProject project = request.mavenProjectFacade().getProject();
+ String packaging = mavenProject.getPackaging();
+ if ("eclipse-plugin".equals(packaging) || "eclipse-test-plugin".equals(packaging)) {
+ PDEProjectHelper.configurePDEBundleProject(project, mavenProject, monitor);
+ applyDsConfiguration(request, monitor);
+ } else if ("eclipse-feature".equals(packaging)) {
+ // see
+ // org.eclipse.pde.internal.ui.wizards.feature.AbstractCreateFeatureOperation
+ if (!project.hasNature(PDE.FEATURE_NATURE)) {
+ addNature(project, PDE.FEATURE_NATURE, monitor);
+ }
+ }
+ }
+
+ private void applyDsConfiguration(ProjectConfigurationRequest request, IProgressMonitor monitor)
+ throws CoreException {
+ List mojoExecutions = getTychoDsPluginMojoExecutions(request, monitor);
+ if (mojoExecutions.isEmpty()) {
+ return;
+ }
+ if (mojoExecutions.size() > 1) {
+ String message = String.format(
+ "Found more than one execution for plugin %s:%s and goal %s, only consider configuration of this one",
+ TYCHO_GROUP_ID, TYCHO_DS_PLUGIN_ARTIFACT_ID, GOAL_DECLARATIVE_SERVICES);
+ createWarningMarker(request, mojoExecutions.get(0), "executions", message);
+ }
+ // first mojo execution is relevant
+ Xpp3Dom dom = mojoExecutions.get(0).getConfiguration();
+ // apply PDE configuration for DS
+ IEclipsePreferences prefs = new ProjectScope(request.mavenProjectFacade().getProject())
+ .getNode(org.eclipse.pde.ds.internal.annotations.Activator.PLUGIN_ID);
+ Xpp3Dom dsEnabled = dom.getChild("enabled");
+ boolean isDsEnabled = false;
+ if (dsEnabled != null && !dsEnabled.getValue().isEmpty()) {
+ isDsEnabled = Boolean.valueOf(dsEnabled.getValue());
+ prefs.putBoolean(org.eclipse.pde.ds.internal.annotations.Activator.PREF_ENABLED, isDsEnabled);
+ }
+ if (isDsEnabled) {
+ Xpp3Dom dsVersion = dom.getChild("dsVersion");
+ if (containsExplicitConfigurationValue(dsVersion)) {
+ String versionValue = dsVersion.getValue();
+ DSAnnotationVersion version = parseVersion(versionValue);
+ if (version != null) {
+ prefs.put(org.eclipse.pde.ds.internal.annotations.Activator.PREF_SPEC_VERSION, version.name());
+ } else {
+ String message = "Unsupported DS spec version " + versionValue + " found, using default instead";
+ createWarningMarker(request, mojoExecutions.get(0), SourceLocationHelper.CONFIGURATION, message);
+ }
+ }
+ Xpp3Dom path = dom.getChild("path");
+ if (containsExplicitConfigurationValue(path)) {
+ prefs.put(org.eclipse.pde.ds.internal.annotations.Activator.PREF_PATH, path.getValue());
+ }
+ }
+ }
+
+ private boolean containsExplicitConfigurationValue(Xpp3Dom config) {
+ // check if value is a property name
+ return config != null && !config.getValue().startsWith("${");
+ }
+
+ private DSAnnotationVersion parseVersion(String version) {
+ if (version.startsWith("V")) {
+ version = version.substring(1).replace('_', '.');
+ }
+ try {
+ Version osgiVersion = Version.parseVersion(version);
+ if (osgiVersion.getMajor() == 1 && osgiVersion.getMinor() == 1) {
+ return DSAnnotationVersion.V1_1;
+ } else if (osgiVersion.getMajor() == 1 && osgiVersion.getMinor() == 2) {
+ return DSAnnotationVersion.V1_2;
+ } else if (osgiVersion.getMajor() == 1 && osgiVersion.getMinor() == 3) {
+ return DSAnnotationVersion.V1_3;
+ }
+ } catch (IllegalArgumentException e) { // assume no match
+ }
+ return null;
+ }
+
+ private List getTychoDsPluginMojoExecutions(ProjectConfigurationRequest request,
+ IProgressMonitor monitor) throws CoreException {
+ return request.mavenProjectFacade().getMojoExecutions(TYCHO_GROUP_ID, TYCHO_DS_PLUGIN_ARTIFACT_ID, monitor,
+ GOAL_DECLARATIVE_SERVICES);
+ }
+
+ private void createWarningMarker(ProjectConfigurationRequest request, MojoExecution execution, String attribute,
+ String message) {
+ PDEMavenBundlePluginConfigurator.createWarningMarker(projectManager, markerManager, request, execution,
+ attribute, message);
+ }
+}