-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsbvr-libs.ometajs
135 lines (124 loc) · 4.58 KB
/
sbvr-libs.ometajs
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
var _ = require('lodash');
export ometa SBVRLibs {}
SBVRLibs.initialize = function() {
this.currentVocabulary = '';
this.vocabularies = {};
this.factTypes = {};
};
SBVRLibs.ApplyFirstExisting = function(rules, ruleArgs) {
if(ruleArgs == null) {
ruleArgs = [];
}
for (var i = 0; i < rules.length; i++) {
if(this[rules[i]] != null) {
if(ruleArgs.length > 0) {
return this._applyWithArgs.apply(this, [rules[i]].concat(ruleArgs));
}
return this._apply(rules[i]);
}
}
};
SBVRLibs.IdentifiersEqual = function(a, b) {
return a[0] === b[0] && a[1] === b[1] && a[2] === b[2];
};
SBVRLibs.FollowConceptType = function(identifier) {
var conceptTypes = this.vocabularies[identifier[2]]['ConceptTypes'];
identifier = identifier.slice(0, 3);
if(conceptTypes.hasOwnProperty(identifier) ) {
return conceptTypes[identifier];
}
return false;
};
SBVRLibs.AddVocabulary = function(vocabulary, baseSynonym) {
this.currentVocabulary = baseSynonym;
if(!this.vocabularies.hasOwnProperty(baseSynonym)) {
this.vocabularies[baseSynonym] = {
'Term': {},
'Name': {},
'IdentifierChildren': {},
'ConceptTypes': {}
};
}
if(!this.vocabularies.hasOwnProperty(vocabulary)) {
this.vocabularies[vocabulary] = this.vocabularies[baseSynonym];
}
};
var formatFactType = function(factType) {
return factType.map(function(v) {
return v[1];
}).join(' ');
};
SBVRLibs.AddFactType = function(factType, realFactType) {
var mappedFactType = [],
matchingFactTypes = _.isEqual(factType, realFactType);
for(var i = 0; i < realFactType.length; i++) {
var realFactTypePart = realFactType[i];
mappedFactType[i] = realFactTypePart.slice(0, 3);
if(realFactTypePart[0] === 'Verb') { // If it's a verb we don't do any mapping
continue;
}
if(matchingFactTypes) {
// If the fact types match then the mapping will always be to themselves
mappedFactType[i][3] = i;
continue;
}
// Otherwise we have to map based upon matching identifiers + instance numbers
var mappingFound = false;
for(var j = 0; j < factType.length; j++) {
var factTypePart = factType[j];
if(factTypePart[0] !== 'Verb' // Not a verb
&& this.IdentifiersEqual(realFactTypePart, factTypePart) // The term/name matches
&& realFactTypePart.length === factTypePart.length // And they have the same length (so both have/do not have an instance number
&& (realFactTypePart.length < 4 || realFactTypePart[3][1] === factTypePart[3][1])) { // And they have no instance number, or the instance number matches.
if(mappingFound) {
// If we find two potential mappings for one term then we can't throw an error.
throw new Error('Ambiguous use of fact type "' + formatFactType(factType) + '", please add explicit numbering')
}
mappingFound = true;
mappedFactType[i][3] = j;
}
}
if(!mappingFound) {
throw new Error('Unable to map identifiers for "' + formatFactType(factType) + '", please add explicit numbering')
}
}
this._traverseFactType(factType, mappedFactType);
};
SBVRLibs._traverseFactType = function(factType, create) {
var self = this,
traverseRecurse = function(currentFactTypePart, remainingFactType, currentLevel) {
if(currentFactTypePart == null) {
if(create) {
currentLevel.__valid = create;
}
return currentLevel;
}
var finalLevel, finalLevels = {};
switch(currentFactTypePart[0]) {
case 'Verb':
currentFactTypePart = currentFactTypePart.slice(0, 2); // Make sure we only use the first 2 parts for verbs.
break;
default:
currentFactTypePart = currentFactTypePart.slice(0, 3); // Make sure we only use the first 3 parts for everything else.
}
if(currentLevel.hasOwnProperty(currentFactTypePart) || (create && (currentLevel[currentFactTypePart] = {})) ) {
finalLevel = traverseRecurse(remainingFactType[0], remainingFactType.slice(1), currentLevel[currentFactTypePart]);
if(finalLevel !== false) {
Object.assign(finalLevels, finalLevel);
}
}
if(!create && (currentFactTypePart[0] === 'Term' || currentFactTypePart[0] === 'Name')) {
while( (currentFactTypePart = self.FollowConceptType(currentFactTypePart)) !== false ) {
if( currentLevel.hasOwnProperty(currentFactTypePart) ) {
// We use recursion so here we go down each branch until we find the suitable one, or run out of branches.
finalLevel = traverseRecurse(remainingFactType[0], remainingFactType.slice(1), currentLevel[currentFactTypePart]);
if(finalLevel !== false) {
Object.assign(finalLevels, finalLevel);
}
}
}
}
return _.isEmpty(finalLevels) === true ? false : finalLevels;
};
return traverseRecurse(factType[0], factType.slice(1), this.factTypes);
};