Publishing Events
To publish events, an Event Publisher must retrieve the Event Admin service. Create an event object with two attributes – topic and properties. The topic specifies the action which Event Handlers are interested in. Additional information about the event is provided as properties.
To publish events synchronously, call the sendEvent(Event) method from the org.osgi.service.event.EventAdmin service. To publish events in an asynchronous manner, invoke the postEvent(Event) method of the org.osgi.service.event.EventAdmin service.
The example that follows delivers events using the sendEvent(Event) method of the org.osgi.service.event.EventAdmin service. This method initiates a synchronous delivery of events and does not return to the caller until the event is successfully delivered.
import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
public class EventPublisher extends Thread implements BundleActivator,
ServiceListener{
private BundleContext bcontext= null;
ServiceReference sr = null;
EventAdmin ea = null;
Event event = null;
Hashtable properties = null;
boolean sending = true;
public void start(BundleContext bc) throws Exception {
this.bcontext = bc;
// Adding the ServiceListener
bc.addServiceListener(this);
// Retrieving the Event Admin service from the OSGi framework
sr = bc.getServiceReference(EventAdmin.class.getName());
if (sr == null){
throw new Exception("Failed to obtain EventAdmin service reference!");
}
ea = (EventAdmin) bc.getService(sr);
if (ea == null) {
throw new Exception("Failed to obtain EventAdmin service object!");
}
start();
}
public void run() {
while(sending){
if(ea != null){
properties = new Hashtable();
properties.put(EventConstants.BUNDLE_SYMBOLICNAME, "test.first");
// Creating and firing events with topic
// "org/osgi/framework/BundleEvent/STARTED" every 2 seconds
event = new Event("org/osgi/framework/BundleEvent/STARTED", properties);
ea.sendEvent(new Event(event);
try {
Thread.sleep(2000);
} catch(InterruptedException ie) {}
}
}
}
public void stop(BundleContext bc) throws Exception {
bc.ungetService(sr);
sending = false;
bc.removeServiceListener(this);
}
// Method inherited from the ServiceListener interface
public void serviceChanged(ServiceEvent se){
// Stops the bundle sending events when the Event Admin service
// is no more obtainable.
if ((se.getServiceReference() == sr) &&
(se.getType() == ServiceEvent.UNREGISTERING)){
try{
bc.getBundle().stop();
} catch(BundleException be){}
}
}
}
Subscribing to Events
Event Subscribers must be registered as services under the org.osgi.service.event.EventHandler interface. They must have a service property org.osgi.service.event.EventConstants.EVENT_TOPIC ("event.topic") describing the event topics which the corresponding Event Handler is interested in. It takes String[] values. Subscribers may also be registered with the org.osgi.service.event.EventConstants.EVENT_FILTER ("event.filter") service property.
The following example demonstrates receiving events from an Event Publisher through the OSGi Event Admin service. The Event Handler subscribes to Bundle events with a level of STARTED as indicated by the value of the handler's EventConstants.EVENT_TOPIC registration property. The Event Handler additionally filters out only the events about bundles with symbolic name starting with "test", as indicated by the EventConstants.EVENT_FILTER property.
import java.util.Dictionary;
import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventConstants;
import org.osgi.service.event.EventHandler;
public class MyEventHandler implements EventHandler, BundleActivator {
final static String[] topic = { "org/osgi/framework/BundleEvent/STARTED" };
String filter = "(bundle.symbolicName=test.*)";
ServiceRegistration register;
public void start(BundleContext bc) throws Exception {
Dictionary dict = new Hashtable();
dict.put(EventConstants.EVENT_TOPIC, topic);
dict.put(EventConstants.EVENT_FILTER, filter);
// Registering the EventHandler
register = bc.registerService(EventHandler.class.getName(), this, dict);
}
public void stop(BundleContext bc) throws Exception {
register.unregister();
}
// Method inherited from the EventHandler interface
public void handleEvent(Event e) {
// Do something with the received events
...
}
}
Event Handler Types
Depending on the bundle that registers the Event Handler there are two types of Event Handler: System Event Handler and Application Event Handler.
System Event Handler
An Event Handler is a System Event Handler if it is registered by a bundle activated by default on framework startup.
A System Event Handler can be registered with a registration property with key mbs.events.handlerPriority and value – Integer. The range of accepted values for this property is from 1 to 49, with default value 49. This is mapped to a Java thread priority using the following formula:
int priority = Thread.MAX_PRIORITY - (priorityPropertyValue/10);
if (priority < Thread.NORM_PRIORITY) priority = Thread.NORM_PRIORITY;
If the system property mbs.events.handlerPriority.default is set, its value overrides the mbs.events.handlerPriority registration property for all System Event Handlers.
The System Event Handlers are grouped based on their priority registration property, i.e handlers with the same priority receive events from a single thread running with the corresponding thread priority.
Application Event Handler
An Event Handler is an Application Event Handler if it is not registered by a bundle activated by default on framework startup.
The registration property mbs.events.handlerPriority is only used for System Event Handlers. If an Application Event Handler is registered with this property it is ignored.
Configuring Application Event Handler Priorities
The following system properties can be used to configure the priorities for the Event Handlers from the corresponding modules:
The default value for these properties is "1".
Event Handler Configuration by a Third Party
Through registering an EventHandlerGroupHook service you can manipulate EventHandler priorities and groups.
Rules for EventHandlerGroupHooks: