Bug 552194 - Show warning when bundle's BREE lower than its dependencies
Change-Id: I04db9e86deda7319256bab4194115d1a9a4ffd69
Signed-off-by: Andrew Obuchowicz <aobuchow@redhat.com>
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDECoreMessages.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDECoreMessages.java
index c1f05ff..2178d14 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDECoreMessages.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDECoreMessages.java
@@ -213,6 +213,7 @@
public static String BundleErrorReporter_R4SyntaxInR3Bundle;
public static String BundleErrorReporter_NotExistPDE;
public static String BundleErrorReporter_EmptyTargetPlatform;
+ public static String BundleErrorReporter_ExecEnv_tooLow;
public static String BundleErrorReporter_HostNotExistPDE;
public static String BundleErrorReporter_HostNeeded;
public static String BundleErrorReporter_PackageNotExported;
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/BundleErrorReporter.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/BundleErrorReporter.java
index f86bef9..0b08f49 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/BundleErrorReporter.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/BundleErrorReporter.java
@@ -18,7 +18,10 @@
package org.eclipse.pde.internal.core.builders;
import java.io.File;
+import java.util.ArrayDeque;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
@@ -27,6 +30,8 @@
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
@@ -636,6 +641,128 @@
break;
}
}
+
+ // Check for highest BREE of bundle dependencies
+ String highestDependencyEE = checkBREE(desc);
+ String highestBundleEE = getHighestBREE(bundleEnvs);
+ try {
+ if (highestBundleEE != getHighestEE(highestDependencyEE, highestBundleEE)) {
+ VirtualMarker marker = report(
+ NLS.bind(PDECoreMessages.BundleErrorReporter_ExecEnv_tooLow,
+ highestDependencyEE, highestDependencyEE),
+ getLine(header, highestBundleEE), sev, PDEMarkerFactory.M_EXEC_ENV_TOO_LOW,
+ PDEMarkerFactory.CAT_EE);
+ addMarkerAttribute(marker, PDEMarkerFactory.REQUIRED_EXEC_ENV, highestDependencyEE);
+ }
+ } catch (Exception e) {
+ PDECore.log(e);
+ }
+ }
+
+ static final List<String> EXECUTION_ENVIRONMENT_NAMES = Arrays.asList("OSGi/Minimum", //$NON-NLS-1$
+ "CDC-1.0/Foundation", //$NON-NLS-1$
+ "CDC-1.1/Foundation", "JRE", "J2SE", "JavaSE"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+ private static String getHighestEE(String execEnv1, String execEnv2) throws IllegalArgumentException {
+ if (execEnv1 == null) {
+ return execEnv2;
+ } else if (execEnv2 == null) {
+ return execEnv1;
+ }
+
+ Pattern p = Pattern.compile("(.*)-(\\d+)\\.?(\\d+)?(.*)?"); //$NON-NLS-1$
+ Matcher eeMatcher1 = p.matcher(execEnv1);
+ Matcher eeMatcher2 = p.matcher(execEnv2);
+
+ if (!eeMatcher1.matches()) {
+ throw new IllegalArgumentException(String.format("%s is not a valid Execution Environment", execEnv1)); //$NON-NLS-1$
+ }
+ if (!eeMatcher2.matches()) {
+ throw new IllegalArgumentException(String.format("%s is not a valid Execution Environment", execEnv2)); //$NON-NLS-1$
+ }
+
+ String eeName1 = eeMatcher1.group(1);
+ String eeName2 = eeMatcher2.group(1);
+ int eeNameIndex1 = EXECUTION_ENVIRONMENT_NAMES.indexOf(eeName1);
+ int eeNameIndex2 = EXECUTION_ENVIRONMENT_NAMES.indexOf(eeName2);
+ int eeMajorVersion1 = Integer.parseInt(eeMatcher1.group(2));
+ int eeMajorVersion2 = Integer.parseInt(eeMatcher2.group(2));
+ Integer eeMinorVersion1 = null;
+ Integer eeMinorVersion2 = null;
+
+ if (eeMatcher1.groupCount() > 2) {
+ eeMinorVersion1 = Integer.valueOf(eeMatcher1.group(3));
+ }
+ if (eeMatcher2.groupCount() > 2) {
+ eeMinorVersion2 = Integer.valueOf(eeMatcher2.group(3));
+ }
+
+ if (eeNameIndex1 > eeNameIndex2) {
+ return execEnv1;
+ } else if (eeNameIndex1 < eeNameIndex2) {
+ return execEnv2;
+ }
+
+ // EE1 and EE2 have the same EE name
+ if (eeMajorVersion1 > eeMajorVersion2) {
+ return execEnv1;
+ } else if (eeMajorVersion1 < eeMajorVersion2) {
+ return execEnv2;
+ }
+
+ // EE1 and EE2 have the same major version
+ if (eeMinorVersion1 != null && eeMinorVersion2 != null) {
+ if (eeMinorVersion1 > eeMinorVersion2) {
+ return execEnv1;
+ } else if (eeMinorVersion1 < eeMinorVersion2) {
+ return execEnv2;
+ }
+ }
+
+ // EE1 == EE2
+ return execEnv1;
+ }
+
+ private String getHighestBREE(String[] executionEnvironments) {
+ if (executionEnvironments.length == 0) {
+ return null;
+ }
+ String highestExecEnv = executionEnvironments[0];
+ if (executionEnvironments.length > 1) {
+ for (String execEnv : executionEnvironments) {
+ try {
+ highestExecEnv = getHighestEE(highestExecEnv, execEnv);
+ } catch (Exception e) {
+ PDECore.log(e);
+ return null;
+ }
+
+ }
+ }
+
+ return highestExecEnv;
+ }
+
+ private String checkBREE(BundleDescription desc) {
+ String highestBREE = getHighestBREE(desc.getExecutionEnvironments());
+ HashSet<BundleDescription> visitedBundles = new HashSet<>();
+ Deque<BundleDescription> bundleDescriptions = new ArrayDeque<>();
+ bundleDescriptions.push(desc);
+ while (!bundleDescriptions.isEmpty()) {
+ BundleDescription dependencyDesc = bundleDescriptions.pop();
+ visitedBundles.add(dependencyDesc);
+ for (BundleDescription transitiveDependencyDesc : dependencyDesc.getResolvedRequires()) {
+ if (!visitedBundles.contains(transitiveDependencyDesc)) {
+ bundleDescriptions.push(transitiveDependencyDesc);
+ }
+ }
+ try {
+ highestBREE = getHighestEE(highestBREE, getHighestBREE(dependencyDesc.getExecutionEnvironments()));
+ } catch (Exception e) {
+ PDECore.log(e);
+ }
+ }
+ return highestBREE;
}
/**
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/PDEMarkerFactory.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/PDEMarkerFactory.java
index 85f0dc3..ea6af55 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/PDEMarkerFactory.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/PDEMarkerFactory.java
@@ -77,6 +77,7 @@
public static final int M_SERVICECOMPONENT_MISSING_LAZY = 0x1026; // other problem
public static final int M_ONLY_CONFIG_SEV = 0x1027; // other problem
public static final int M_NO_AUTOMATIC_MODULE = 0x1028; // other problem
+ public static final int M_EXEC_ENV_TOO_LOW = 0x1029; // other problem
// build properties fixes
public static final int B_APPEND_SLASH_FOLDER_ENTRY = 0x2001;
@@ -99,6 +100,7 @@
public static final String MPK_LOCATION_PATH = "xmlTree.locationPath"; //$NON-NLS-1$
public static final String ATTR_CAN_ADD = "deprecatedAutostart.canAdd"; //$NON-NLS-1$
public static final String ATTR_HEADER = "deprecatedAutostart.header"; //$NON-NLS-1$
+ public static final String REQUIRED_EXEC_ENV = "executionEnvironment.key"; //$NON-NLS-1$
/**
* Boolean attribute for marker added when no newline is found at the end of a manifest. Value is
* <code>true</code> if there is character content on the last line that should be
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/pderesources.properties b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/pderesources.properties
index 894576d..2051238 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/pderesources.properties
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/pderesources.properties
@@ -174,6 +174,7 @@
BundleErrorReporter_BundleRangeInvalidInBundleVersion=Unsatisfied version constraint: ''{0}''
BundleErrorReporter_NotExistPDE=Bundle ''{0}'' cannot be resolved
BundleErrorReporter_EmptyTargetPlatform=Target Platform is not set
+BundleErrorReporter_ExecEnv_tooLow=One of the bundles dependencies requires an Execution Environment of {0}, thus this bundles Execution Environment should be set to at least {1}.
BundleErrorReporter_exportNoJRE=Cannot export packages prefixed with 'java'
BundleErrorReporter_importNoJRE=Cannot import packages prefixed with 'java'
BundleErrorReporter_HostNotExistPDE=Host bundle ''{0}'' cannot be resolved
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/Messages.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/Messages.java
new file mode 100644
index 0000000..71a608d
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/Messages.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * 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:
+ * Andrew Obuchowicz <aobuchow@redhat.com>
+ *******************************************************************************/
+package org.eclipse.pde.internal.ui.correction;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.pde.internal.ui.correction.messages"; //$NON-NLS-1$
+ public static String ReplaceExecEnvironment_Marker_Label;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ReplaceExecEnvironment.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ReplaceExecEnvironment.java
new file mode 100644
index 0000000..e38d17d
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ReplaceExecEnvironment.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2019 IBM Corporation and others.
+ *
+ * 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:
+ * Andrew Obuchowicz <aobuchow@redhat.com> - Initial Implementation
+ *******************************************************************************/
+package org.eclipse.pde.internal.ui.correction;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.pde.internal.core.builders.PDEMarkerFactory;
+import org.eclipse.pde.internal.core.ibundle.IManifestHeader;
+import org.eclipse.pde.internal.core.text.bundle.*;
+import org.osgi.framework.Constants;
+
+public class ReplaceExecEnvironment extends AbstractManifestMarkerResolution {
+
+ String fRequiredEE;
+
+ public ReplaceExecEnvironment(int type, IMarker marker) {
+ super(type, marker);
+ this.fRequiredEE = super.marker.getAttribute(PDEMarkerFactory.REQUIRED_EXEC_ENV, "JavaSE-1.8"); //$NON-NLS-1$
+ }
+
+ @Override
+ public String getLabel() {
+ return NLS.bind(Messages.ReplaceExecEnvironment_Marker_Label, this.fRequiredEE);
+ }
+
+ @Override
+ protected void createChange(BundleModel model) {
+ IManifestHeader header = model.getBundle().getManifestHeader(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT);
+ if (header instanceof RequiredExecutionEnvironmentHeader) {
+ RequiredExecutionEnvironmentHeader reqHeader = (RequiredExecutionEnvironmentHeader) header;
+ ExecutionEnvironment[] bundleEnvs = reqHeader.getEnvironments();
+ IExecutionEnvironment[] systemEnvs = JavaRuntime.getExecutionEnvironmentsManager()
+ .getExecutionEnvironments();
+
+ for (IExecutionEnvironment systemEnv : systemEnvs) {
+ if (systemEnv.getId().equals(fRequiredEE)) {
+ for (ExecutionEnvironment bundleEnv : bundleEnvs) {
+ reqHeader.removeExecutionEnvironment(bundleEnv);
+ }
+ reqHeader.addExecutionEnvironment(systemEnv);
+ }
+
+ }
+ }
+
+ }
+
+}
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ResolutionGenerator.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ResolutionGenerator.java
index 332ed9a..0d6e3fa 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ResolutionGenerator.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/ResolutionGenerator.java
@@ -80,7 +80,11 @@
case PDEMarkerFactory.M_MISMATCHED_EXEC_ENV :
return new IMarkerResolution[] {new UpdateClasspathResolution(AbstractPDEMarkerResolution.RENAME_TYPE, marker)};
case PDEMarkerFactory.M_UNKNOW_EXEC_ENV :
- return new IMarkerResolution[] {new RemoveUnknownExecEnvironments(AbstractPDEMarkerResolution.REMOVE_TYPE,marker)};
+ return new IMarkerResolution[] {
+ new RemoveUnknownExecEnvironments(AbstractPDEMarkerResolution.REMOVE_TYPE, marker) };
+ case PDEMarkerFactory.M_EXEC_ENV_TOO_LOW:
+ return new IMarkerResolution[] {
+ new ReplaceExecEnvironment(AbstractPDEMarkerResolution.RENAME_TYPE, marker) };
case PDEMarkerFactory.M_DEPRECATED_IMPORT_SERVICE :
return new IMarkerResolution[] {new RemoveImportExportServicesResolution(AbstractPDEMarkerResolution.REMOVE_TYPE, ICoreConstants.IMPORT_SERVICE, marker)};
case PDEMarkerFactory.M_DEPRECATED_EXPORT_SERVICE :
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/messages.properties b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/messages.properties
new file mode 100644
index 0000000..6193e6e
--- /dev/null
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/correction/messages.properties
@@ -0,0 +1,10 @@
+###############################################################################
+# Copyright (c) 2019 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+# Contributors:
+# Andrew Obuchowicz <aobuchow@redhat.com>
+###############################################################################
+ReplaceExecEnvironment_Marker_Label=Replace Bundle Execution Environment with ''{0}''
\ No newline at end of file