Event Service
Concepts
The JS OSGi platform provided by map.apps implements the OSGi EventAdmin Service Specification (specified in the OSGi Compendium Specification) and slightly extends it for simpler usage within bundles.
The EventAdminService (referenced as Event Service in the following) is used to broadcast messages as topics within the OSGi runtime. OSGi Services which implement the EventHandler interface are informed about these messages.
The Event Service is one of the core services that are required to build independent bundles that can interact with each other.
Broadcasting Messages
The Event Service is part of the system bundle and registered as ct.framework.api.EventService
.
It can be referenced by using the following definition inside a component:
"references": [{
"name": "_eventService",
"providing": "ct.framework.api.EventService"
}]
The Event Service provides two methods to broadcast an event:
-
sendEvent
synchronously broadcasts a message to the EventListeners.sendEvent// in your component code do: this._eventService.sendEvent("my/topic/ACTION",{propA : "event property A"});
-
postEvent
asynchronously broadcasts a message to the EventListeners. This is the recommended way of using the Event Service.postEvent// in your componente code do: this._eventService.postEvent("my/topic/ACTION",{ propA: "event property A"});
Listening for Messages
An OSGi service that wants to listen to messages broadcasted by the Event Service must be registered as ct.framework.api.EventHandler
and provide the service property Event-Topics
.
The following kinds of listener registrations using the manifest.json
file are available:
// Registers a an event handler to listen on messages of topic "ct/map/EXTENT_CHANGE".
{
"name": "MyEventHandler",
"provides": ["ct.framework.api.EventHandler"],
"properties":{
"Event-Topics": ["ct/map/EXTENT_CHANGE"]
}
}
// Service Implementation
export default class{
// 'handleEvent' is the default method name called by the Event Service to inform the listener.
// @param evt {apprt/event/Event} the broadcasted event
handleEvent(event){
// topic = 'ct/map/EXTENT_CHANGE'
let topic = event.getTopic();
// reason is 'EXTENT_CHANGE' (the last topic part)
let reason = event.getTopicReason();
let extent = event.getProperty("extent");
// do something with the extent
}
}
// Registers an event handler to listen on messages of all topics starting with "ct/tool/ACTIVATE/".
// It demonstrates that you can use the wildcard '*' at the end of a topic path
// to listen on all events use the topic name '*'.
// The "Event-Filter" property allows filtering messages by their properties.
// In this example the event handler is only informed about event messages if the message has the property "toolId" with the value 'toolA' or 'toolB'
{
"name": "MyEventHandler",
"provides": ["ct.framework.api.EventHandler"],
"properties":{
"Event-Topics": ["ct/tool/ACTIVATE/*"],
"Event-Filter": ["(|(toolId=toolA)(toolId=toolB))"]
}
}
// Service implementation
export default class{
// 'handleEvent' is the default method name called by the Event Service to inform the listener.
// @param evt {apprt/event/Event} the broadcasted event
handleEvent(event){
let toolId = event.getProperty("toolId");
// do something with the ID
}
}
// Here the topic object notation is shown.
// It allows to map topics to individual methods in the EventHandler instance.
{
"name": "MyEventHandler",
"provides": ["ct.framework.api.EventHandler"],
"properties":{
"Event-Topics": [{
"topic":"ct/tool/ACTIVATE/toolA",
"method":"_handleActivationOfToolA"
}]
}
}
// Service implementation
export default class{
// @param evt {apprt/event/Event} the broadcasted event
_handleActivationOfToolA(event){
var toolId = event.getProperty("toolId");
// do something with the ID
}
}
// This example demonstrates the use of the topic object notation to map multiple topics to one method.
{
"name": "MyEventHandler",
"provides": ["ct.framework.api.EventHandler"],
"properties":{
"Event-Topics": [{
"topic":["ct/tool/ACTIVATE/toolA","ct/tool/ACTIVATE/toolB"],
"method":"_handleActivationOfTool"
}]
}
}
// Service implementation
export default class{
// @param evt {apprt/event/Event} the broadcasted event
_handleActivationOfTool(event){
var toolId = event.getProperty("toolId");
// do something with the ID
}
}
// This sample shows the usage of the topic object notation and the direct configuration of a filter within this topic object
{
"name": "MyEventHandler",
"provides": ["ct.framework.api.EventHandler"],
"properties":{
"Event-Topics": [{
"topic":"ct/tool/ACTIVATE/*",
"method":"_handleActivationOfToolA",
"filter" : "(toolId=toolA)"
}]
}
}
// Service implementation
export default class{
// @param evt {apprt/event/Event} the broadcasted event
_handleActivationOfToolA(event){
var toolId = event.getProperty("toolId");
// do something with the ID
}
}
// This sample shows the usage of the topic object notation with the pre-configuration of handler method params
{
"name": "MyEventHandler",
"provides": ["ct.framework.api.EventHandler"],
"properties":{
"Event-Topics": [{
"topic":"ct/tool/ACTIVATE/toolA",
"method":"_switchActivate",
"params" : [true]
},
{
"topic":"ct/tool/DEACTIVATE/toolA",
"method":"_switchActivate",
"params" : [false]
}]
}
}
// Service implementation (does not know that it is an EventHandler)
export default class{
// @param flag {boolean} a flag provided by the configuration
_switchActivate(active /*, event // is still provided */){
if (active){
// do if active
}else{
// do if not active
}
}
}