org.osgi.service.event.EventHandler is defined in R4.cmpn 113 Event Admin
Service Specification. It's for you to define your own event.
org.osgi.framework.ServiceEvent is defined in R4.core.

The former is the Service platform stuff, while the later is the core
framework stuff. They have no relationship.

The right way for you to solve your problem is to write a class to implement
the interface ServiceListener.
And then add the its instance to BundleContext as follows:

bundleContext.addServiceListener(yourServiceListener);

If you want to filter the event by the service type, then create a filter
"(objectClass=xxxxxxxx)" and add it to the BundleContext along with your
ServiceListener as follows:

bundleContext.addServiceListener(yourServiceListener, filter);


Regards,
Agemo

On Wed, Jun 3, 2009 at 4:45 PM, Guido Spadotto <[email protected]> wrote:

>  Hi all,
>  I'm pretty new to OSGi, so I'd like you to give me some help
> (I've done my homework, but I'm a bit stuck).
>
> The problem: I have to write a service that listens to the
> org/osgi/framework/ServiceEvent/* topic to react to services
> being registered/unregistered.
>
> When a service event is fired to that topic, my service has to
> react to and handle only events that are related to services
> implementing *a given interface* (actually, extending a given class,
> but this will change in the future).
>
> My current solution is based on a DS component that extends
> EventHandler, whose handleEvent method is reported below
> (which I think is not the "correct" way to go):
>
> public void handleEvent(Event evt) {
>     //I know the event is a service event from the topic I'm listening to
>     ServiceEvent sEvt = (ServiceEvent)
> evt.getProperty(EventConstants.EVENT);
>     switch (sEvt.getType()) {
>         case ServiceEvent.REGISTERED:
>            // A service comes...
>            ServiceReference mySr = sEvt.getServiceReference();
>            Bundle containingBundle = mySr.getBundle();
>            BundleContext bc = containingBundle.getBundleContext();
>            Object service = bc.getService(mySr);
>            boolean isPssService = false;
>            try {
>              //TODO Ugly!
>              Class pssServiceClass =
> Class.forName(ServiceLocator.pssServiceClassName);
>              isPssService =
> pssServiceClass.isAssignableFrom(service.getClass());
>            } catch (ClassNotFoundException e) {
>              //Handle
>            }
>            if (isPssService){
>              //Another ugly casting
>              PssService pssService = (PssService) service;
>              ... do something ...
>            }else{
>              this.log(LogService.LOG_DEBUG, "Generic service registered");
>            }
>            break;
>         case ServiceEvent.UNREGISTERING:
>            // A service goes...
>            ... filter as above, then do something else...
>            break;
>         default:
>              this.log(LogService.LOG_WARNING, "Unhandled Service event: ("+
> evt.getTopic() + ")");
>              break;
>     }
> }
>
> The questions:
>
> 1) Is there a way of filtering the handled events
>    to only those being fired by a service implementing
>    a given interface? At the moment, the only solution
>    to this requirement I'm aware of is by forcing the
>    registering/unregistering services to define a property
>    with a value to use in the "event.filter" service property.
> 2) Is there a standard pattern for retrieving and invoking the methods
>    from a service that caused a service event to be fired, starting
>    from the ServiceEvent itself, without using Class.forName to
>    downcast the BundleContext.getService(ServiceReference) result?
> 3) Am I supposed to call BundleContext.ungetService(ServiceReference)
>    while handling the ServiceEvent.UNREGISTERING event, to decrease
>    the context bundle's use count?
>
> Sorry for this lengthy mail, as you can see I have few ideas,
> and pretty confused. ;)
>
> Regards,
>  --
>  [image: Logo] Guido Spadotto
> Soluta.net, Italy
> http://www.soluta.net
>
>
>

Reply via email to