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
|
odoo.define('web.AbstractService', function (require) {
"use strict";
var Class = require('web.Class');
const { serviceRegistry } = require("web.core");
var Mixins = require('web.mixins');
var ServicesMixin = require('web.ServicesMixin');
var AbstractService = Class.extend(Mixins.EventDispatcherMixin, ServicesMixin, {
dependencies: [],
init: function (env) {
Mixins.EventDispatcherMixin.init.call(this, arguments);
this.env = env;
},
/**
* @abstract
*/
start: function () {},
/**
* Directly calls the requested service, instead of triggering a
* 'call_service' event up, which wouldn't work as services have no parent
*
* @param {OdooEvent} ev
*/
_trigger_up: function (ev) {
Mixins.EventDispatcherMixin._trigger_up.apply(this, arguments);
if (ev.is_stopped()) {
return;
}
const payload = ev.data;
if (ev.name === 'call_service') {
let args = payload.args || [];
if (payload.service === 'ajax' && payload.method === 'rpc') {
// ajax service uses an extra 'target' argument for rpc
args = args.concat(ev.target);
}
const service = this.env.services[payload.service];
const result = service[payload.method].apply(service, args);
payload.callback(result);
} else if (ev.name === 'do_action') {
this.env.bus.trigger('do-action', payload);
}
},
//--------------------------------------------------------------------------
// Static
//--------------------------------------------------------------------------
/**
* Deploy services in the env (specializations of AbstractService registered
* into the serviceRegistry).
*
* @static
* @param {Object} env
*/
deployServices(env) {
const UndeployedServices = Object.assign({}, serviceRegistry.map);
function _deployServices() {
let done = false;
while (!done) {
// find a service with no missing dependency
const serviceName = Object.keys(UndeployedServices).find(serviceName => {
const Service = UndeployedServices[serviceName];
return Service.prototype.dependencies.every(depName => {
return env.services[depName];
});
});
if (serviceName) {
const Service = UndeployedServices[serviceName];
const service = new Service(env);
env.services[serviceName] = service;
delete UndeployedServices[serviceName];
service.start();
} else {
done = true;
}
}
}
serviceRegistry.onAdd((serviceName, Service) => {
if (serviceName in env.services || serviceName in UndeployedServices) {
throw new Error(`Service ${serviceName} is already loaded.`);
}
UndeployedServices[serviceName] = Service;
_deployServices();
});
_deployServices();
}
});
return AbstractService;
});
|