4c505322474d547c70ada2b4d7f397ce5a335668
[dlux.git] / modules / common-yangutils-resources / src / main / resources / yangutils / services / module-connector.services.js
1 define([], function () {
2     'use strict';
3
4     function ModuleConnectorService(){
5
6         var service = {
7                 processModuleObjs: processModuleObjs,
8                 __test: {
9                     isBuildInType: isBuildInType,
10                     linkFunctions: linkFunctions,
11                     findLinkedStatement: findLinkedStatement,
12                     appendChildren: appendChildren,
13                     searchModule: searchModule,
14                     applyLinks: applyLinks,
15                     interConnectModules: interConnectModules,
16                     applyModuleRevision: applyModuleRevision,
17                 },
18             },
19             linkFunctions = {
20                 uses: uses,
21                 type: type,
22             };
23
24         return service;
25
26         // TODO: add service's description
27         function processModuleObjs(modules) {
28             var rootNodes = [],
29                 augments = [],
30                 connectedModules = interConnectModules(modules.slice());
31
32             connectedModules.forEach(function (module) {
33                 rootNodes = rootNodes.concat(module.getRoots());
34                 augments = augments.concat(module.getAugments());
35             });
36
37             return { rootNodes: rootNodes, augments: augments };
38         }
39
40         // TODO: add function's description
41         function uses(usesNode, currentModule, parentNode) {
42             var targetType = 'grouping';
43             return function (modules) {
44                 var data = findLinkedStatement(usesNode, targetType, currentModule, modules),
45                     node = data.node,
46                     module = data.module,
47                     changed = false;
48
49                 if (node && module) {
50                     usesNode.parent.children.splice(usesNode.parent.children.indexOf(usesNode), 1); // delete uses node
51                     for (var i = 0; i < node.children.length; i++) {
52                         applyLinks(node.children[i], module, modules);
53                     }
54                     appendChildren(usesNode.parent, node);
55                     changed = true;
56                 }
57
58                 return changed;
59             };
60         }
61
62         // TODO: add function's description
63         function type(typeNode, currentModule, parentNode) {
64             var targetType = 'typedef';
65
66             if (isBuildInType(typeNode.label) === false) {
67                 return function (modules) {
68                     var data = findLinkedStatement(typeNode, targetType, currentModule, modules),
69                         node = data.node ? data.node.getChildren('type')[0] : null,
70                         changed = false;
71
72                     if (node) {
73                         // delete referencing type node
74
75                         parentNode.children.splice(typeNode.parent.children.indexOf(typeNode), 1);
76                         parentNode.addChild(node);
77                         changed = true;
78                     }
79
80                     return changed;
81                 };
82             } else {
83                 return function (modules) {
84                     return false;
85                 };
86             }
87         }
88
89         // TODO: add function's description
90         function isBuildInType(type) {
91             return ['int8', 'int16', 'int32', 'int64', 'uint8', 'uint16', 'uint32', 'uint64',
92                     'decimal64', 'string', 'boolean', 'enumeration', 'bits', 'binary',
93                     'leafref', 'identityref', 'empty', 'union', 'instance-identifier'].indexOf(type) > -1;
94         }
95
96         // TODO: add function's description
97         function findLinkedStatement(node, targetType, currentModule, modules) {
98             var sourceNode,
99                 sourceModule,
100                 link = node.label;
101
102             if (link.indexOf(':') > -1) {
103                 var parts = link.split(':'),
104                     targetImport = currentModule.getImportByPrefix(parts[0]);
105
106                 sourceModule = targetImport ?
107                                     searchModule(modules, targetImport.label, targetImport.revisionDate) : null;
108                 sourceNode = sourceModule ? sourceModule.searchNode(targetType, parts[1]) : null;
109             } else {
110                 sourceModule = searchModule(modules, node.module, node.moduleRevision);
111                 sourceNode = sourceModule ? sourceModule.searchNode(targetType, link) : null;
112             }
113
114             return { node: sourceNode, module: sourceModule };
115         }
116
117         // TODO: add function's description
118         function appendChildren(targetNode, sourceNode) {
119             sourceNode.children.forEach(function (child) {
120                 targetNode.addChild(child);
121             });
122         }
123
124         // TODO: add function's description
125         function searchModule(modules, moduleName, moduleRevision) {
126             var searchResults = modules.filter(function (item) {
127                     return (moduleName === item._name && (moduleRevision ? moduleRevision === item._revision : true));
128                 }),
129                 targetModule = (searchResults && searchResults.length) ? searchResults[0] : null;
130
131             return targetModule;
132         }
133
134         // TODO: add function's description
135         function applyLinks(node, module, modules, parentNode) {
136             var changed = false;
137             if (linkFunctions.hasOwnProperty(node.type)) { // applying link function to uses.node
138                 changed = linkFunctions[node.type](node, module, parentNode)(modules);
139             }
140
141             for (var i = 0; i < node.children.length; i++) {
142                 if (applyLinks(node.children[i], module, modules, node)) {
143                     i--;
144                     // need to repeat current index because we are deleting uses nodes,
145                     // so in case there are more uses in row, it would skip second one
146                 }
147             }
148
149             return changed;
150         }
151
152         // TODO: add function's description
153         function interConnectModules(modules) {
154
155             modules.forEach(function (module) {
156                 module.getRoots().concat(module.getRawAugments()).forEach(function (node) {
157                     applyLinks(node, module, modules);
158                 });
159             });
160
161             modules.forEach(function (module) {
162                 var copy = null;
163
164                 module._roots = module.getRoots().map(function (node) {
165                     copy = node.deepCopy();
166                     return applyModuleRevision(copy, module._name, module._revision);
167                 });
168
169                 module._augments = module.getRawAugments().map(function (node) {
170                     copy = node.deepCopy();
171                     return applyModuleRevision(copy, module._name, module._revision);
172                 });
173             });
174
175             return modules;
176         }
177
178         // TODO: add function's description
179         function applyModuleRevision(node, module, revision) {
180             node.module = module;
181             node.moduleRevision = revision;
182
183             node.children.map(function (child) {
184                 return applyModuleRevision(child, module, revision);
185             });
186
187             return node;
188         }
189     }
190
191     ModuleConnectorService.$inject = [];
192
193     return ModuleConnectorService;
194
195 });