Skip to content

Commit 8b939b9

Browse files
committed
Make PDE projects adaptable to an OSGi Resource
Currently one needs to use some special PDE API to learn about the OSGi nature of a project. This is not only cumbersome but also ties the consumer to a specific tooling. With this change now any eclipse project can be adapted to an OSGi Resource making the caller completely tooling independent. That way it is for example possible to select a PDE project and have it displayed in the OSGi Resolution view.
1 parent c9db1fb commit 8b939b9

2 files changed

Lines changed: 42 additions & 2 deletions

File tree

ui/org.eclipse.pde.bnd.ui/README.MD

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ One problem for such a reusable component is that it usually needs to get holds
1818
To mitigate we use the [Eclipse Adapter Pattern](https://www.eclipse.org/articles/Article-Adapters/) as it is widely used in Eclipse, flexible and allows
1919
the use of [OSGi services / Dependency Injection](https://eclipse.dev/eclipse/news/4.18/platform_isv.php#dialog-adapterfactory-as-service) already.
2020

21-
### The IProject adapter
21+
### The `IProject` adapter
2222

2323
Components need to learn the project and workspace of a bndlib backed project, for this the very first step for an integration is to provide an adapter that can
2424
transform an (Eclipse) `IProject` into a (bndlib) `Project` (from were the Workspace then can be derived), an example might look like this:
@@ -46,6 +46,18 @@ public class MyBndPluginAdapter implements IAdapterFactory {
4646
}
4747
```
4848

49+
## The `Resource` Adapter
50+
51+
Some components might want to learn about an (OSGi) `Resource` (e.g. a Bundle) for a particular object.
52+
To support such use-case one should provide an Adapter from tooling specific objects to (OSGi) `Resource`.
53+
54+
For example the previous Adapter might be enhanced to support an adaption from an (Eclipse) `IProject` to an
55+
(OSGi) `Resource` if it represents a bundle and the tolling knows how to transform the specific project metadata into an universal
56+
`Resource` representation. That way it is possible to select the project and show its requirements and
57+
capabilities in the OSGi Resolution View without specific knowledge on how this process works.
58+
59+
### Further Information
60+
4961
Some relevant 'glue' classes for Bnd <-> PDE interaction, to have a look at:
5062

5163
- `org.eclipse.pde.bnd.ui.Central`
@@ -63,6 +75,7 @@ it currently offers these components:
6375

6476
- [bnd templates](https://eclipse.dev/eclipse/news/4.31/pde.php#bndtemplates)
6577
- [osgi repositories view](https://eclipse.dev/eclipse/news/4.32/pde.php#osgirepositories)
78+
- [OSGi Resolution View](https://eclipse.dev/eclipse/markdown/?f=news/4.36/pde.md#new-osgi-resolution-view)
6679
- Formating of bnd files, quick fixes, completion proposals
6780
- ... more to come ...
6881

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bnd/PdeBndAdapter.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,28 @@
1313
*******************************************************************************/
1414
package org.eclipse.pde.internal.core.bnd;
1515

16+
import java.io.InputStream;
17+
import java.util.jar.Manifest;
18+
1619
import org.bndtools.versioncontrol.ignores.manager.api.VersionControlIgnoresManager;
20+
import org.eclipse.core.resources.IFile;
1721
import org.eclipse.core.resources.IProject;
1822
import org.eclipse.core.runtime.AdapterTypes;
1923
import org.eclipse.core.runtime.IAdapterFactory;
24+
import org.eclipse.pde.internal.core.natures.PluginProject;
25+
import org.eclipse.pde.internal.core.project.PDEProject;
26+
import org.osgi.resource.Resource;
2027
import org.osgi.service.component.annotations.Component;
2128
import org.osgi.service.component.annotations.Reference;
2229
import org.osgi.service.component.annotations.ReferenceCardinality;
2330
import org.osgi.service.component.annotations.ReferencePolicy;
2431

2532
import aQute.bnd.build.Project;
33+
import aQute.bnd.osgi.resource.ResourceBuilder;
2634

2735
@Component(service = IAdapterFactory.class)
28-
@AdapterTypes(adaptableClass = IProject.class, adapterNames = { Project.class, VersionControlIgnoresManager.class })
36+
@AdapterTypes(adaptableClass = IProject.class, adapterNames = { Project.class, VersionControlIgnoresManager.class,
37+
Resource.class })
2938
public class PdeBndAdapter implements IAdapterFactory {
3039

3140
@Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC)
@@ -46,6 +55,24 @@ public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
4655
if (adapterType == VersionControlIgnoresManager.class) {
4756
return adapterType.cast(versionControlIgnoresManager);
4857
}
58+
if (adapterType == Resource.class) {
59+
if (adaptableObject instanceof IProject project) {
60+
if (PluginProject.isPluginProject(project)) {
61+
IFile manifestFile = PDEProject.getManifest(project);
62+
if (manifestFile != null && manifestFile.exists()) {
63+
Manifest manifest;
64+
try (InputStream stream = manifestFile.getContents()) {
65+
manifest = new Manifest(stream);
66+
} catch (Exception e) {
67+
return null;
68+
}
69+
ResourceBuilder builder = new ResourceBuilder();
70+
builder.addManifest(manifest);
71+
return adapterType.cast(builder.build());
72+
}
73+
}
74+
}
75+
}
4976
return null;
5077
}
5178

0 commit comments

Comments
 (0)