diff --git a/org.eclipse.m2e.pde.target.tests/src/org/eclipse/m2e/pde/target/tests/OSGiMetadataGenerationTest.java b/org.eclipse.m2e.pde.target.tests/src/org/eclipse/m2e/pde/target/tests/OSGiMetadataGenerationTest.java index eee1f8d49..8c4547858 100644 --- a/org.eclipse.m2e.pde.target.tests/src/org/eclipse/m2e/pde/target/tests/OSGiMetadataGenerationTest.java +++ b/org.eclipse.m2e.pde.target.tests/src/org/eclipse/m2e/pde/target/tests/OSGiMetadataGenerationTest.java @@ -44,493 +44,614 @@ public class OSGiMetadataGenerationTest extends AbstractMavenTargetTest { - @Test - public void testWithEmptyMetaInfServices() throws Exception { - ITargetLocation target = resolveMavenTarget( - """ - - - - org.apache.qpid - qpid-jms-discovery - 2.7.0 - jar - - - - """); - assertStatusOk(getTargetStatus(target)); - } - - @Test - public void testNonJarArtifactInDependencies() throws Exception { - ITargetLocation target = resolveMavenTarget( - """ - - - - com.azure - azure-ai-openai - 1.0.0-beta.13 - jar - - - - """); - assertStatusOk(getTargetStatus(target)); - } - - @Test - public void testVersionRanges() throws Exception { - ITargetLocation target = resolveMavenTarget( - """ - - - - io.cucumber - cucumber-java - 7.21.1 - jar - - - - """); - assertStatusOk(getTargetStatus(target)); - } - - @Test - public void testBadDependencyInChain() throws Exception { - ITargetLocation target = resolveMavenTarget(""" - - - - edu.ucar - cdm - 4.5.5 - jar - - - - """); - assertStatusOk(getTargetStatus(target)); - } - - @Test - public void testBadSymbolicName() throws Exception { - ITargetLocation target = resolveMavenTarget(""" - - - - javax.xml.ws - jaxws-api - 2.3.1 - - - - """); - assertStatusOk(getTargetStatus(target)); - } - - @Test - public void testWithClassifierFailsToCollect() throws Exception { - String targetXML = """ - - - - org.ehcache - ehcache - 3.10.0 - jar - jakarta - - - - """; - for (String deepth : new String[] { "none", "direct", "infinite" }) { - ITargetLocation target = resolveMavenTarget(targetXML.replace("%depth%", deepth)); - assertStatusOk(getTargetStatus(target)); - TargetBundle[] bundles = target.getBundles(); - for (TargetBundle targetBundle : bundles) { - URI location = targetBundle.getBundleInfo().getLocation(); - assertTrue( - "bundle with classifier was not correctly fetched width deepth = " + deepth + " location = " - + location, - location.toString().endsWith("org/ehcache/ehcache/3.10.0/ehcache-3.10.0-jakarta.jar")); - } - } - } - - @Test - @Ignore("see https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/issues/5987") - public void testSourceWithSignature() throws Exception { - ITargetLocation target = resolveMavenTarget( - """ - - - - org.eclipse.lemminx - org.eclipse.lemminx - 0.29.0 - jar - - - - - lemminx-releases - https://repo.eclipse.org/content/repositories/lemminx-releases/ - - - - """); - assertStatusOk(getTargetStatus(target)); - TargetBundle[] allBundles = target.getBundles(); - boolean sourcesFound = false; - for (TargetBundle targetBundle : allBundles) { - if (targetBundle.isSourceBundle()) { - sourcesFound = true; - assertValidSignature(targetBundle); - } - } - assertTrue("No source bundle generated!", sourcesFound); - } - - @Test - public void testArtifactWithSignature() throws Exception { - ITargetLocation target = resolveMavenTarget( - """ - - - - org.verapdf - core - 1.26.5 - - - - """); - assertStatusOk(getTargetStatus(target)); - TargetBundle[] allBundles = target.getBundles(); - for (TargetBundle targetBundle : allBundles) { - assertValidSignature(targetBundle); - } - assertTrue("No bundle generated!", allBundles.length > 0); - } - - @Test - public void testBadDependencyDirect() throws Exception { - ITargetLocation target = resolveMavenTarget(""" - - - - com.ibm.icu - icu4j - 2.6.1 - jar - - - - """); - IStatus targetStatus = getTargetStatus(target); - assertEquals(String.valueOf(targetStatus), IStatus.ERROR, targetStatus.getSeverity()); - } - - @Test - public void testMissingOptionalDependency() throws Exception { - ITargetLocation target = resolveMavenTarget(""" - - - - net.sf.saxon - Saxon-HE - 10.9 - jar - - - - """); - assertStatusOk(getTargetStatus(target)); - } - - @Test - public void testNonOSGiArtifact_missingArtifactError() throws Exception { - ITargetLocation target = resolveMavenTarget(""" - - - - com.google.errorprone - error_prone_annotations - 2.18.0 - jar - - - - """); - IStatus targetStatus = getTargetStatus(target); - assertEquals(String.valueOf(targetStatus), IStatus.ERROR, targetStatus.getSeverity()); - - assertEquals(1, targetStatus.getChildren().length); - String notABundleErrorMessage = "com.google.errorprone:error_prone_annotations:jar:2.18.0 is not a bundle"; - assertEquals(notABundleErrorMessage, targetStatus.getChildren()[0].getMessage()); - - assertArrayEquals(EMPTY, target.getFeatures()); - TargetBundle[] allBundles = target.getBundles(); - assertEquals(1, allBundles.length); - IStatus status = allBundles[0].getStatus(); - assertEquals(IStatus.ERROR, status.getSeverity()); - assertEquals(notABundleErrorMessage, status.getMessage()); - } - - @Test - public void testNonOSGiArtifact_missingArtifactIgnore() throws Exception { - ITargetLocation target = resolveMavenTarget(""" - - - - com.google.errorprone - error_prone_annotations - 2.18.0 - jar - - - - """); - assertStatusOk(getTargetStatus(target)); - assertArrayEquals(EMPTY, target.getFeatures()); - assertArrayEquals(EMPTY, target.getBundles()); - } - - @Test - public void testNonOSGiArtifact_missingArtifactGenerate_defaultInstructions() throws Exception { - ITargetLocation target = resolveMavenTarget(""" - - - - com.google.errorprone - error_prone_annotations - 2.18.0 - jar - - - - """); - assertStatusOk(getTargetStatus(target)); - assertArrayEquals(EMPTY, target.getFeatures()); - ExpectedBundle expectedBundle = generatedBundle("wrapped.com.google.errorprone.error_prone_annotations", - "2.18.0", "com.google.errorprone:error_prone_annotations"); - assertTargetBundles(target, withSourceBundles(List.of(expectedBundle))); - - // Validate generated metadata - Attributes attributes = getManifestMainAttributes(getGeneratedBundle(target)); - assertEquals("wrapped.com.google.errorprone.error_prone_annotations", - attributes.getValue(Constants.BUNDLE_SYMBOLICNAME)); - assertEquals("Bundle derived from maven artifact com.google.errorprone:error_prone_annotations:2.18.0", - attributes.getValue(Constants.BUNDLE_NAME)); - assertEqualManifestHeaders(Constants.IMPORT_PACKAGE, attributes, "java.lang;resolution:=optional", - "java.lang.annotation;resolution:=optional", "javax.lang.model.element;resolution:=optional"); - assertEqualManifestHeaders(Constants.EXPORT_PACKAGE, attributes, - "com.google.errorprone.annotations;version=\"2.18.0\";uses:=\"javax.lang.model.element\"", - "com.google.errorprone.annotations.concurrent;version=\"2.18.0\""); - assertNull(attributes.getValue(Constants.REQUIRE_BUNDLE)); - assertEquals("*", attributes.getValue(Constants.DYNAMICIMPORT_PACKAGE)); - - Attributes sourceAttributes = getManifestMainAttributes(getGeneratedSourceBundle(target)); - assertEquals("wrapped.com.google.errorprone.error_prone_annotations.source", - sourceAttributes.getValue(Constants.BUNDLE_SYMBOLICNAME)); - assertEquals("Source Bundle for wrapped.com.google.errorprone.error_prone_annotations:2.18.0", - sourceAttributes.getValue(Constants.BUNDLE_NAME)); - assertEqualManifestHeaders("Eclipse-SourceBundle", sourceAttributes, - "wrapped.com.google.errorprone.error_prone_annotations;version=\"2.18.0\";roots:=\".\""); - assertNull(sourceAttributes.getValue(Constants.IMPORT_PACKAGE)); - assertNull(sourceAttributes.getValue(Constants.EXPORT_PACKAGE)); - assertNull(sourceAttributes.getValue(Constants.REQUIRE_BUNDLE)); - assertNull(sourceAttributes.getValue(Constants.DYNAMICIMPORT_PACKAGE)); - } - - @Test - public void testConditionalPackage() throws Exception { - ITargetLocation target = resolveMavenTarget( - """ - - - - org.apache.maven.archetype - archetype-common - 3.3.1 - jar - - - - - """); - assertStatusOk(getTargetStatus(target)); - TargetBundle[] bundles = target.getBundles(); - for (TargetBundle bundle : bundles) { - BundleInfo bundleInfo = bundle.getBundleInfo(); - File file = new File(bundleInfo.getLocation()); - try (Jar jar = new Jar(file)) { - Set resources = jar.getResources().keySet(); - assertTrue("Conditional package org.apache.commons.* not included.", - resources.stream().anyMatch(s -> s.startsWith("org/apache/commons/"))); - } - ; - } - } - - @Test - public void testNonOSGiArtifact_missingArtifactGenerate_customInstructions() throws Exception { - ITargetLocation target = resolveMavenTarget( - """ - - - - com.google.errorprone - error_prone_annotations - 2.18.0 - jar - - - - - """); - assertStatusOk(getTargetStatus(target)); - assertArrayEquals(EMPTY, target.getFeatures()); - ExpectedBundle expectedBundle = generatedBundle("m2e.custom.test.wrapped.error_prone_annotations", "2.18.0", - "com.google.errorprone:error_prone_annotations"); - assertTargetBundles(target, withSourceBundles(List.of(expectedBundle))); - - // Validate generated metadata - Attributes attributes = getManifestMainAttributes(getGeneratedBundle(target)); - assertEquals("m2e.custom.test.wrapped.error_prone_annotations", - attributes.getValue(Constants.BUNDLE_SYMBOLICNAME)); - assertEquals("Bundle in Test from artifact com.google.errorprone:error_prone_annotations:2.18.0:", - attributes.getValue(Constants.BUNDLE_NAME)); - assertEqualManifestHeaders(Constants.IMPORT_PACKAGE, attributes, "java.lang", "java.lang.annotation", - "javax.lang.model.element"); - assertEqualManifestHeaders(Constants.EXPORT_PACKAGE, attributes, - "com.google.errorprone.annotations;version=\"2.18.0\";uses:=\"javax.lang.model.element\"", - "com.google.errorprone.annotations.concurrent;version=\"2.18.0\""); - assertNull(attributes.getValue(Constants.REQUIRE_BUNDLE)); - assertNull(attributes.getValue(Constants.DYNAMICIMPORT_PACKAGE)); - - Attributes sourceAttributes = getManifestMainAttributes(getGeneratedSourceBundle(target)); - assertEquals("m2e.custom.test.wrapped.error_prone_annotations.source", - sourceAttributes.getValue(Constants.BUNDLE_SYMBOLICNAME)); - assertEquals("Source Bundle for m2e.custom.test.wrapped.error_prone_annotations:2.18.0", - sourceAttributes.getValue(Constants.BUNDLE_NAME)); - assertEqualManifestHeaders("Eclipse-SourceBundle", sourceAttributes, - "m2e.custom.test.wrapped.error_prone_annotations;version=\"2.18.0\";roots:=\".\""); - assertNull(sourceAttributes.getValue(Constants.IMPORT_PACKAGE)); - assertNull(sourceAttributes.getValue(Constants.EXPORT_PACKAGE)); - assertNull(sourceAttributes.getValue(Constants.REQUIRE_BUNDLE)); - assertNull(sourceAttributes.getValue(Constants.DYNAMICIMPORT_PACKAGE)); - } - - @Test - public void testNonOSGiArtifact_missingArtifactGenerate_changedCustomInstructions() throws Exception { - String targetXML = """ - - - - com.google.errorprone - error_prone_annotations - 2.18.0 - jar - - - - - """; - ITargetLocation target = resolveMavenTarget(targetXML.formatted("m2e.wrapped.${mvnArtifactId}")); - assertStatusOk(getTargetStatus(target)); - assertArrayEquals(EMPTY, target.getFeatures()); - assertEquals(2, target.getBundles().length); - assertEquals("m2e.wrapped.error_prone_annotations", - getGeneratedBundle(target).getBundleInfo().getSymbolicName()); - assertEquals("m2e.wrapped.error_prone_annotations.source", - getGeneratedSourceBundle(target).getBundleInfo().getSymbolicName()); - - target = resolveMavenTarget(targetXML.formatted("others.wrapped.${mvnArtifactId}")); - assertStatusOk(getTargetStatus(target)); - assertArrayEquals(EMPTY, target.getFeatures()); - assertEquals(2, target.getBundles().length); - assertEquals("others.wrapped.error_prone_annotations", - getGeneratedBundle(target).getBundleInfo().getSymbolicName()); - assertEquals("others.wrapped.error_prone_annotations.source", - getGeneratedSourceBundle(target).getBundleInfo().getSymbolicName()); - } - - @Test - public void testNonOSGiArtifact_missingArtifactGenerate_hasVersions() throws Exception { - ITargetLocation target = resolveMavenTarget( - """ - - - - org.apache.lucene - lucene-analysis-common - 9.5.0 - jar - - - - """); - assertStatusOk(getTargetStatus(target)); - Optional luceneAnalysisCommon = Arrays.stream(target.getBundles()).filter( - tb -> tb.getBundleInfo().getSymbolicName().equals("wrapped.org.apache.lucene.lucene-analysis-common")) - .findFirst(); - assertTrue("lucene-analysis-common bundle not found in target state", luceneAnalysisCommon.isPresent()); - Attributes manifest = getManifestMainAttributes(luceneAnalysisCommon.get()); - ManifestElement[] importHeader = parseHeader(Constants.IMPORT_PACKAGE, - manifest.getValue(Constants.IMPORT_PACKAGE)); - for (ManifestElement element : importHeader) { - String value = element.getValue(); - if (value.startsWith("org.apache.lucene.")) { - String attribute = element.getAttribute(Constants.VERSION_ATTRIBUTE); - assertNotNull("Package " + value + " has no version attribute: " + element, attribute); - VersionRange versionRange = VersionRange.valueOf(attribute); - assertEquals("Unexpected version range " + versionRange + " on package " + value + ": " + element, 0, - versionRange.getLeft().compareTo(Version.valueOf("9.5.0"))); - } - } - } - - private static TargetBundle getGeneratedBundle(ITargetLocation target) { - return Arrays.stream(target.getBundles()).filter(b -> !b.isSourceBundle()).findFirst().orElseThrow(); - } - - private static TargetBundle getGeneratedSourceBundle(ITargetLocation target) { - return Arrays.stream(target.getBundles()).filter(TargetBundle::isSourceBundle).findFirst().orElseThrow(); - } - - private static void assertEqualManifestHeaders(String header, Attributes mainManifestAttributes, - String... expectedHeaderValues) throws BundleException { - ManifestElement[] expected = parseHeader(header, String.join(",", expectedHeaderValues)); - ManifestElement[] actual = parseHeader(header, mainManifestAttributes.getValue(header)); - Function toString = a -> Arrays.stream(a).map(ManifestElement::toString) - .toArray(String[]::new); - assertEquals(Set.of(toString.apply(expected)), Set.of(toString.apply(actual))); // order is irrelevant - } + @Test + public void testWithEmptyMetaInfServices_generate() throws Exception { + testWithEmptyMetaInfServices("generate"); + } + + @Test + public void testWithEmptyMetaInfServices_generateRewrite() throws Exception { + testWithEmptyMetaInfServices("generate_rewrite"); + + } + + private void testWithEmptyMetaInfServices(String missingManifestMode) throws Exception { + ITargetLocation target = resolveMavenTarget(String.format(// + """ + + + + org.apache.qpid + qpid-jms-discovery + 2.7.0 + jar + + + + """, missingManifestMode)); + assertStatusOk(getTargetStatus(target)); + } + + @Test + public void testNonJarArtifactInDependencies_generate() throws Exception { + testNonJarArtifactInDependencies("generate"); + } + + @Test + public void testNonJarArtifactInDependencies_generateRewrite() throws Exception { + testNonJarArtifactInDependencies("generate_rewrite"); + } + + private void testNonJarArtifactInDependencies(String missingManifestMode) throws Exception { + ITargetLocation target = resolveMavenTarget(String.format(// + """ + + + + com.azure + azure-ai-openai + 1.0.0-beta.13 + jar + + + + """, missingManifestMode)); + assertStatusOk(getTargetStatus(target)); + } + + @Test + public void testVersionRanges_generate() throws Exception { + testVersionRanges("generate"); + } + + @Test + public void testVersionRanges_generateRewrite() throws Exception { + testVersionRanges("generate_rewrite"); + } + + private void testVersionRanges(String missingManifestMode) throws Exception { + ITargetLocation target = resolveMavenTarget(String.format(// + """ + + + + io.cucumber + cucumber-java + 7.21.1 + jar + + + + """, missingManifestMode)); + assertStatusOk(getTargetStatus(target)); + } + + @Test + public void testBadDependencyInChain_generate() throws Exception { + testBadDependencyInChain("generate"); + } + + @Test + public void testBadDependencyInChain_generateRewrite() throws Exception { + testBadDependencyInChain("generate_rewrite"); + } + + private void testBadDependencyInChain(String missingManifestMode) throws Exception { + ITargetLocation target = resolveMavenTarget(String.format(// + """ + + + + edu.ucar + cdm + 4.5.5 + jar + + + + """, missingManifestMode)); + assertStatusOk(getTargetStatus(target)); + } + + @Test + public void testBadSymbolicName_generate() throws Exception { + testBadSymbolicName("generate"); + } + + @Test + public void testBadSymbolicName_generateRewrite() throws Exception { + testBadSymbolicName("generate_rewrite"); + } + + private void testBadSymbolicName(String missingManifestMode) throws Exception { + ITargetLocation target = resolveMavenTarget(String.format(// + """ + + + + javax.xml.ws + jaxws-api + 2.3.1 + + + + """, missingManifestMode)); + assertStatusOk(getTargetStatus(target)); + } + + @Test + public void testWithClassifierFailsToCollect_generate_depthNone() throws Exception { + testWithClassifierFailsToCollect("none", "generate"); + } + + @Test + public void testWithClassifierFailsToCollect_generateRewrite_depthNone() throws Exception { + testWithClassifierFailsToCollect("none", "generate_rewrite"); + } + + @Test + public void testWithClassifierFailsToCollect_generate_depthDirect() throws Exception { + testWithClassifierFailsToCollect("direct", "generate"); + } + + @Test + public void testWithClassifierFailsToCollect_generateRewrite_depthDirect() throws Exception { + testWithClassifierFailsToCollect("direct", "generate_rewrite"); + } + + @Test + public void testWithClassifierFailsToCollect_generate_depthInfinite() throws Exception { + testWithClassifierFailsToCollect("infinite", "generate"); + } + + @Test + public void testWithClassifierFailsToCollect_generateRewrite_depthInfinite() throws Exception { + testWithClassifierFailsToCollect("infinite", "generate_rewrite"); + } + + private void testWithClassifierFailsToCollect(String depth, String missingManifestMode) throws Exception { + String targetXML = String.format(// + """ + + + + junit + junit + 4.13.2 + jar + sources + + + + """, depth, missingManifestMode); + ITargetLocation target = resolveMavenTarget(targetXML); + assertStatusOk(getTargetStatus(target)); + TargetBundle[] bundles = target.getBundles(); + for (TargetBundle targetBundle : bundles) { + URI location = targetBundle.getBundleInfo().getLocation(); + assertTrue("bundle with classifier was not correctly fetched width depth = " + depth + " location = " + + location, location.toString().matches(".*/junit/junit/4\\.13\\.2/.*/junit-4\\.13\\.2-sources\\.jar")); + } + } + + @Test + @Ignore("see https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/issues/5987") + public void testSourceWithSignature() throws Exception { + ITargetLocation target = resolveMavenTarget(""" + + + + org.eclipse.lemminx + org.eclipse.lemminx + 0.29.0 + jar + + + + + lemminx-releases + https://repo.eclipse.org/content/repositories/lemminx-releases/ + + + + """); + assertStatusOk(getTargetStatus(target)); + TargetBundle[] allBundles = target.getBundles(); + boolean sourcesFound = false; + for (TargetBundle targetBundle : allBundles) { + if (targetBundle.isSourceBundle()) { + sourcesFound = true; + assertValidSignature(targetBundle); + } + } + assertTrue("No source bundle generated!", sourcesFound); + } + + @Test + public void testArtifactWithSignature_generate() throws Exception { + testArtifactWithSignature("generate"); + } + + @Test + public void testArtifactWithSignature_generateRewrite() throws Exception { + testArtifactWithSignature("generate_rewrite"); + } + + private void testArtifactWithSignature(String missingManifestMode) throws Exception { + ITargetLocation target = resolveMavenTarget(String.format(// + """ + + + + org.verapdf + core + 1.26.5 + + + + """, missingManifestMode)); + assertStatusOk(getTargetStatus(target)); + TargetBundle[] allBundles = target.getBundles(); + for (TargetBundle targetBundle : allBundles) { + assertValidSignature(targetBundle); + } + assertTrue("No bundle generated!", allBundles.length > 0); + } + + @Test + public void testBadDependencyDirect_generate() throws Exception { + testBadDependencyDirect("generate"); + } + + @Test + public void testBadDependencyDirect_generateRewrite() throws Exception { + testBadDependencyDirect("generate_rewrite"); + } + + private void testBadDependencyDirect(String missingManifestMode) throws Exception { + ITargetLocation target = resolveMavenTarget(String.format(// + """ + + + + com.ibm.icu + icu4j + 2.6.1 + jar + + + + """, missingManifestMode)); + IStatus targetStatus = getTargetStatus(target); + assertEquals(String.valueOf(targetStatus), IStatus.ERROR, targetStatus.getSeverity()); + } + + @Test + public void testMissingOptionalDependency_generate() throws Exception { + testMissingOptionalDependency("generate"); + } + + @Test + public void testMissingOptionalDependency_generateRewrite() throws Exception { + testMissingOptionalDependency("generate_rewrite"); + } + + private void testMissingOptionalDependency(String missingManifestMode) throws Exception { + ITargetLocation target = resolveMavenTarget(String.format(// + """ + + + + net.sf.saxon + Saxon-HE + 10.9 + jar + + + + """, missingManifestMode)); + assertStatusOk(getTargetStatus(target)); + } + + @Test + public void testNonOSGiArtifact_missingArtifactError() throws Exception { + ITargetLocation target = resolveMavenTarget(""" + + + + com.google.errorprone + error_prone_annotations + 2.18.0 + jar + + + + """); + IStatus targetStatus = getTargetStatus(target); + assertEquals(String.valueOf(targetStatus), IStatus.ERROR, targetStatus.getSeverity()); + + assertEquals(1, targetStatus.getChildren().length); + String notABundleErrorMessage = "com.google.errorprone:error_prone_annotations:jar:2.18.0 is not a bundle"; + assertEquals(notABundleErrorMessage, targetStatus.getChildren()[0].getMessage()); + + assertArrayEquals(EMPTY, target.getFeatures()); + TargetBundle[] allBundles = target.getBundles(); + assertEquals(1, allBundles.length); + IStatus status = allBundles[0].getStatus(); + assertEquals(IStatus.ERROR, status.getSeverity()); + assertEquals(notABundleErrorMessage, status.getMessage()); + } + + @Test + public void testNonOSGiArtifact_missingArtifactIgnore() throws Exception { + ITargetLocation target = resolveMavenTarget(""" + + + + com.google.errorprone + error_prone_annotations + 2.18.0 + jar + + + + """); + assertStatusOk(getTargetStatus(target)); + assertArrayEquals(EMPTY, target.getFeatures()); + assertArrayEquals(EMPTY, target.getBundles()); + } + + @Test + public void testNonOSGiArtifact_missingArtifactGenerate_defaultInstructions() throws Exception { + testNonOSGiArtifact_missingArtifactGenerate_defaultInstructions("generate"); + } + + @Test + public void testNonOSGiArtifact_missingArtifactGenerateRewrite_defaultInstructions() throws Exception { + testNonOSGiArtifact_missingArtifactGenerate_defaultInstructions("generate_rewrite"); + } + + private void testNonOSGiArtifact_missingArtifactGenerate_defaultInstructions(String missingManifestMode) throws Exception { + ITargetLocation target = resolveMavenTarget(String.format(// + """ + + + + com.google.errorprone + error_prone_annotations + 2.18.0 + jar + + + + """, missingManifestMode)); + assertStatusOk(getTargetStatus(target)); + assertArrayEquals(EMPTY, target.getFeatures()); + ExpectedBundle expectedBundle = generatedBundle("wrapped.com.google.errorprone.error_prone_annotations", "2.18.0", "com.google.errorprone:error_prone_annotations"); + assertTargetBundles(target, withSourceBundles(List.of(expectedBundle))); + + // Validate generated metadata + Attributes attributes = getManifestMainAttributes(getGeneratedBundle(target)); + assertEquals("wrapped.com.google.errorprone.error_prone_annotations", attributes.getValue(Constants.BUNDLE_SYMBOLICNAME)); + assertEquals("Bundle derived from maven artifact com.google.errorprone:error_prone_annotations:2.18.0", attributes.getValue(Constants.BUNDLE_NAME)); + assertEqualManifestHeaders(Constants.IMPORT_PACKAGE, attributes, "java.lang;resolution:=optional", "java.lang.annotation;resolution:=optional", "javax.lang.model.element;resolution:=optional"); + assertEqualManifestHeaders(Constants.EXPORT_PACKAGE, attributes, "com.google.errorprone.annotations;version=\"2.18.0\";uses:=\"javax.lang.model.element\"", "com.google.errorprone.annotations.concurrent;version=\"2.18.0\""); + assertNull(attributes.getValue(Constants.REQUIRE_BUNDLE)); + assertEquals("*", attributes.getValue(Constants.DYNAMICIMPORT_PACKAGE)); + + Attributes sourceAttributes = getManifestMainAttributes(getGeneratedSourceBundle(target)); + assertEquals("wrapped.com.google.errorprone.error_prone_annotations.source", sourceAttributes.getValue(Constants.BUNDLE_SYMBOLICNAME)); + assertEquals("Source Bundle for wrapped.com.google.errorprone.error_prone_annotations:2.18.0", sourceAttributes.getValue(Constants.BUNDLE_NAME)); + assertEqualManifestHeaders("Eclipse-SourceBundle", sourceAttributes, "wrapped.com.google.errorprone.error_prone_annotations;version=\"2.18.0\";roots:=\".\""); + assertNull(sourceAttributes.getValue(Constants.IMPORT_PACKAGE)); + assertNull(sourceAttributes.getValue(Constants.EXPORT_PACKAGE)); + assertNull(sourceAttributes.getValue(Constants.REQUIRE_BUNDLE)); + assertNull(sourceAttributes.getValue(Constants.DYNAMICIMPORT_PACKAGE)); + } + + @Test + public void testConditionalPackage_generate() throws Exception { + testConditionalPackage("generate"); + } + + @Test + public void testConditionalPackage_generateRewrite() throws Exception { + testConditionalPackage("generate_rewrite"); + } + + private void testConditionalPackage(String missingManifestMode) throws Exception { + ITargetLocation target = resolveMavenTarget(String.format(// + """ + + + + org.apache.maven.archetype + archetype-common + 3.3.1 + jar + + + + + """, missingManifestMode)); + assertStatusOk(getTargetStatus(target)); + TargetBundle[] bundles = target.getBundles(); + for (TargetBundle bundle : bundles) { + BundleInfo bundleInfo = bundle.getBundleInfo(); + File file = new File(bundleInfo.getLocation()); + try (Jar jar = new Jar(file)) { + Set resources = jar.getResources().keySet(); + assertTrue("Conditional package org.apache.commons.* not included.", resources.stream().anyMatch(s -> s.startsWith("org/apache/commons/"))); + } + } + } + + @Test + public void testNonOSGiArtifact_missingArtifactGenerate_customInstructions() throws Exception { + testNonOSGiArtifact_missingArtifactGenerate_customInstructions("generate"); + } + + @Test + public void testNonOSGiArtifact_missingArtifactGenerateRewrite_customInstructions() throws Exception { + testNonOSGiArtifact_missingArtifactGenerate_customInstructions("generate_rewrite"); + } + + private void testNonOSGiArtifact_missingArtifactGenerate_customInstructions(String missingManifestMode) throws Exception { + ITargetLocation target = resolveMavenTarget(String.format(// + """ + + + + com.google.errorprone + error_prone_annotations + 2.18.0 + jar + + + + + """, missingManifestMode)); + assertStatusOk(getTargetStatus(target)); + assertArrayEquals(EMPTY, target.getFeatures()); + ExpectedBundle expectedBundle = generatedBundle("m2e.custom.test.wrapped.error_prone_annotations", "2.18.0", "com.google.errorprone:error_prone_annotations"); + assertTargetBundles(target, withSourceBundles(List.of(expectedBundle))); + + // Validate generated metadata + Attributes attributes = getManifestMainAttributes(getGeneratedBundle(target)); + assertEquals("m2e.custom.test.wrapped.error_prone_annotations", attributes.getValue(Constants.BUNDLE_SYMBOLICNAME)); + assertEquals("Bundle in Test from artifact com.google.errorprone:error_prone_annotations:2.18.0:", attributes.getValue(Constants.BUNDLE_NAME)); + assertEqualManifestHeaders(Constants.IMPORT_PACKAGE, attributes, "java.lang", "java.lang.annotation", "javax.lang.model.element"); + assertEqualManifestHeaders(Constants.EXPORT_PACKAGE, attributes, "com.google.errorprone.annotations;version=\"2.18.0\";uses:=\"javax.lang.model.element\"", "com.google.errorprone.annotations.concurrent;version=\"2.18.0\""); + assertNull(attributes.getValue(Constants.REQUIRE_BUNDLE)); + assertNull(attributes.getValue(Constants.DYNAMICIMPORT_PACKAGE)); + + Attributes sourceAttributes = getManifestMainAttributes(getGeneratedSourceBundle(target)); + assertEquals("m2e.custom.test.wrapped.error_prone_annotations.source", sourceAttributes.getValue(Constants.BUNDLE_SYMBOLICNAME)); + assertEquals("Source Bundle for m2e.custom.test.wrapped.error_prone_annotations:2.18.0", sourceAttributes.getValue(Constants.BUNDLE_NAME)); + assertEqualManifestHeaders("Eclipse-SourceBundle", sourceAttributes, "m2e.custom.test.wrapped.error_prone_annotations;version=\"2.18.0\";roots:=\".\""); + assertNull(sourceAttributes.getValue(Constants.IMPORT_PACKAGE)); + assertNull(sourceAttributes.getValue(Constants.EXPORT_PACKAGE)); + assertNull(sourceAttributes.getValue(Constants.REQUIRE_BUNDLE)); + assertNull(sourceAttributes.getValue(Constants.DYNAMICIMPORT_PACKAGE)); + } + + @Test + public void testNonOSGiArtifact_missingArtifactGenerate_changedCustomInstructions() throws Exception { + testNonOSGiArtifact_missingArtifactGenerate_changedCustomInstructions("generate"); + } + + @Test + public void testNonOSGiArtifact_missingArtifactGenerateRewrite_changedCustomInstructions() throws Exception { + testNonOSGiArtifact_missingArtifactGenerate_changedCustomInstructions("generate_rewrite"); + } + + private void testNonOSGiArtifact_missingArtifactGenerate_changedCustomInstructions(String missingManifestMode) throws Exception { + String targetXML = String.format(// + """ + + + + com.google.errorprone + error_prone_annotations + 2.18.0 + jar + + + + + """, missingManifestMode); + ITargetLocation target = resolveMavenTarget(targetXML.replace("%symbolicName%", "m2e.wrapped.${mvnArtifactId}")); + assertStatusOk(getTargetStatus(target)); + assertArrayEquals(EMPTY, target.getFeatures()); + assertEquals(2, target.getBundles().length); + assertEquals("m2e.wrapped.error_prone_annotations", getGeneratedBundle(target).getBundleInfo().getSymbolicName()); + assertEquals("m2e.wrapped.error_prone_annotations.source", getGeneratedSourceBundle(target).getBundleInfo().getSymbolicName()); + + target = resolveMavenTarget(targetXML.replace("%symbolicName%", "others.wrapped.${mvnArtifactId}")); + assertStatusOk(getTargetStatus(target)); + assertArrayEquals(EMPTY, target.getFeatures()); + assertEquals(2, target.getBundles().length); + assertEquals("others.wrapped.error_prone_annotations", getGeneratedBundle(target).getBundleInfo().getSymbolicName()); + assertEquals("others.wrapped.error_prone_annotations.source", getGeneratedSourceBundle(target).getBundleInfo().getSymbolicName()); + } + + @Test + public void testNonOSGiArtifact_missingArtifactGenerate_hasVersions() throws Exception { + testNonOSGiArtifact_missingArtifactGenerate_hasVersions("generate"); + } + + @Test + public void testNonOSGiArtifact_missingArtifactGenerateRewrite_hasVersions() throws Exception { + testNonOSGiArtifact_missingArtifactGenerate_hasVersions("generate_rewrite"); + } + + private void testNonOSGiArtifact_missingArtifactGenerate_hasVersions(String missingManifestMode) throws Exception { + ITargetLocation target = resolveMavenTarget(String.format(// + """ + + + + org.apache.lucene + lucene-analysis-common + 9.5.0 + jar + + + + """, missingManifestMode)); + assertStatusOk(getTargetStatus(target)); + Optional luceneAnalysisCommon = Arrays.stream(target.getBundles()).filter(tb -> tb.getBundleInfo().getSymbolicName().equals("wrapped.org.apache.lucene.lucene-analysis-common")).findFirst(); + assertTrue("lucene-analysis-common bundle not found in target state", luceneAnalysisCommon.isPresent()); + Attributes manifest = getManifestMainAttributes(luceneAnalysisCommon.get()); + ManifestElement[] importHeader = parseHeader(Constants.IMPORT_PACKAGE, manifest.getValue(Constants.IMPORT_PACKAGE)); + for (ManifestElement element : importHeader) { + String value = element.getValue(); + if (value.startsWith("org.apache.lucene.")) { + String attribute = element.getAttribute(Constants.VERSION_ATTRIBUTE); + assertNotNull("Package " + value + " has no version attribute: " + element, attribute); + VersionRange versionRange = VersionRange.valueOf(attribute); + assertEquals("Unexpected version range " + versionRange + " on package " + value + ": " + + element, 0, versionRange.getLeft().compareTo(Version.valueOf("9.5.0"))); + } + } + } + + private static TargetBundle getGeneratedBundle(ITargetLocation target) { + return Arrays.stream(target.getBundles()).filter(b -> !b.isSourceBundle()).findFirst().orElseThrow(); + } + + private static TargetBundle getGeneratedSourceBundle(ITargetLocation target) { + return Arrays.stream(target.getBundles()).filter(TargetBundle::isSourceBundle).findFirst().orElseThrow(); + } + + private static void assertEqualManifestHeaders(String header, Attributes mainManifestAttributes, String... expectedHeaderValues) + throws BundleException { + ManifestElement[] expected = parseHeader(header, String.join(",", expectedHeaderValues)); + ManifestElement[] actual = parseHeader(header, mainManifestAttributes.getValue(header)); + Function toString = a -> Arrays.stream(a).map(ManifestElement::toString).toArray(String[]::new); + assertEquals(Set.of(toString.apply(expected)), Set.of(toString.apply(actual))); // order is irrelevant + } } \ No newline at end of file diff --git a/org.eclipse.m2e.pde.target/src/org/eclipse/m2e/pde/target/MavenTargetBundle.java b/org.eclipse.m2e.pde.target/src/org/eclipse/m2e/pde/target/MavenTargetBundle.java index 2e8528815..a5cfb4e74 100644 --- a/org.eclipse.m2e.pde.target/src/org/eclipse/m2e/pde/target/MavenTargetBundle.java +++ b/org.eclipse.m2e.pde.target/src/org/eclipse/m2e/pde/target/MavenTargetBundle.java @@ -44,163 +44,173 @@ public class MavenTargetBundle extends TargetBundle { - private static final ILog LOGGER = Platform.getLog(MavenTargetBundle.class); - private TargetBundle bundle; - private IStatus status; - private final BundleInfo bundleInfo; - private boolean isWrapped; - private Artifact artifact; - - @Override - public BundleInfo getBundleInfo() { - if (bundle == null) { - return bundleInfo; - } - return bundle.getBundleInfo(); - } - - @Override - public boolean isSourceBundle() { - return bundle != null && bundle.isSourceBundle(); - } - - @Override - public BundleInfo getSourceTarget() { - if (bundle == null) { - return null; - } - return bundle.getSourceTarget(); - } - - @Override - public boolean isFragment() { - return bundle != null && bundle.isFragment(); - } - - @Override - public String getSourcePath() { - if (bundle == null) { - return null; - } - return bundle.getSourcePath(); - } - - public MavenTargetBundle(Artifact artifact, MavenTargetLocation location, IProgressMonitor monitor) { - this.artifact = artifact; - File file = artifact.getFile(); - this.bundleInfo = new BundleInfo(artifact.getGroupId() + "." + artifact.getArtifactId(), artifact.getVersion(), - file != null ? file.toURI() : null, -1, false); - try { - bundle = new TargetBundle(file); - } catch (Exception ex) { - MissingMetadataMode metadataMode = location.getMetadataMode(); - if (metadataMode == MissingMetadataMode.ERROR) { - status = Status.error(artifact + " is not a bundle", ex); - LOGGER.log(status); - } else if (metadataMode == MissingMetadataMode.GENERATE) { - try { - bundle = getWrappedArtifact(artifact, location, monitor); - isWrapped = true; - } catch (Exception e) { - // not possible then - String message = artifact + " is not a bundle and cannot be automatically bundled as such "; - if (e.getMessage() != null) { - message += " (" + e.getMessage() + ")"; - } - status = Status.error(message, e); - LOGGER.log(status); - } - } else { - status = Status.CANCEL_STATUS; - LOGGER.log(status); - } - } - } - - public Artifact getArtifact() { - return artifact; - } - - private static TargetBundle getWrappedArtifact(Artifact artifact, MavenTargetLocation location, - IProgressMonitor monitor) throws Exception { - IMaven maven = MavenPlugin.getMaven(); - List repositories = RepositoryUtils.toRepos(location.getAvailableArtifactRepositories(maven)); - Function instructionsLookup = node -> { - BNDInstructions instructions = location.getInstructionsForArtifact(node.getArtifact()); - return instructions == null ? BNDInstructions.getDefaultInstructionProperties() - : instructions.asProperties(); - }; - IMavenExecutionContext exeContext = IMavenExecutionContext.getThreadContext() - .orElseGet(maven::createExecutionContext); - MultiStatus bundleStatus = new MultiStatus(MavenTargetBundle.class, 0, - "Some problems where detected while wrapping " + artifact); - Path wrappedBundle = exeContext.execute((context, monitor1) -> { - RepositorySystem repoSystem = MavenPluginActivator.getDefault().getRepositorySystem(); - RepositorySystemSession repositorySession = context.getRepositorySession(); - try { - WrappedBundle wrap = MavenBundleWrapper.getWrappedArtifact(artifact, instructionsLookup, repositories, - repoSystem, repositorySession, context.getComponentLookup().lookup(SyncContextFactory.class)); - List directErrors = wrap.messages(false) - .filter(msg -> msg.type() == ProcessingMessage.Type.ERROR).toList(); - if (directErrors.isEmpty()) { - // treat all items as warnings.... - wrap.messages(true).map(ProcessingMessage::message).distinct().forEach(msg -> { - bundleStatus.add(Status.warning(msg)); - }); - return wrap.getFile().get(); - } - if (directErrors.size() == 1) { - throw new CoreException(Status.error(directErrors.get(0).message())); - } - MultiStatus multiStatus = new MultiStatus(MavenTargetBundle.class, IStatus.ERROR, - "wrapping artifact " + artifact.getArtifactId() + " failed!"); - for (ProcessingMessage message : directErrors) { - multiStatus.add(Status.error(message.message())); - } - throw new CoreException(multiStatus); - } catch (CoreException e) { - throw e; - } catch (Exception e) { - throw new CoreException(Status.error("Can't collect dependencies!", e)); - } - }, monitor); - TargetBundle bundle = new TargetBundle(wrappedBundle.toFile()) { - @Override - public IStatus getStatus() { - if (!bundleStatus.isOK()) { - // TODO see https://github.com/eclipse-pde/eclipse.pde/issues/656 - // return bundleStatus; - } - return super.getStatus(); - } - }; - return bundle; - - } - - public boolean isWrapped() { - return isWrapped; - } - - @Override - public IStatus getStatus() { - if (bundle == null) { - if (status == null) { - return Status.OK_STATUS; - } - return status; - } - return bundle.getStatus(); - } - - @Override - public int hashCode() { - return getBundleInfo().hashCode(); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof MavenTargetBundle other && getBundleInfo().equals(other.getBundleInfo()); - } + private static final ILog LOGGER = Platform.getLog(MavenTargetBundle.class); + + private TargetBundle bundle; + + private IStatus status; + + private final BundleInfo bundleInfo; + + private boolean isWrapped; + + private Artifact artifact; + + @Override + public BundleInfo getBundleInfo() { + if (bundle == null) { + return bundleInfo; + } + return bundle.getBundleInfo(); + } + + @Override + public boolean isSourceBundle() { + return bundle != null && bundle.isSourceBundle(); + } + + @Override + public BundleInfo getSourceTarget() { + if (bundle == null) { + return null; + } + return bundle.getSourceTarget(); + } + + @Override + public boolean isFragment() { + return bundle != null && bundle.isFragment(); + } + + @Override + public String getSourcePath() { + if (bundle == null) { + return null; + } + return bundle.getSourcePath(); + } + + public MavenTargetBundle(Artifact artifact, MavenTargetLocation location, IProgressMonitor monitor) { + this.artifact = artifact; + File file = artifact.getFile(); + bundleInfo = new BundleInfo(artifact.getGroupId() + "." + artifact.getArtifactId(), artifact.getVersion(), file != null ? file.toURI() + : null, -1, false); + MissingMetadataMode missingMetadataMode = location.getMetadataMode(); + + if (missingMetadataMode == MissingMetadataMode.GENERATE) { + generateOrRewriteManifest(artifact, location, monitor, false); + } else if (missingMetadataMode == MissingMetadataMode.GENERATE_REWRITE) { + generateOrRewriteManifest(artifact, location, monitor, true); + } else { + try { + bundle = new TargetBundle(file); + } catch (Exception ex) { + MissingMetadataMode metadataMode = location.getMetadataMode(); + if (metadataMode == MissingMetadataMode.ERROR) { + status = Status.error(artifact + " is not a bundle", ex); + LOGGER.log(status); + } else { + status = Status.CANCEL_STATUS; + LOGGER.log(status); + } + } + } + } + + private void generateOrRewriteManifest(Artifact artifact, MavenTargetLocation location, IProgressMonitor monitor, boolean rewriteManifest) { + try { + bundle = getWrappedArtifact(artifact, location, monitor, rewriteManifest); + isWrapped = true; + } catch (Exception e) { + // not possible then + String message = artifact + " is not a bundle and cannot be automatically bundled as such "; + if (e.getMessage() != null) { + message += " (" + e.getMessage() + ")"; + } + status = Status.error(message, e); + LOGGER.log(status); + } + } + + public Artifact getArtifact() { + return artifact; + } + + private static TargetBundle getWrappedArtifact(Artifact artifact, MavenTargetLocation location, IProgressMonitor monitor, boolean rewriteManifest) + throws Exception { + IMaven maven = MavenPlugin.getMaven(); + List repositories = RepositoryUtils.toRepos(location.getAvailableArtifactRepositories(maven)); + Function instructionsLookup = node -> { + BNDInstructions instructions = location.getInstructionsForArtifact(node.getArtifact()); + return instructions == null ? BNDInstructions.getDefaultInstructionProperties() : instructions.asProperties(); + }; + IMavenExecutionContext exeContext = IMavenExecutionContext.getThreadContext().orElseGet(maven::createExecutionContext); + MultiStatus bundleStatus = new MultiStatus(MavenTargetBundle.class, 0, "Some problems where detected while wrapping " + artifact); + Path wrappedBundle = exeContext.execute((context, monitor1) -> { + RepositorySystem repoSystem = MavenPluginActivator.getDefault().getRepositorySystem(); + RepositorySystemSession repositorySession = context.getRepositorySession(); + try { + WrappedBundle wrap = MavenBundleWrapper.getWrappedArtifact(artifact, instructionsLookup, repositories, repoSystem, repositorySession, context.getComponentLookup().lookup(SyncContextFactory.class), rewriteManifest); + List directErrors = wrap.messages(false).filter(msg -> msg.type() == ProcessingMessage.Type.ERROR).toList(); + if (directErrors.isEmpty()) { + // treat all items as warnings.... + wrap.messages(true).map(ProcessingMessage::message).distinct().forEach(msg -> { + bundleStatus.add(Status.warning(msg)); + }); + return wrap.getFile().get(); + } + if (directErrors.size() == 1) { + throw new CoreException(Status.error(directErrors.get(0).message())); + } + MultiStatus multiStatus = new MultiStatus(MavenTargetBundle.class, IStatus.ERROR, "wrapping artifact " + artifact.getArtifactId() + + " failed!"); + for (ProcessingMessage message : directErrors) { + multiStatus.add(Status.error(message.message())); + } + throw new CoreException(multiStatus); + } catch (CoreException e) { + throw e; + } catch (Exception e) { + throw new CoreException(Status.error("Can't collect dependencies!", e)); + } + }, monitor); + TargetBundle bundle = new TargetBundle(wrappedBundle.toFile()) { + @Override + public IStatus getStatus() { + if (!bundleStatus.isOK()) { + // TODO see https://github.com/eclipse-pde/eclipse.pde/issues/656 + // return bundleStatus; + } + return super.getStatus(); + } + }; + return bundle; + + } + + public boolean isWrapped() { + return isWrapped; + } + + @Override + public IStatus getStatus() { + if (bundle == null) { + if (status == null) { + return Status.OK_STATUS; + } + return status; + } + return bundle.getStatus(); + } + + @Override + public int hashCode() { + return getBundleInfo().hashCode(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof MavenTargetBundle other && getBundleInfo().equals(other.getBundleInfo()); + } } diff --git a/org.eclipse.m2e.pde.target/src/org/eclipse/m2e/pde/target/MissingMetadataMode.java b/org.eclipse.m2e.pde.target/src/org/eclipse/m2e/pde/target/MissingMetadataMode.java index ebfa1f030..49fe50e54 100644 --- a/org.eclipse.m2e.pde.target/src/org/eclipse/m2e/pde/target/MissingMetadataMode.java +++ b/org.eclipse.m2e.pde.target/src/org/eclipse/m2e/pde/target/MissingMetadataMode.java @@ -13,5 +13,8 @@ package org.eclipse.m2e.pde.target; public enum MissingMetadataMode { - IGNORE, ERROR, GENERATE; + IGNORE, + ERROR, + GENERATE, + GENERATE_REWRITE; } diff --git a/org.eclipse.m2e.pde.target/src/org/eclipse/m2e/pde/target/shared/MavenBundleWrapper.java b/org.eclipse.m2e.pde.target/src/org/eclipse/m2e/pde/target/shared/MavenBundleWrapper.java index d2f898527..a7bc3f718 100644 --- a/org.eclipse.m2e.pde.target/src/org/eclipse/m2e/pde/target/shared/MavenBundleWrapper.java +++ b/org.eclipse.m2e.pde.target/src/org/eclipse/m2e/pde/target/shared/MavenBundleWrapper.java @@ -90,24 +90,24 @@ private MavenBundleWrapper() { } /** - * Wraps an artifact (and possible its dependents if required) to produce a - * manifest with OSGi metadata. - * - * @param artifact the artifact to wrap - * @param instructionsLookup a lookup for bnd instructions - * @param repositories the repositories that should be used to resolve - * dependencies - * @param repoSystem the repository system for lookup dependent items - * @param repositorySession the session to use - * @param syncContextFactory the sync context factory to acquire exclusive - * access to the wrapped artifact and its dependencies - * @return the wrapped artifact - * @throws Exception if wrapping the artifact fails for any reason - */ + * Wraps an artifact (and possible its dependents if required) to produce a manifest with OSGi metadata. + * + * @param artifact the artifact to wrap + * @param instructionsLookup a lookup for bnd instructions + * @param repositories the repositories that should be used to resolve dependencies + * @param repoSystem the repository system for lookup dependent items + * @param repositorySession the session to use + * @param syncContextFactory the sync context factory to acquire exclusive access to the wrapped artifact and its dependencies + * @param rewriteManifest if true, the manifest file is forced to be rewritten + * @return the wrapped artifact + * @throws Exception if wrapping the artifact fails for any reason + */ public static WrappedBundle getWrappedArtifact(Artifact artifact, Function instructionsLookup, List repositories, RepositorySystem repoSystem, RepositorySystemSession repositorySession, - SyncContextFactory syncContextFactory) throws Exception { + SyncContextFactory syncContextFactory, + boolean rewriteManifest) + throws Exception { CollectRequest collectRequest = new CollectRequest(); collectRequest.setRoot(new Dependency(artifact, null)); collectRequest.setRepositories(repositories); @@ -150,7 +150,7 @@ public boolean visitEnter(DependencyNode n) { }); syncContext.acquire(lockList, null); Map visited = new HashMap<>(); - WrappedBundle wrappedNode = getWrappedNode(node, instructionsLookup, visited); + WrappedBundle wrappedNode = getWrappedNode(node, instructionsLookup, visited, rewriteManifest); for (WrappedBundle wrap : visited.values()) { wrap.getJar().ifPresent(jar -> jar.close()); } @@ -159,7 +159,9 @@ public boolean visitEnter(DependencyNode n) { } private static WrappedBundle getWrappedNode(DependencyNode node, - Function instructionsLookup, Map visited) + Function instructionsLookup, + Map visited, + boolean rewriteManifest) throws Exception { WrappedBundle wrappedNode = visited.get(node); if (wrappedNode != null) { @@ -198,7 +200,7 @@ private static WrappedBundle getWrappedNode(DependencyNode node, "Artifact " + node.getArtifact() + " can not be read as a jar file")))); return wrappedNode; } - if (isValidOSGi(jar.getManifest())) { + if (!rewriteManifest && isValidOSGi(jar.getManifest())) { // already a bundle! visited.put(node, wrappedNode = new WrappedBundle(node, List.of(), null, originalFile.toPath(), jar, List.of())); @@ -207,7 +209,7 @@ private static WrappedBundle getWrappedNode(DependencyNode node, List children = node.getChildren(); List depends = new ArrayList<>(); for (DependencyNode child : children) { - depends.add(getWrappedNode(child, instructionsLookup, visited)); + depends.add(getWrappedNode(child, instructionsLookup, visited, rewriteManifest)); } WrappedBundle wrappedNodeAfterVisit = visited.get(node); if (wrappedNodeAfterVisit != null) { diff --git a/org.eclipse.m2e.pde.ui/src/org/eclipse/m2e/pde/ui/target/editor/MavenTargetLocationEditor.java b/org.eclipse.m2e.pde.ui/src/org/eclipse/m2e/pde/ui/target/editor/MavenTargetLocationEditor.java index b8739935d..72332e8f8 100644 --- a/org.eclipse.m2e.pde.ui/src/org/eclipse/m2e/pde/ui/target/editor/MavenTargetLocationEditor.java +++ b/org.eclipse.m2e.pde.ui/src/org/eclipse/m2e/pde/ui/target/editor/MavenTargetLocationEditor.java @@ -46,7 +46,7 @@ public boolean canEdit(ITargetDefinition target, TreePath treePath) { return true; } // it must use generate mode - if (location.getMetadataMode() == MissingMetadataMode.GENERATE) { + if (location.getMetadataMode() == MissingMetadataMode.GENERATE || location.getMetadataMode() == MissingMetadataMode.GENERATE_REWRITE) { // and the selected child must be a dependency node if (lastSegment instanceof DependencyNode node) { MavenTargetBundle bundle = location.getMavenTargetBundle(node.getArtifact()); diff --git a/org.eclipse.m2e.pde.ui/src/org/eclipse/m2e/pde/ui/target/editor/MavenTargetLocationWizard.java b/org.eclipse.m2e.pde.ui/src/org/eclipse/m2e/pde/ui/target/editor/MavenTargetLocationWizard.java index 4c85af597..7a3458983 100644 --- a/org.eclipse.m2e.pde.ui/src/org/eclipse/m2e/pde/ui/target/editor/MavenTargetLocationWizard.java +++ b/org.eclipse.m2e.pde.ui/src/org/eclipse/m2e/pde/ui/target/editor/MavenTargetLocationWizard.java @@ -231,7 +231,8 @@ private void applyGridLayout(Composite composite, int numColumns, int horizontal private void updateUI() { editInstructionsButton.setVisible( - metadata.getStructuredSelection().getFirstElement() == MissingMetadataMode.GENERATE); + metadata.getStructuredSelection().getFirstElement() == MissingMetadataMode.GENERATE + || metadata.getStructuredSelection().getFirstElement() == MissingMetadataMode.GENERATE_REWRITE); if (include.getStructuredSelection().getFirstElement() == DependencyDepth.NONE) { for (Button button : scopes) { button.setEnabled(false); @@ -287,7 +288,7 @@ public IWizardPage getNextPage(IWizardPage page) { @Override public void setTarget(ITargetDefinition target) { - this.targetDefinition = target; + targetDefinition = target; } @Override