Reputation: 1458
I'm a building an OSGI framework and I was wondering if there is a way to get all the bundles who bound themselves to mine?
It's because I offer a service to those bundles, and make new resources to optimize my preformence while offering this service. I also offer a way to destroy those resources when no longer needed, but I want a failsafe for when a bundle unbinds without first deleting his used resources.
Can I use my BundleContext for this?
Upvotes: 1
Views: 109
Reputation: 23948
You seem to be asking two different questions. In the first paragraph you're asking about bundles that are bound to you, which I interpret to mean bundles that import your exported packaged. In the second you're asking about consumers of your services; these are orthogonal issues.
For the first question, you can use the BundleWiring API:
BundleWiring myWiring = myBundle.adapt(BundleWiring.class);
List<BundleWire> exports = myWiring.getProvidedWires(PackageNamespace.PACKAGE_NAMESPACE);
for (BundleWire export : exports) {
Bundle importer = export.getRequirerWiring().getBundle()
}
For services, you can use the ServiceFactory
pattern. By registering your service as an instance of ServiceFactory
rather than directly as an instance of the service interface you can keep track of the bundles that consume your service. Here is a skeleton of a service implementation using this pattern:
public class MyServiceFactory implements ServiceFactory<MyServiceImpl> {
public MyServiceImpl getService(Bundle bundle, ServiceRegistration reg) {
// create an instance of the service, customised for the consumer bundle
return new MyServiceImpl(bundle);
}
public void ungetService(Bundle bundle, ServiceRegistration reg, MyServiceImpl svc) {
// release the resources used by the service impl
svc.releaseResources();
}
}
UPDATE: Since you are implementing your service with DS, things are a bit easier. DS manages the creation of the instance for you... the only slightly tricky thing is working out which bundle is your consumer:
@Component(servicefactory = true)
public class MyComponent {
@Activate
public void activate(ComponentContext context) {
Bundle consumer = context.getUsingBundle();
// ...
}
}
In many cases you don't even need to get the ComponentContext and the consuming bundle. If you are assigning resources for each consumer bundle, then you can just save those into instance fields of the component, and remember to clean them up in your deactivate method. DS will create an instance of the component class for each consumer bundle.
Upvotes: 3