-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathCondition.js
More file actions
104 lines (96 loc) · 4.02 KB
/
Copy pathCondition.js
File metadata and controls
104 lines (96 loc) · 4.02 KB
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
/**
* Created by hjiang on 3/4/17.
*/
let AttributeCondition = require("./AttributeCondition");
let Operators = require("./Operators");
class Condition {
constructor(owner, context, condition, usedFor = "Condition"){
this.name = owner;
this.usedFor = usedFor;
this.context = context;
this.logger = this.context.registry.getLogger();
this.operators = new Operators();
this.toString = JSON.stringify(condition);
this.condition = this._buildCondition(condition);
}
_buildCondition(condition){
// if the condition is of MAP type
if (condition.constructor === Object) {
// if the map has multiple keys, which are of AND relations
if (Object.keys(condition).length > 1) {
let allOf = [];
for (let key in condition) {
if(!condition.hasOwnProperty(key)) continue;
let value = condition[key];
allOf.push(this._buildCondition({[key]: value}));
}
condition = {"allOf": allOf};
}
// if the map contains exactly one key
else if (Object.keys(condition).length === 1){
let key = Object.keys(condition)[0];
let value = condition[key];
// if the key is an operator
if (key in this.operators){
value = Array.isArray(value)?value:[value];
condition[key] = value.map(subCondition=>{
return this._buildCondition(subCondition);
});
}
// if the key is an attribute
else if (key in this.context){
condition = new AttributeCondition(this.context, condition);
}
// else invalid
else {
this.logger.info(`[${this.name}] warning: unrecognized key when building condition: ${key}`);
}
}
// else the map is empty
else {
// this.logger.info(`[${this.name}] warning: empty ${this.usedFor} implies global applicability`);
}
}
// if the condition is of ARRAY type, which contains subConditions with OR relations
else {
condition = condition.map(subCondition=>{return this._buildCondition(subCondition)});
condition = condition.length===0?{}:{"anyOf": condition};
}
return condition;
}
isApplicable(message, condition = this.condition){
if (condition instanceof AttributeCondition){
return condition.isApplicable(message);
}
// if the condition is not of Object type
else if (condition.constructor !== Object) {
throw new Error(`[${this.name}] syntax error: compiled condition should only be of Object type`);
}
// the condition is not an instance of AttributeCondition
// the condition contains multiple keys
else if (Object.keys(condition).length > 1){
throw new Error(`[${this.name}] syntax error: compiled condition contains multiple keys in a map`);
}
// the condition contains only one key
else if (Object.keys(condition).length === 1) {
let key = Object.keys(condition)[0];
let value = condition[key];
if (key in this.operators) {
return this.operators[key](
value.map(subCondition => {
return this.isApplicable(message, subCondition);
})
);
} else if (key in this.context){
throw new Error(`[${this.name}] syntax error: attribute is failed to build attribute condition object: ${key}`);
} else {
throw new Error(`[${this.name}] syntax error: unrecognized key in condition field: ${key}`);
}
}
// empty condition
else {
return true;
}
}
}
module.exports = Condition;