From 6d0a83aef1ca6bf9554b68e62b15b26bef140e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Thu, 19 Oct 2023 16:48:07 +0200 Subject: [PATCH] Support setting the bundleroot for manifest generated projects Currently we have only the option to set the bundleroot to a different folder (what the will become the outputfolder). In some cases one might want to set the bundle root also to the project root. This now adds special handling for the case where bundle root != output folder. Fix https://github.com/eclipse-pde/eclipse.pde/issues/803 --- .../pde/internal/core/bnd/ProjectJar.java | 52 ++++++++++++++++++- .../pde/internal/core/project/PDEProject.java | 19 ++++--- 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/ProjectJar.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/ProjectJar.java index 52af524a91..8f6eb62df4 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/ProjectJar.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/ProjectJar.java @@ -26,6 +26,7 @@ import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; @@ -38,10 +39,11 @@ public class ProjectJar extends Jar { private final IContainer outputFolder; + private IFile manifestFile; public ProjectJar(IProject project, Predicate filter) throws CoreException { super(project.getName()); - outputFolder = PDEProject.getBundleRoot(project); + outputFolder = PDEProject.getJavaOutputFolder(project); FileResource.addResources(this, outputFolder, filter); if (project.hasNature(JavaCore.NATURE_ID)) { IJavaProject javaProject = JavaCore.create(project); @@ -57,12 +59,53 @@ public ProjectJar(IProject project, Predicate filter) throws CoreExce } } } + manifestFile = PDEProject.getManifest(project); } @Override public void setManifest(Manifest manifest) { super.setManifest(manifest); - putResource(JarFile.MANIFEST_NAME, new ManifestResource(manifest)); + ManifestResource resource = new ManifestResource(manifest); + // We must handle this with a little care here, first we put it as a + // resource, what will make other parts of BND find it and copy it to + // the output location(so it can be found when using the output as a + // classpath) + putResource(JarFile.MANIFEST_NAME, resource); + // but we also need to make sure if BUNDLE_ROOT != output location + // another copy for PDE and other things that expect it at the bundle + // root... + IFile file = outputFolder.getFile(IPath.fromOSString(JarFile.MANIFEST_NAME)); + if (!file.getFullPath().equals(manifestFile.getFullPath())) { + // bundle root is currently not where we store it... + if (manifestFile.exists()) { + try (InputStream stream = resource.openInputStream()) { + manifestFile.setContents(stream, true, false, null); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + try { + mkdirs(manifestFile); + } catch (CoreException e) { + throw new RuntimeException(e); + } + try (InputStream stream = resource.openInputStream()) { + manifestFile.create(stream, true, null); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + try { + manifestFile.setDerived(true, new NullProgressMonitor()); + } catch (CoreException e) { + // if only that don't work just go on... + } + } + } @Override @@ -104,4 +147,9 @@ private void mkdirs(IResource resource) throws CoreException { } } + @Override + public String toString() { + return "Project" + super.toString(); //$NON-NLS-1$ + } + } diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/project/PDEProject.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/project/PDEProject.java index a53eb17038..a1fe5cd0ce 100644 --- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/project/PDEProject.java +++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/project/PDEProject.java @@ -68,13 +68,10 @@ public static IContainer getBundleRoot(IProject project) { } } if (BndProject.isBndProject(project)) { - try { - if (project.hasNature(JavaCore.NATURE_ID)) { - IJavaProject javaProject = JavaCore.create(project); - IPath outputLocation = javaProject.getOutputLocation(); - IWorkspaceRoot workspaceRoot = project.getWorkspace().getRoot(); - return workspaceRoot.getFolder(outputLocation); + IFolder outputFolder = getJavaOutputFolder(project); + if (outputFolder != null) { + return outputFolder; } } catch (CoreException e) { // can't determine the bundle root then from java settings! @@ -84,6 +81,16 @@ public static IContainer getBundleRoot(IProject project) { return project; } + public static IFolder getJavaOutputFolder(IProject project) throws CoreException { + if (project.hasNature(JavaCore.NATURE_ID)) { + IJavaProject javaProject = JavaCore.create(project); + IPath outputLocation = javaProject.getOutputLocation(); + IWorkspaceRoot workspaceRoot = project.getWorkspace().getRoot(); + return workspaceRoot.getFolder(outputLocation); + } + return null; + } + /** * Returns the launch shortcuts configured for this project * or null if default launchers should be used.