blob: ef5518099c7323b499b3a5a81f0d4876bd1a33f0 [file] [log] [blame]
Sean Condon83fc39f2018-04-19 18:56:13 +01001/*
Sean Condon5ca00262018-09-06 17:55:25 +01002 * Copyright 2018-present Open Networking Foundation
Sean Condon83fc39f2018-04-19 18:56:13 +01003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Sean Condonb2c483c2019-01-16 20:28:55 +000016import {Inject, Injectable} from '@angular/core';
Bhavesh72ead492018-07-19 16:29:18 +053017import { FnService } from './fn.service';
Sean Condon5ca00262018-09-06 17:55:25 +010018import { LogService } from '../log.service';
Sean Condon83fc39f2018-04-19 18:56:13 +010019import { WebSocketService } from '../remote/websocket.service';
20
Sean Condonb2c483c2019-01-16 20:28:55 +000021const UPDATE_PREFS: string = 'updatePrefs';
22const UPDATE_PREFS_REQ: string = 'updatePrefReq';
Sean Condon0d064ec2019-02-04 21:53:53 +000023
24
Sean Condon83fc39f2018-04-19 18:56:13 +010025/**
26 * ONOS GUI -- Util -- User Preference Service
27 */
Sean Condona00bf382018-06-23 07:54:01 +010028@Injectable({
Bhavesh72ead492018-07-19 16:29:18 +053029 providedIn: 'root',
Sean Condona00bf382018-06-23 07:54:01 +010030})
Sean Condon83fc39f2018-04-19 18:56:13 +010031export class PrefsService {
Bhavesh72ead492018-07-19 16:29:18 +053032 protected handlers: string[] = [];
Sean Condonb2c483c2019-01-16 20:28:55 +000033 cache: Object;
34 listeners: ((data) => void)[] = [];
Sean Condon83fc39f2018-04-19 18:56:13 +010035 constructor(
Bhavesh72ead492018-07-19 16:29:18 +053036 protected fs: FnService,
37 protected log: LogService,
Sean Condonb2c483c2019-01-16 20:28:55 +000038 protected wss: WebSocketService,
39 @Inject('Window') private window: any
Sean Condon83fc39f2018-04-19 18:56:13 +010040 ) {
Bhavesh72ead492018-07-19 16:29:18 +053041 this.wss.bindHandlers(new Map<string, (data) => void>([
Sean Condonb2c483c2019-01-16 20:28:55 +000042 [UPDATE_PREFS, (data) => this.updatePrefs(data)]
Bhavesh72ead492018-07-19 16:29:18 +053043 ]));
Sean Condonb2c483c2019-01-16 20:28:55 +000044 this.handlers.push(UPDATE_PREFS);
45
46 // When index.html is fetched it is served up by MainIndexResource.java
47 // which fetches userPrefs in to the global scope.
48 // After that updates are done through WebSocket
Sean Condon98b6ddb2019-12-24 08:07:40 +000049 this.cache = (<any>Object).assign({}, this.window['userPrefs']);
Bhavesh72ead492018-07-19 16:29:18 +053050
Sean Condon83fc39f2018-04-19 18:56:13 +010051 this.log.debug('PrefsService constructed');
52 }
53
Sean Condonb2c483c2019-01-16 20:28:55 +000054 setPrefs(name: string, obj: Object) {
Bhavesh72ead492018-07-19 16:29:18 +053055 // keep a cached copy of the object and send an update to server
56 this.cache[name] = obj;
Sean Condonb2c483c2019-01-16 20:28:55 +000057 this.wss.sendEvent(UPDATE_PREFS_REQ, { key: name, value: obj });
Bhavesh72ead492018-07-19 16:29:18 +053058 }
59 updatePrefs(data: any) {
60 this.cache = data;
Sean Condonb2c483c2019-01-16 20:28:55 +000061 this.listeners.forEach((lsnr) => lsnr(data) );
Bhavesh72ead492018-07-19 16:29:18 +053062 }
63
64 asNumbers(obj: any, keys?: any, not?: any) {
65 if (!obj) {
66 return null;
67 }
68
69 const skip = {};
70 if (not) {
71 keys.forEach(k => {
72 skip[k] = 1;
73 }
74 );
75 }
76
77 if (!keys || not) {
78 // do them all
79 Array.from(obj).forEach((v, k) => {
80 if (!not || !skip[k]) {
81 obj[k] = Number(obj[k]);
82 }
83 });
84 } else {
85 // do the explicitly named keys
86 keys.forEach(k => {
87 obj[k] = Number(obj[k]);
88 });
89 }
90 return obj;
91 }
92
Sean Condon0d064ec2019-02-04 21:53:53 +000093 getPrefs(name: string, defaults: Object, qparams?: string) {
Sean Condon98b6ddb2019-12-24 08:07:40 +000094 const obj = (<any>Object).assign({}, defaults || {}, this.cache[name] || {});
Bhavesh72ead492018-07-19 16:29:18 +053095
96 // if query params are specified, they override...
97 if (this.fs.isO(qparams)) {
98 obj.forEach(k => {
99 if (qparams.hasOwnProperty(k)) {
100 obj[k] = qparams[k];
101 }
102 });
103 }
104 return obj;
105 }
106
107 // merge preferences:
108 // The assumption here is that obj is a sparse object, and that the
109 // defined keys should overwrite the corresponding values, but any
110 // existing keys that are NOT explicitly defined here should be left
111 // alone (not deleted).
Sean Condonb2c483c2019-01-16 20:28:55 +0000112 mergePrefs(name: string, obj: any): void {
Bhavesh72ead492018-07-19 16:29:18 +0530113 const merged = this.cache[name] || {};
Sean Condon98b6ddb2019-12-24 08:07:40 +0000114 this.setPrefs(name, (<any>Object).assign(merged, obj));
Bhavesh72ead492018-07-19 16:29:18 +0530115 }
116
Sean Condonb2c483c2019-01-16 20:28:55 +0000117 /**
118 * Add a listener function
119 * This will get called back when an 'updatePrefs' message is received on WSS
120 * @param listener a function that can accept one param - data
121 */
122 addListener(listener: (data) => void): void {
Bhavesh72ead492018-07-19 16:29:18 +0530123 this.listeners.push(listener);
124 }
125
Sean Condonb2c483c2019-01-16 20:28:55 +0000126 removeListener(listener: (data) => void) {
127 this.listeners = this.listeners.filter((obj) => obj !== listener);
Bhavesh72ead492018-07-19 16:29:18 +0530128 }
129
Sean Condon83fc39f2018-04-19 18:56:13 +0100130}