This repository has been archived by the owner on Apr 3, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathosgi.js
138 lines (118 loc) · 4.15 KB
/
osgi.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/**
* OSGi module.
* This module provides access to OSGi services.
*
* @namespace osgi
*/
const log = require('./log')('osgi');
const bundleContext = require('@runtime/osgi').bundleContext;
const lifecycle = require('@runtime/osgi').lifecycle;
const Hashtable = Java.type('java.util.Hashtable');
/**
* Map of interface names to sets of services registered (by this module)
*/
let registeredServices = {};
let jsObjectToHashtable = function(obj) {
if(obj === null) {
return null;
}
let rv = new Hashtable();
for(let k in obj) {
rv.put(k, obj[k]);
}
return rv;
}
/**
* Gets a service registered with OSGi.
*
* @private
* @param {String|HostClass} classOrName the class of the service to get
* @returns an instance of the service, or null if it cannot be found
* @memberOf osgi
*/
let lookupService = function (classOrName) {
var bc = bundleContext;
if(bundleContext === undefined) {
log.warn("bundleContext is undefined");
var FrameworkUtil = Java.type("org.osgi.framework.FrameworkUtil");
var _bundle = FrameworkUtil.getBundle(scriptExtension.class);
bc = (_bundle !== null) ? _bundle.getBundleContext() : null;
}
if (bc !== null) {
var classname = (typeof classOrName === "object") ? classOrName.getName() : classOrName;
var ref = bc.getServiceReference(classname);
return (ref !== null) ? bc.getService(ref) : null;
}
}
/**
* Gets a service registered with OSGi. Allows providing multiple classes/names to try for lookup.
*
* @param {Array<String|HostClass>} classOrNames the class of the service to get
*
* @returns an instance of the service, or null if it cannot be found
* @throws {Error} if no services of the requested type(s) can be found
* @memberOf osgi
*/
let getService = function (...classOrNames) {
let rv = null;
for(let classOrName of classOrNames) {
try {
rv = lookupService(classOrName)
} catch(e) {
log.warn(`Failed to get service ${classOrName}: {}`, e);
}
if(typeof rv !== 'undefined' && rv !== null) {
return rv;
}
}
throw Error(`Failed to get any services of type(s): ${classOrNames}`);
}
/**
* Finds services registered with OSGi.
*
* @param {String} className the class of the service to get
* @param {*} [filter] an optional filter used to filter the returned services
* @returns {Object[]} any instances of the service that can be found
* @memberOf osgi
*/
let findServices = function (className, filter) {
if (bundleContext !== null) {
var refs = bundleContext.getAllServiceReferences(className, filter);
return refs != null ? [...refs].map(ref => bundleContext.getService(ref)) : [];
}
}
let registerService = function(service, ...interfaceNames) {
lifecycle.addDisposeHook(() => unregisterService(service));
registerPermanentService(service, interfaceNames, null);
}
let registerPermanentService = function(service, interfaceNames, properties = null) {
let registration = bundleContext.registerService(interfaceNames, service, jsObjectToHashtable(properties));
for (let interfaceName of interfaceNames) {
if(typeof registeredServices[interfaceName] === 'undefined') {
registeredServices[interfaceName] = new Set();
}
registeredServices[interfaceName].add({service, registration});
log.debug("Registered service {} of as {}", service, interfaceName)
}
return registration;
}
let unregisterService = function(serviceToUnregister) {
log.debug("Unregistering service {}", serviceToUnregister);
for(let interfaceName in registeredServices) {
let servicesForInterface = registeredServices[interfaceName];
servicesForInterface.forEach(({service, registration}) => {
if (service == serviceToUnregister) {
servicesForInterface.delete({service, registration});
registration.unregister();
log.debug("Unregistered service: {}", service);
}
});
}
}
module.exports = {
getService,
findServices,
registerService,
registerPermanentService,
unregisterService
}