forked from openhab/openhab-js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.js
274 lines (253 loc) · 7.83 KB
/
utils.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
const time = require('@js-joda/core');
/**
* openHAB JavaScript library version
*
* @memberof utils
* @name OPENHAB_JS_VERSION
* @type {string}
*/
const VERSION = require('./package.json').version;
const log = require('./log')('utils');
const HashSet = Java.type('java.util.HashSet');
const ArrayList = Java.type('java.util.ArrayList');
/**
* Utils namespace.
* This namespace handles utilities, especially for conversion from and to Java data types.
*
* @namespace utils
*/
function _getAllPropertyNames (obj) {
const proto = Object.getPrototypeOf(obj);
const inherited = (proto) ? _getAllPropertyNames(proto) : [];
return [...new Set(Object.getOwnPropertyNames(obj).concat(inherited))];
}
/**
* Convert JavaScript Set to Java Set.
*
* @memberOf utils
* @param {Set} set JavaScript Set
* @returns {JavaSet} Java Set
*/
function jsSetToJavaSet (set) {
const rv = new HashSet();
set.forEach(e => rv.add(e));
return rv;
}
/**
* Convert JavaScript Array to Java Set.
*
* @memberOf utils
* @param {Array} arr
* @returns {JavaSet} Java Set
*/
function jsArrayToJavaSet (arr) {
const set = new HashSet();
for (const i of arr) {
set.add(i);
}
return set;
}
/**
* Convert JavaScript Array to Java List.
*
* @memberOf utils
* @param {Array} arr JavaScript Array
* @returns {JavaList}
*/
function jsArrayToJavaList (arr) {
const list = new ArrayList();
for (const i of arr) {
list.add(i);
}
return list;
}
/**
* Convert Java List to JavaScript Array.
*
* @memberOf utils
* @param {JavaList} list
* @returns {Array} JavaScript Array
*/
function javaListToJsArray (list) {
return Java.from(list);
}
/**
* Convert Java Set to JavaScript Array.
*
* @memberOf utils
* @param {JavaSet} set
* @returns {Array} JavaScript Array
*/
function javaSetToJsArray (set) {
return Java.from(new ArrayList(set));
}
/**
* Convert Java Map to JavaScript Map.
*
* @memberof utils
* @param {JavaMap} map
* @returns {Map<any, any>} JavaScript Map
*/
function javaMapToJsMap (map) {
const js = new Map();
javaSetToJsSet(map.keySet()).forEach((key) => js.set(key, map.get(key)));
return js;
}
/**
* Convert Java Map to JavaScript Object.
*
* @memberof utils
* @param {JavaMap} map
* @returns {object} JavaScript Object
*/
function javaMapToJsObj (map) {
const obj = {};
map.forEach((key, val) => { obj[key] = val; });
return obj;
}
/**
* Convert Java Set to JavaScript Set.
*
* @memberOf utils
* @param {JavaSet} set Java Set ({@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Set.html})
* @returns {Set} JavaScript Set Object ({@link https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Set})
*/
function javaSetToJsSet (set) {
return new Set(javaSetToJsArray(set));
}
/**
* Generate a random UUID.
*
* @memberOf utils
* @returns {string} random UUID
*/
const randomUUID = () => Java.type('java.util.UUID').randomUUID();
/**
* Outputs all members and properties of an object and whether it is a JS or a Java Object to the log.
*
* @memberOf utils
* @param {*} obj object
* @param {boolean} [dumpProps=false] whether properties also should be dumped
*/
function dumpObject (obj, dumpProps = false) {
try {
log.info('Dumping object...');
log.info(' typeof obj = {}', (typeof obj));
const isJavaObject = Java.isJavaObject(obj);
log.info(' Java.isJavaObject(obj) = {}', isJavaObject);
const isJavaType = Java.isType(obj);
log.info(' Java.isType(obj) = {}', isJavaType);
if (isJavaObject) {
if (isJavaType) {
log.info(' Java.typeName(obj) = {}', Java.typeName(obj));
} else {
log.info(' Java.typeName(obj.getClass()) = {}', Java.typeName(obj.getClass()));
if (Java.typeName(obj.getClass()) === 'java.util.HashMap') {
log.info('Dumping contents...');
const keys = obj.keySet().toArray();
for (const key in keys) {
log.info('{}({}) = {}({})', keys[key], typeof keys[key], obj.get(keys[key]), typeof obj.get(keys[key]));
if (typeof keys[key] === 'object') {
log.info('Dumping key {} ...', keys[key]);
dumpObject(keys[key]);
}
}
}
}
} else if (typeof obj === 'string') {
log.info(' string value = ' + obj);
} else if (typeof obj === 'boolean') {
log.info(' boolean value = ' + obj);
} else if (typeof obj === 'number') {
log.info(' number value = ' + obj);
} else if (typeof obj === 'object' && obj != null) {
const keys = Object.keys(obj);
log.info(' getOwnPropertyNames(obj) = {}', keys.toString());
log.info(' getAllPropertyNames(obj) = {}', _getAllPropertyNames(obj).toString());
// log.info("obj.toString() = {}", obj.toString());
// log.info("JSON.stringify(obj) = {}", JSON.stringify(obj));
if (dumpProps === true) {
for (const key in keys) {
log.info('Dumping property {} ...', keys[key]);
dumpObject(obj[keys[key]]);
}
}
} else {
log.info(' value = ' + obj);
}
} catch (e) {
log.info('Failed to dump object: ' + e.message);
}
}
/**
* Checks whether an object is instance of a Java class.
*
* @memberOf utils
* @param {*} instance object
* @param {JavaClass} type Java class ({@link https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Class.html})
* @returns {boolean} whether it is an instance of a Java class
* @throws error if type is not a java class
*/
function isJsInstanceOfJava (instance, type) {
if (!Java.isType(type)) {
throw Error('type is not a java class');
}
if (instance === null || instance === undefined || instance.getClass() === null || instance.getClass() === undefined) {
return false;
}
return type.getClass().isAssignableFrom(instance.getClass());
}
/**
* Convert Java Instant to JS-Joda Instant.
*
* @memberOf utils
* @param {JavaInstant} instant {@link https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/Instant.html java.time.Instant}
* @returns {time.Instant} {@link https://js-joda.github.io/js-joda/class/packages/core/src/Instant.js~Instant.html JS-Joda Instant}
*/
function javaInstantToJsInstant (instant) {
return time.Instant.ofEpochMilli(instant.toEpochMilli());
}
/**
* Convert Java ZonedDateTime to JS-Joda ZonedDateTime.
*
* @memberOf utils
* @param {JavaZonedDateTime} zdt {@link https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/ZonedDateTime.html java.time.ZonedDateTime}
* @returns {time.ZonedDateTime} {@link https://js-joda.github.io/js-joda/class/packages/core/src/ZonedDateTime.js~ZonedDateTime.html JS-Joda ZonedDateTime}
*/
function javaZDTToJsZDT (zdt) {
const epoch = zdt.toInstant().toEpochMilli();
const instant = time.Instant.ofEpochMilli(epoch);
const zone = time.ZoneId.of(zdt.getZone().toString());
return time.ZonedDateTime.ofInstant(instant, zone);
}
/**
* Convert Java ZonedDateTime to JS-Joda ZonedDateTime and default to SYSTEM timezone if not explicitly set.
*
* @memberOf utils
* @param {JavaZonedDateTime} zdt {@link https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/ZonedDateTime.html java.time.ZonedDateTime}
* @returns {time.ZonedDateTime} {@link https://js-joda.github.io/js-joda/class/packages/core/src/ZonedDateTime.js~ZonedDateTime.html JS-Joda ZonedDateTime}
*/
function javaZDTToJsZDTWithDefaultZoneSystem (zdt) {
const jsZDT = javaZDTToJsZDT(zdt);
if (/^[+-]*/.test(jsZDT.zone().toString())) {
return jsZDT.withZoneSameLocal(time.ZoneId.SYSTEM);
}
return jsZDT;
}
module.exports = {
jsSetToJavaSet,
jsArrayToJavaSet,
jsArrayToJavaList,
javaListToJsArray,
javaSetToJsArray,
javaSetToJsSet,
javaMapToJsMap,
javaMapToJsObj,
randomUUID,
dumpObject,
isJsInstanceOfJava,
javaInstantToJsInstant,
javaZDTToJsZDT,
javaZDTToJsZDTWithDefaultZoneSystem,
OPENHAB_JS_VERSION: VERSION
};