5.1. Event Handling

The OSGi event types and event listeners follow the event model introduced in JDK software version 1.x. There are three types of events, and their event classes are defined in the org.osgi.framework package:

  1. FrameworkEvent. A framework event occurs when the framework is launched or an error has occurred asynchronously during execution of the framework.

  2. BundleEvent. A bundle event occurs after a bundle life cycle action takes place.

  3. ServiceEvent. A service event occurs in response to a service registration, unregistration, or property change.

A named constant is used to identify further a condition in one of the three event types. For example, BundleEvent.STARTED indicates the bundle event of a bundle that has been activated. Table 5.1 illustrates the types of events, when they are fired, and the methods of their corresponding event listeners that are invoked.

Table 5.1. OSGi Framework Events
Event Type When the Event Is Fired Listener Method Invoked
FrameworkEvent STARTED The framework starts up. FrameworkListener.frameworkEvent
ERROR An error has been raised within the framework.
BundleEvent INSTALLED A bundle has been installed in the framework. BundleListener.bundleChanged
STARTED A bundle has been activated.
STOPPED A bundle has been deactivated.
UPDATED A bundle has been updated.
UNINSTALLED A bundle has been uninstalled.
ServiceEvent REGISTERED A service has been registered. ServiceListener.serviceChanged
UNREGISTERING A service is being unregistered.
MODIFIED The properties of a service have been modified.

Because the framework must be launched before bundles can be hosted, how is it possible for a bundle's listener to receive the FrameworkEvent.STARTED event? The answer is during framework restart. The framework records which bundles were active before shutdown. When it is restarted, it first reactivates those bundles, which can be notified of the FrameworkEvent.STARTED event at the end of the framework restart process.

The following example bundle, when started, listens to any events generated within the framework. It demonstrates how to add and remove listeners, and how to implement listener methods. Code in bold type calls out relevant APIs.

Its manifest is straightforward:

BundleActivator: com.acme.event.Activator

The activator also serves as the listener for all three types of events:

package com.acme.event;
import org.osgi.framework.*;

public class Activator implements BundleActivator,
   FrameworkListener, BundleListener, ServiceListener {

   public void start(BundleContext ctxt) {
      ctxt.addFrameworkListener(this);
      ctxt.addBundleListener(this);
      ctxt.addServiceListener(this);
   }

   public void stop(BundleContext ctxt) {
      ctxt.removeFrameworkListener(this);
      ctxt.removeBundleListener(this);
      ctxt.removeServiceListener(this);
   }

   /**
    * Implementation of FrameworkListener
    */
   public void frameworkEvent(FrameworkEvent e) {
      switch (e.getType()) {
      case FrameworkEvent.STARTED:
         System.out.println("The framework has been started.");
         break;
      case FrameworkEvent.ERROR:
         Bundle b = e.getBundle();
         Throwable t = e.getThrowable();
         System.err.println("Error occurred in bundle " +
            b.getLocation() + ", stack trace follows: ");
         t.printStackTrace();
         break;
      }
   }

   /**
    * Implementation of BundleListener
    */
   public void bundleChanged(BundleEvent e) {
      Bundle bundle = e.getBundle();
      String location = bundle.getLocation();
      switch (e.getType()) {
      case BundleEvent.INSTALLED:
         System.out.println(location + " has been installed");
         break;
      case BundleEvent.UNINSTALLED:
         System.out.println(location + " has been uninstalled");
         break;
      case BundleEvent.STARTED:
         System.out.println(location + " has been activated");
         break;
      case BundleEvent.STOPPED:
         System.out.println(location + " has been deactivated");
         break;
      case BundleEvent.UPDATED:
         System.out.println(location + " has been updated");
         break;
      }
   }

   /**
    * Implementation of ServiceListener
    */
   public void serviceChanged(ServiceEvent e) {
      ServiceReference ref = e.getServiceReference();
      switch (e.getType()) {
      case ServiceEvent.REGISTERED:
         System.out.println(ref + " has been registered");
         break;
      case ServiceEvent.UNREGISTERING:
         System.out.println(ref + " is being unregistered");
         break;
      case ServiceEvent.MODIFIED:
         System.out.println("the properties of "+ref+
         " have been modified");
         break;
      }
   }
}

The framework automatically removes any event listeners added by a bundle when the bundle is stopped, in the same way it unregisters any services on the bundle's behalf. Therefore, the activator stop method may very well be empty:

public void stop(BundleContext ctxt) {
   // We do not need to remove the listeners added by this
   // bundle because the framework will automatically remove
   // them for us.
}

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.130.233