d554ca7e04db5dd504d4fe9b5ba0ddf76dbf3a32
[dlux.git] / modules / common-yangutils-resources / src / main / resources / yangutils / yangutils.services.js
1 define(['common/yangutils/yangutils.module'], function (yangUtils) {\r
2 \r
3     yangUtils.factory('nodeUtils',function () {\r
4         var nu = {};\r
5 \r
6         nu.isRootNode = function(type) {\r
7             return type === 'container' || type === 'list' || type === 'rpc';\r
8         };\r
9 \r
10         nu.isOnlyOperationalNode = function(node) {\r
11             return node.hasOwnProperty('isConfigStm') ? node.isConfigStm !== false : true;\r
12         };\r
13 \r
14         return nu;\r
15     });\r
16 \r
17     yangUtils.factory('YangUtilsRestangular', ['Restangular', 'ENV', 'constants', function (Restangular, ENV, constants) {\r
18         var isEmptyElement = function(element) {\r
19             return element.hasOwnProperty('id') && element.id === undefined;\r
20         };\r
21 \r
22         var r = Restangular.withConfig(function(RestangularConfig) {\r
23             RestangularConfig.setBaseUrl(ENV.getBaseURL("MD_SAL"));\r
24             RestangularConfig.setRequestInterceptor(function(elem, operation) {\r
25                 if (operation === 'post' && isEmptyElement(elem)) {\r
26                     return null;\r
27                 } else {\r
28                     return elem;\r
29                 }\r
30             });\r
31         });\r
32 \r
33         return r;\r
34     }]);\r
35 \r
36     yangUtils.factory('parsingJson', function () {\r
37         var pj = {};\r
38 \r
39         pj.parseJson = function(data, parsingErrorClbk){\r
40 \r
41             var result = null;\r
42 \r
43             try{\r
44                 result = JSON.parse(data);\r
45             }catch(e){\r
46                 if(angular.isFunction(parsingErrorClbk)){\r
47                     parsingErrorClbk(e);\r
48                 }\r
49             }\r
50 \r
51             finally {\r
52                 return result;\r
53             }\r
54 \r
55         };\r
56 \r
57         return pj;\r
58     });\r
59 \r
60     yangUtils.factory('eventDispatcher', function () {\r
61 \r
62         var eD = {};\r
63 \r
64         var convertArgsToList = function(arg) {\r
65             var argList = [],\r
66                 l = arg.length,\r
67                 i = 0;\r
68 \r
69             for(i = 0; i < l; i++) {\r
70                 argList.push(arg[i]);\r
71             }\r
72 \r
73             return argList;\r
74         };\r
75 \r
76         eD.broadcastHandler = {};\r
77 \r
78         eD.registerHandler = function(source, bcCallback) {\r
79             eD.broadcastHandler[source] = bcCallback;\r
80         };\r
81 \r
82         eD.dispatch = function() {\r
83             var args = convertArgsToList(arguments),\r
84                 argumentList = args.slice(1),\r
85                 handler = eD.broadcastHandler[arguments[0]];\r
86 \r
87             if(handler) {\r
88                 handler(argumentList);\r
89             }\r
90         };\r
91 \r
92         return eD;\r
93     });\r
94 \r
95     yangUtils.factory('arrayUtils', function () {\r
96 \r
97         var arrayUtils = {};\r
98 \r
99         arrayUtils.getFirstElementByCondition = function(list, condition) {\r
100             var selItems = list && condition ? list.filter(function(item) {\r
101                 return condition(item);\r
102             }) : [];\r
103             return (selItems.length ? selItems[0] : null);\r
104         };\r
105 \r
106         arrayUtils.pushElementsToList = function(list, listToAdd) {\r
107             listToAdd.forEach(function(e) {\r
108                 list.push(e);\r
109             });\r
110         };\r
111 \r
112         return arrayUtils;\r
113     });\r
114 \r
115     yangUtils.factory('YangUIApis', function (YangUtilsRestangular) {\r
116         var apis = {};\r
117 \r
118         apis.getAllModules = function() {\r
119             return YangUtilsRestangular.one('restconf').one('modules');\r
120         };\r
121 \r
122         apis.getModuleSchema = function(name, rev) {\r
123             return YangUtilsRestangular.one('restconf').one('modules').one('module').one(name).one(rev).one('schema');\r
124         };\r
125 \r
126         apis.getSingleModuleInfo = function(modulePath) {\r
127             return YangUtilsRestangular.one('restconf').one('modules').one('module').customGET(modulePath);\r
128         };\r
129 \r
130         apis.getAllApis = function() {\r
131             return YangUtilsRestangular.one('apidoc').one('apis');\r
132         };\r
133 \r
134         apis.getSingleApiInfo = function(apiPath) {\r
135             return YangUtilsRestangular.one('apidoc').one('apis').customGET(apiPath);\r
136         };\r
137 \r
138         apis.getCustomModules = function(baseApiPath) {\r
139             return YangUtilsRestangular.one('restconf').one('modules').customGET(baseApiPath);\r
140         };\r
141 \r
142         apis.getCustomModules = function(baseApiPath) {\r
143             return YangUtilsRestangular.one('restconf').one('modules').customGET(baseApiPath);\r
144         };\r
145 \r
146         return apis;\r
147     });\r
148 \r
149     yangUtils.factory('pathUtils', function (arrayUtils, syncFact) {\r
150 \r
151         var pathUtils = {},\r
152             parentPath = '..';\r
153 \r
154         var Idenfitier = function(label, value) {\r
155             this.label = label;\r
156             this.value = value || '';\r
157         };\r
158 \r
159         var PathElem = function (name, module, identifierNames, moduleChanged, revision) {\r
160             this.name = name;\r
161             this.module = module;\r
162             this.identifiers = identifierNames ? identifierNames.map(function(name) {\r
163                 return new Idenfitier(name);\r
164             }) : [];\r
165             this.moduleChanged = moduleChanged || false;\r
166             this.revision = revision;\r
167 \r
168             this.equals = function(comparedElem, compareIdentifierValues) {\r
169                 var result = this.name === comparedElem.name && this.module === comparedElem.module && this.identifiers.length === comparedElem.identifiers.length;\r
170 \r
171                 if(result) {\r
172                     var identifiersCnt = this.identifiers.length,\r
173                         i;\r
174 \r
175                     for(i = 0; i < identifiersCnt && result; i++) {\r
176                         result = this.identifiers[i].label === comparedElem.identifiers[i].label;\r
177                         if(compareIdentifierValues) {\r
178                             result = this.identifiers[i].value === comparedElem.identifiers[i].value;\r
179                         }\r
180                     }\r
181                 }\r
182 \r
183                 return result;\r
184             };\r
185 \r
186             this.hasIdentifier = function () {\r
187                 return this.identifiers.length > 0;\r
188             };\r
189 \r
190             this.addIdentifier = function(name) {\r
191                 this.identifiers.push(new Idenfitier(name));\r
192             };\r
193 \r
194             this.getIdentifierValues = function() {\r
195                 return this.identifiers.map(function(i) {\r
196                     return i.value;\r
197                 });\r
198             };\r
199 \r
200             this.toString = function () {\r
201                 return (this.module ? this.module + ':' : '') + this.name + '/' + (this.hasIdentifier() ? this.getIdentifierValues().join('/') + '/' : '');\r
202             };\r
203 \r
204             this.checkNode = function (node) {\r
205                 return (this.module ? this.module === node.module : true) && (this.name ? this.name === node.label : true) && (this.revision ? this.revision === node.moduleRevision : true);\r
206             };\r
207 \r
208             this.clone = function() {\r
209                 var copy = new PathElem(this.name, this.module, null, this.moduleChanged, this.revision);\r
210 \r
211                 copy.identifiers = this.identifiers.map(function(i) {\r
212                     return new Idenfitier(i.label, i.value);\r
213                 });\r
214 \r
215                 return copy;\r
216             };\r
217         };\r
218 \r
219         var getModuleNodePair = function (pathString, defaultModule) {\r
220             return pathString.indexOf(':') > -1 ? pathString.split(':') : [defaultModule, pathString];\r
221         };\r
222 \r
223         var isIdentifier = function (item) {\r
224             return (item.indexOf('{') === item.indexOf('}')) === false;\r
225         };\r
226 \r
227         var searchForRevisionInImportNodes = function(module, importNodes) {\r
228             var revision = null,\r
229                 node = importNodes.filter(function(i) {\r
230                     return i.label === module;\r
231                 })[0];\r
232 \r
233             if(node) {\r
234                 revision = node._revisionDate;\r
235             }\r
236 \r
237             return revision;\r
238         };\r
239 \r
240         pathUtils.createPathElement = function (name, module, identifierStrings, moduleChanged, revision) {\r
241             return new PathElem(name, module, identifierStrings, moduleChanged, revision);\r
242         };\r
243 \r
244         pathUtils.search = function (node, path) {\r
245             var pathElem = path.shift(),\r
246                 selNode = pathElem.name === parentPath ?\r
247                 node.parent :\r
248                 arrayUtils.getFirstElementByCondition(node.children, function (child) {\r
249                     return pathElem.checkNode(child);\r
250                 });\r
251 \r
252             if (selNode !== null) {\r
253                 if (path.length) {\r
254                     return pathUtils.search(selNode, path);\r
255                 } else {\r
256                     return selNode;\r
257                 }\r
258             } else {\r
259                 console.warn('pathUtils.search: cannot find element ',pathElem.name);\r
260                 return null;\r
261             }\r
262         };\r
263 \r
264         pathUtils.translate = function(path, prefixConverter, importNodes, getDefaultModuleCallback) {\r
265             var pathStrElements = path.split('/').filter(function(e) {\r
266                     return e !== '';\r
267                 }),\r
268                 pathArrayElements = [],\r
269                 index,\r
270                 maxIndex = pathStrElements.length,\r
271                 getLastElement = function(a) {\r
272                     return pathArrayElements.length > 0 ? pathArrayElements[pathArrayElements.length - 1] : null;\r
273                 },\r
274                 getElementModule = function(e) {\r
275                     return e ? e.module : '';\r
276                 },\r
277                 getModuleChange = function(actModule, lastElemModule) {\r
278                     return (lastElemModule !== null) ? actModule !== lastElemModule : false;\r
279                 };\r
280 \r
281             for(index = 0; index < maxIndex; index += 1) {\r
282                 var actElem = pathStrElements[index],\r
283                     lastElem = getLastElement(pathArrayElements);\r
284 \r
285                 if(isIdentifier(actElem) && lastElem) {\r
286                     lastElem.addIdentifier(actElem.slice(1, -1));\r
287                 } else {\r
288                 \r
289                     var lastElemModule = getElementModule(lastElem),\r
290                         defaultModule = getDefaultModuleCallback ? getDefaultModuleCallback() : lastElemModule,\r
291                         pair = getModuleNodePair(actElem, defaultModule),\r
292                         processedModule = (prefixConverter && pair[0] !== lastElemModule) ? prefixConverter(pair[0]) : pair[0],\r
293                         revision = importNodes ? searchForRevisionInImportNodes(processedModule, importNodes) : null,\r
294                         pathElem = pathUtils.createPathElement(pair[1], processedModule, null, getModuleChange(processedModule, lastElemModule), revision);\r
295 \r
296                     pathArrayElements.push(pathElem);\r
297                 }\r
298             }\r
299 \r
300             return pathArrayElements;\r
301         };\r
302 \r
303         pathUtils.translatePathArray = function(pathArray) {\r
304             var getIdentifiersValues = function(identifiers) {\r
305                     return identifiers.map(function(i) {\r
306                         return i.value;\r
307                     }).join('/');\r
308                 },\r
309                 getLastElem = function(i) {\r
310                     var result = null;\r
311                     if((i - 1) >= 0) {\r
312                         result = pathArray[i - 1];\r
313                     }\r
314                     return result;\r
315                 },\r
316                 getModuleStr = function(actElem, lastElem) {\r
317                     return ((lastElem && actElem.module && lastElem.module !== actElem.module) ? (actElem.module + ':') : '');\r
318                 },\r
319                 getIdentifiersStr = function(actElem) {\r
320                     return (actElem.hasIdentifier() ? '/' + getIdentifiersValues(actElem.identifiers) : '');\r
321                 },\r
322                 getElemStr = function(actElem, lastElem) {\r
323                     return getModuleStr(actElem, lastElem) + actElem.name + getIdentifiersStr(actElem);\r
324                 };\r
325 \r
326             return pathArray.map(function(pe, i) {\r
327                 return getElemStr(pe, getLastElem(i));\r
328             });\r
329         };\r
330 \r
331         var trimPath = function(pathString) {\r
332             var searchStr = 'restconf',\r
333                 output = pathString;\r
334 \r
335             if(pathString.indexOf(searchStr) > -1) {\r
336                 output = pathString.slice(pathString.indexOf(searchStr)+searchStr.length+1);\r
337             }\r
338 \r
339             return output;\r
340         };\r
341 \r
342         var changeTreeDataNode = function(treeApiNode, treeData, prop, val) {\r
343             var sel = treeApiNode ? treeData.filter(function(d) {\r
344                             return d.branch.uid === treeApiNode.uid;\r
345                         }) : [];\r
346 \r
347             if(sel.length === 1) {\r
348                 sel[0].branch[prop] = val;\r
349             }\r
350         };\r
351 \r
352         var changeTreeDataByProp = function(treeData, props, vals) {\r
353             treeData.forEach(function(d, index) {\r
354                 props.forEach(function(v, i){\r
355                     d.branch[v] = vals[i];\r
356                 });\r
357             });\r
358         };\r
359 \r
360         pathUtils.fillPath = function(pathArrayIn, pathString) {\r
361             var pathArray = trimPath(pathString).split('/'),\r
362                 pathPosition = 0;\r
363 \r
364             pathArrayIn.forEach(function(pathItem, index){\r
365                 if ( pathItem.hasIdentifier() ){\r
366                     pathItem.identifiers.forEach(function(identifier){\r
367                         pathPosition++;\r
368                         identifier.value = pathArray[pathPosition];\r
369                     });\r
370                 }\r
371                 pathPosition++;\r
372             });\r
373 \r
374         };\r
375 \r
376         var getActElementChild = function(actElem, childLabel) {\r
377             var sel = actElem.children.filter(function(child) {\r
378                     return child.label === childLabel;\r
379                 }),\r
380                 ret = sel.length === 1 ? sel[0] : null;\r
381 \r
382             return ret;\r
383         };\r
384 \r
385         pathUtils.getModuleNameFromPath = function(path){\r
386             var pathArray = pathUtils.translate(trimPath(path));\r
387 \r
388             return pathArray.length > 1 ? pathArray[1].module : null;\r
389         };\r
390 \r
391         pathUtils.searchNodeByPath = function(pathString, treeApis, treeData, disabledExpand) {\r
392             var pathArray = pathUtils.translate(trimPath(pathString)),\r
393                 module = pathArray.length > 1 ? pathArray[1].module : null,\r
394                 selectedTreeApi = module ? treeApis.filter(function(treeApi) {\r
395                     return treeApi.module === module;\r
396                 })[0] : null,\r
397                 retObj = null;\r
398 \r
399             if(selectedTreeApi && pathArray.length) {\r
400                 var actElem = selectedTreeApi,\r
401                     continueCondition = true;\r
402 \r
403                 if ( !disabledExpand ) {\r
404                     changeTreeDataByProp(treeData, ['expanded','selected'], [false, false]);\r
405                 }\r
406 \r
407                 for(i = 0; i < pathArray.length && continueCondition; ) {\r
408                     if ( !disabledExpand ) {\r
409                         changeTreeDataNode(actElem, treeData, 'expanded', true);\r
410                     }\r
411 \r
412                     var nextElem = getActElementChild(actElem, pathArray[i].name);\r
413                     if(nextElem !== null) {\r
414                         actElem = nextElem;\r
415                         i = i + ( actElem && actElem.identifiersLength > 0 ? actElem.identifiersLength + 1 : 1);\r
416                     } else {\r
417                         continueCondition = false;\r
418                     }\r
419                 }\r
420 \r
421                 if ( !disabledExpand ) {\r
422                     changeTreeDataNode(actElem, treeData, 'selected', true);\r
423                 }\r
424 \r
425                 if(actElem) {\r
426                     retObj = { indexApi: actElem.indexApi, indexSubApi: actElem.indexSubApi };\r
427                 }\r
428             }\r
429             return retObj;\r
430         };\r
431 \r
432         pathUtils.fillIdentifiers = function(identifiers, label, value) {\r
433           identifiers.some(function(i) {\r
434                 var identifierMatch = i.label === label;\r
435                 if(identifierMatch) {\r
436                     i.value = value || '';\r
437                 }\r
438 \r
439                 return identifierMatch;\r
440             });\r
441         };\r
442 \r
443         pathUtils.fillListNode = function(node, label, value) {\r
444             if(node.type === 'list' && node.actElemStructure !== null) {\r
445                 var nodeToFill = node.actElemStructure.getChildren('leaf', label)[0];\r
446 \r
447                 if(nodeToFill) {\r
448                   nodeToFill.fill(nodeToFill.label, value);\r
449                 }\r
450             }\r
451         };\r
452 \r
453         pathUtils.fillListRequestData = function(data, listLabel, label, value){\r
454             if ( data.hasOwnProperty(listLabel) && data[listLabel].length ) {\r
455                 data[listLabel][0][label] = value;\r
456             }\r
457         };\r
458 \r
459         pathUtils.findIndexOfStrInPathStr = function(pathParts, targetStr) { //pathParts is path string split by '/'\r
460             var targetIndex = -1;\r
461 \r
462             pathParts.some(function(p, i) {\r
463                 var condition = p === targetStr;\r
464                 if(condition) {\r
465                     targetIndex = i;\r
466                 }\r
467                 return condition;\r
468             });\r
469 \r
470             return targetIndex;\r
471         };\r
472 \r
473         pathUtils.getStorageAndNormalizedPath = function(pathStr) {\r
474             var pathParts = pathStr.split('/'),\r
475                 restconfIndex = pathUtils.findIndexOfStrInPathStr(pathParts, 'restconf'),\r
476                 storage = pathParts[restconfIndex + 1],\r
477                 normalizedPath = pathParts.slice(restconfIndex + 1).join('/');\r
478 \r
479             return { storage: storage, normalizedPath: normalizedPath };\r
480         };\r
481 \r
482         pathUtils.__test = {\r
483             PathElem: PathElem,\r
484             getModuleNodePair: getModuleNodePair,\r
485             isIdentifier: isIdentifier\r
486         };\r
487 \r
488         return pathUtils;\r
489     });\r
490 \r
491     yangUtils.factory('syncFact', function ($timeout) {\r
492         var timeout = 180000;\r
493 \r
494         var SyncObject = function () {\r
495             this.runningRequests = [];\r
496             this.reqId = 0;\r
497             this.timeElapsed = 0;\r
498 \r
499             this.spawnRequest = function (digest) {\r
500                 var id = digest + (this.reqId++).toString();\r
501                 this.runningRequests.push(id);\r
502                 //console.debug('adding request ',id,' total running requests  = ',this.runningRequests);\r
503                 return id;\r
504             };\r
505 \r
506             this.removeRequest = function (id) {\r
507                 var index = this.runningRequests.indexOf(id);\r
508 \r
509                 if (index > -1) {\r
510                     this.runningRequests.splice(index, 1);\r
511                     //console.debug('removing request ',id,' remaining requests = ',this.runningRequests);\r
512                 } else {\r
513                     console.warn('cannot remove request', id, 'from', this.runningRequests, 'index is', index);\r
514                 }\r
515             };\r
516 \r
517             this.waitFor = function (callback) {\r
518                 var t = 1000,\r
519                         processes = this.runningRequests.length,\r
520                         self = this;\r
521 \r
522                 if (processes > 0 && self.timeElapsed < timeout) {\r
523                     // console.debug('waitin on',processes,'processes',this.runningRequests);\r
524                     $timeout(function () {\r
525                         self.timeElapsed = self.timeElapsed + t;\r
526                         self.waitFor(callback);\r
527                     }, t);\r
528                 } else {\r
529                     callback();\r
530                 }\r
531             };\r
532         };\r
533 \r
534         return {\r
535             generateObj: function () {\r
536                 return new SyncObject();\r
537             }\r
538         };\r
539     });\r
540 \r
541 \r
542     yangUtils.factory('custFunct', function (reqBuilder) {\r
543         var CustFunctionality = function (label, node, callback, viewStr, hideButtonOnSelect) {\r
544             this.label = label;\r
545             this.callback = callback;\r
546             this.viewStr = viewStr;\r
547             this.hideButtonOnSelect = hideButtonOnSelect;\r
548 \r
549             this.setCallback = function (callback) {\r
550                 this.callback = callback;\r
551             };\r
552 \r
553             this.runCallback = function (args) {\r
554                 if (this.callback) {\r
555                     this.callback(args);\r
556                 } else {\r
557                     console.warn('no callback set for custom functionality', this.label);\r
558                 }\r
559             };\r
560         };\r
561 \r
562         var cmpApiToTemplatePath = function(subApi, templateStr) {\r
563             var subApiStr = subApi.storage + '/' + subApi.pathTemplateString;\r
564             return subApiStr === templateStr;\r
565         };\r
566 \r
567         custFunct = {};\r
568 \r
569         custFunct.createNewFunctionality = function (label, node, callback, viewStr, hideButtonOnSelect) {\r
570             if (node && callback) {\r
571                 return new CustFunctionality(label, node, callback, viewStr, hideButtonOnSelect);\r
572             } else {\r
573                 console.error('no node or callback is set for custom functionality');\r
574             }\r
575         };\r
576 \r
577         custFunct.getMPCustFunctionality = function(funcList) {\r
578             var mpCF = funcList.filter(function(cf) {\r
579                 return cf.label === 'YANGUI_CUST_MOUNT_POINTS';\r
580             });\r
581 \r
582             return mpCF[0];\r
583         };\r
584 \r
585         custFunct.createCustomFunctionalityApis = function (apis, module, revision, pathString, label, callback, viewStr, hideButtonOnSelect) {\r
586             apis = apis.map(function (item) {\r
587                 if ((module ? item.module === module : true) && (revision ? item.revision === revision : true)) {\r
588 \r
589                     item.subApis = item.subApis.map(function (subApi) {\r
590                         \r
591                         if (cmpApiToTemplatePath(subApi, pathString)) {\r
592                             subApi.addCustomFunctionality(label, callback, viewStr, hideButtonOnSelect);\r
593                         }\r
594 \r
595                         return subApi;\r
596                     });\r
597                 }\r
598 \r
599                 return item;\r
600             });\r
601         };\r
602 \r
603         return custFunct;\r
604     });\r
605 \r
606 \r
607     yangUtils.factory('reqBuilder', function () {\r
608 \r
609         var transformPropData = function(data) {\r
610             // return data || {};\r
611             return data;\r
612         };\r
613 \r
614         var builder = {\r
615             createObj: function () {\r
616                 return {};\r
617             },\r
618             createList: function () {\r
619                 return [];\r
620             },\r
621             insertObjToList: function (list, obj) {\r
622                 list.push(obj);\r
623             },\r
624             insertPropertyToObj: function (obj, propName, propData) {\r
625                 var data = transformPropData(propData),\r
626                     name = propName;\r
627 \r
628                 obj[name] = data;\r
629             },\r
630             resultToString: function (obj) {\r
631                 return JSON.stringify(obj, null, 4);\r
632             }\r
633         };\r
634 \r
635         return builder;\r
636 \r
637     });\r
638 \r
639 \r
640     yangUtils.factory('typeWrapper', function (restrictionsFact) {\r
641         var findLeafParent = function (node) {\r
642             if (node.type === 'leaf') {\r
643                 return node;\r
644             } else {\r
645                 if (node.parent) {\r
646                     return findLeafParent(node.parent);\r
647                 } else {\r
648                     return null;\r
649                 }\r
650             }\r
651         };\r
652 \r
653         var wrapper = {\r
654             wrapAll: function (node) {\r
655                 if (node.type === 'type') {\r
656                     this._setDefaultProperties(node);\r
657                 }\r
658 \r
659                 if(this.hasOwnProperty(node.label)) {\r
660                     this[node.label](node);\r
661                 }\r
662             },\r
663             _setDefaultProperties: function (node) {\r
664                 var fnToString = function (string) {\r
665                     var valueStr = '';\r
666 \r
667                     if(string !== null) {\r
668                         try {\r
669                             valueStr = string.toString();\r
670                         } catch (e) {\r
671                             console.warn('cannot convert value', node.value);\r
672                         }\r
673                     }\r
674 \r
675                     return valueStr;\r
676                 };\r
677 \r
678                 node.leafParent = findLeafParent(node);\r
679                 node.builtInChecks = [];\r
680                 node.errors = [];\r
681                 node.clear = function () {\r
682                 };\r
683                 node.fill = function () {\r
684                 };\r
685                 node.performRestrictionsCheck = function (value) {\r
686                     var patternRestrictions = node.getChildren('pattern'),\r
687                         patternCheck = function(value) {\r
688                             return patternRestrictions.map(function(patternNode) {\r
689                                 return patternNode.restrictions[0];\r
690                             }).some(function(patternRestriction) {\r
691                                 var condition = patternRestriction.check(value);\r
692                                 if(condition === false) {\r
693                                     node.errors.push(patternRestriction.info);\r
694                                 }\r
695                                 return condition;\r
696                             });\r
697                         },\r
698                         lengthRestrictions = node.getChildren('length'),\r
699                         rangeRestrictions = node.getChildren('range'),\r
700                         lengthRangeCheck = function(restrictionsContainers, value) {\r
701                             return restrictionsContainers[0].restrictions.some(function(restriction) {\r
702                                 var condition = restriction.check(value);\r
703                                 if(condition === false) {\r
704                                     node.errors.push(restriction.info);\r
705                                 }\r
706                                 return condition;\r
707                             });\r
708                         };\r
709                     \r
710                     var patternCondition = patternRestrictions.length ? patternCheck(value) : true,\r
711                         lengthCondition = lengthRestrictions.length && value.length? lengthRangeCheck(lengthRestrictions, value.length) : true,\r
712                         rangeCondition = rangeRestrictions.length ? lengthRangeCheck(rangeRestrictions, value) : true;\r
713 \r
714                     return patternCondition && lengthCondition && rangeCondition;\r
715                 };\r
716                 node.performBuildInChecks = function (value) {\r
717                     return node.builtInChecks.length ? node.builtInChecks.every(function (restriction) {\r
718                         var condition = restriction.check(value);\r
719                         if(condition === false) {\r
720                             node.errors.push(restriction.info);\r
721                         }\r
722                         return condition;\r
723                     }) : true;\r
724                 };\r
725                 node.check = function (value) {\r
726                     node.errors = [];\r
727                     var condition = value !== '' ? node.performBuildInChecks(value) && node.performRestrictionsCheck(value) : true;\r
728                     if(condition) {\r
729                         node.errors = [];\r
730                     }\r
731                     return condition;\r
732                 };\r
733                 node.getValue = function(){\r
734                     return fnToString(node.leafParent.value);\r
735                 };\r
736             },\r
737             // string: function (node) {\r
738             // },\r
739             // boolean: function (node) {\r
740             // },\r
741             empty: function (node) {\r
742                 node.setLeafValue = function (value) {\r
743                     node.leafParent.value = value === 1 ? {} : '';\r
744                 };\r
745                 \r
746                 node.clear = function () {\r
747                     node.value = null;\r
748                 };\r
749 \r
750                 node.fill = function (value) {\r
751                     node.emptyValue = value === '' ? 1 : ($.isEmptyObject(value) ? 1 : 0);\r
752                     node.leafParent.value = parseInt(node.emptyValue, 10) === 1 ? {} : '';\r
753                 };\r
754 \r
755                 node.getValue = function(){\r
756                     return parseInt(node.emptyValue, 10) === 1 ? {} : '';\r
757                 };\r
758             },\r
759             enumeration: function (node) {\r
760                 node.selEnum = null;\r
761                 \r
762                 var childNames = [];\r
763                 node.getChildren('enum').forEach(function(child) {\r
764                     childNames.push(child.label);\r
765                 });\r
766                 node.builtInChecks.push(restrictionsFact.isInArray(childNames));\r
767 \r
768                 node.setLeafValue = function (value) {\r
769                     if(value !== null) {\r
770                         node.leafParent.value = value;\r
771                     }\r
772                 };\r
773                 \r
774                 node.clear = function () {\r
775                     node.selEnum = null;\r
776                 };\r
777 \r
778                 node.fill = function (value) {\r
779                     var selChild = node.getChildren('enum', value)[0];\r
780                     node.selEnum = selChild ? selChild : null;\r
781                 };\r
782             },\r
783             bits: function (node) {\r
784                 var actBitsLen = 0,\r
785                     i;\r
786 \r
787                 node.maxBitsLen = node.getChildren('bit').length;\r
788                 node.bitsValues = [];\r
789 \r
790                 for (i = 0; i < node.maxBitsLen; i++) {\r
791                     node.bitsValues[i] = 0;\r
792                 }\r
793 \r
794                 node.clear = function () {\r
795                     for (i = 0; i < node.bitsValues.length; i++) {\r
796                         node.bitsValues[i] = 0;\r
797                     }\r
798                 };\r
799 \r
800                 node.fill = function (value) {\r
801                     var bitLabels = node.getChildren('bit').map(function(bit) {\r
802                             return bit.label;\r
803                         });\r
804                     \r
805                     node.leafParent.value.split(' ').forEach(function(val) {\r
806                         var valIndex = bitLabels.indexOf(val);\r
807                         if(valIndex !== -1) {\r
808                             node.bitsValues[valIndex] = 1;\r
809                         }\r
810                     });\r
811                 };\r
812 \r
813                 node.setLeafValue = function (values, fromFilter) {\r
814                     var bitLabels = node.getChildren('bit').map(function(bit) {\r
815                             return bit.label;\r
816                         }),\r
817                         nodeValue = null;\r
818 \r
819                     nodeValue = node.bitsValues.map(function(val, index) {\r
820                         if(parseInt(val, 10) === 1) {\r
821                             return bitLabels[index];\r
822                         } else {\r
823                             return null;\r
824                         }\r
825                     }).filter(function(val) {\r
826                         return val !== null;\r
827                     }).join(" ");\r
828 \r
829                     node.leafParent.value = nodeValue;\r
830                     if(fromFilter){\r
831                         node.leafParent.filterBitsValue = nodeValue;\r
832                     }\r
833                 };\r
834             },\r
835             // binary: function (node) {\r
836             // },\r
837             // leafref: function (node) {\r
838             // },\r
839             // identityref: function (node) {\r
840             // },\r
841             union: function (node) {\r
842                 node.clear = function () {\r
843                     node.getChildren('type').forEach(function(child) {\r
844                         child.clear();\r
845                     });\r
846                 };\r
847                 node.fill = function (value) {\r
848                     node.getChildren('type').forEach(function(child) {\r
849                         child.fill(value);\r
850                     });\r
851                 };\r
852 \r
853                 node.check = function (value) {\r
854                     var condition = false;\r
855                     node.getChildren('type').forEach(function (childType) {\r
856                         var childCondition = childType.check(value);\r
857                         condition = condition || childCondition;\r
858                     });\r
859                     return condition;\r
860                 };\r
861 \r
862                 node.getChildren('type').forEach(function (childType) {\r
863                     wrapper.wrapAll(childType);\r
864                 });\r
865             },\r
866             // 'instance-identifier': function (node) {\r
867             // },\r
868             decimal64: function (node) {\r
869                 node.builtInChecks.push(restrictionsFact.getIsDecimalFnc());\r
870             },\r
871             int8: function (node) {\r
872                 node.builtInChecks.push(restrictionsFact.getIsNumberFnc());\r
873                 node.builtInChecks.push(restrictionsFact.getMinMaxFnc(-128, 127));\r
874             },\r
875             int16: function (node) {\r
876                 node.builtInChecks.push(restrictionsFact.getIsNumberFnc());\r
877                 node.builtInChecks.push(restrictionsFact.getMinMaxFnc(-32768, 32767));\r
878             },\r
879             int32: function (node) {\r
880                 node.builtInChecks.push(restrictionsFact.getIsNumberFnc());\r
881                 node.builtInChecks.push(restrictionsFact.getMinMaxFnc(-2147483648, 2147483647));\r
882             },\r
883             int64: function (node) {\r
884                 node.builtInChecks.push(restrictionsFact.getIsNumberFnc());\r
885                 node.builtInChecks.push(restrictionsFact.getMinMaxFnc(-9223372036854775808, 9223372036854775807));\r
886             },\r
887             uint8: function (node) {\r
888                 node.builtInChecks.push(restrictionsFact.getIsUNumberFnc());\r
889                 node.builtInChecks.push(restrictionsFact.getMinMaxFnc(0, 255));\r
890             },\r
891             uint16: function (node) {\r
892                 node.builtInChecks.push(restrictionsFact.getIsUNumberFnc());\r
893                 node.builtInChecks.push(restrictionsFact.getMinMaxFnc(0, 65535));\r
894             },\r
895             uint32: function (node) {\r
896                 node.builtInChecks.push(restrictionsFact.getIsUNumberFnc());\r
897                 node.builtInChecks.push(restrictionsFact.getMinMaxFnc(0, 4294967295));\r
898             },\r
899             uint64: function (node) {\r
900                 node.builtInChecks.push(restrictionsFact.getIsUNumberFnc());\r
901                 node.builtInChecks.push(restrictionsFact.getMinMaxFnc(0, 18446744073709551615));\r
902             }\r
903         };\r
904 \r
905         wrapper.__test = {\r
906             findLeafParent: findLeafParent\r
907         };\r
908 \r
909         return wrapper;\r
910 \r
911     });\r
912 \r
913     yangUtils.factory('nodeWrapper', function (constants, $timeout, reqBuilder, restrictionsFact, typeWrapper, listFiltering, eventDispatcher) {\r
914 \r
915         var comparePropToElemByName = function comparePropToElemByName(propName, elemName) {\r
916             // AUGMENT FIX\r
917             // return propName === elemName; //TODO also check by namespace - redundancy?\r
918             \r
919             return (propName.indexOf(':') > -1 ? propName.split(':')[1] : propName) === elemName; //TODO also check by namespace - redundancy?\r
920         };\r
921 \r
922         var equalArrays = function (arrA, arrB) {\r
923             var match = (arrA.length === arrB.length) && arrA.length > 0;\r
924 \r
925             if (match) {\r
926                 var i = 0;\r
927                 while (i < arrA.length && match) {\r
928                     var valMatch = arrA[i] === arrB[i];\r
929                     match = match && valMatch;\r
930                     i++;\r
931                 }\r
932             }\r
933             return match;\r
934         };\r
935 \r
936         var equalListElems = function (listElemA, listElemB, refKey) {\r
937             var getKeyValue = function (data, label, module) {\r
938                     if (data && data.hasOwnProperty(label)) {\r
939                         return data[label];\r
940                     } else if (data && data.hasOwnProperty(module + ':' + label)) {\r
941                         return data[module + ':' + label];\r
942                     } else {\r
943                         return null;\r
944                     }\r
945                 },\r
946                 getKeyArrayValues = function (data, refKey) {\r
947                     return refKey.map(function (key) {\r
948                         return getKeyValue(data, key.label, key.module);\r
949                     }).filter(function (item) {\r
950                         return item !== null;\r
951                     });\r
952                 },\r
953                 keyValuesA = getKeyArrayValues(listElemA, refKey);\r
954                 keyValuesB = getKeyArrayValues(listElemB, refKey);\r
955 \r
956             return equalArrays(keyValuesA, keyValuesB);\r
957         };\r
958 \r
959         var checkListElemKeys = function (listData, refKey) {\r
960             var doubleKeyIndexes = [],\r
961                 checkedElems = [];\r
962 \r
963             listData.forEach(function (item, index) {\r
964                 var duplitactes = checkedElems.filter(function (checked) {\r
965                     var isDuplicate = equalListElems(item, checked.item, refKey);\r
966                     if (isDuplicate && doubleKeyIndexes.indexOf(checked.index) === -1) {\r
967                         doubleKeyIndexes.push(checked.index);\r
968                     }\r
969                     return isDuplicate;\r
970                 });\r
971 \r
972                 if (duplitactes.length) {\r
973                     //item is already in checkedElems so we don't need to push it again\r
974                     doubleKeyIndexes.push(index);\r
975                 } else {\r
976                     checkedElems.push({index: index, item: item});\r
977                 }\r
978             });\r
979 \r
980             return doubleKeyIndexes;\r
981         };\r
982 \r
983         var parseRestrictText = function (text) {\r
984             return text.split('|').map(function (elem) {\r
985                 var subElems = elem.split('..');\r
986                 return subElems.length === 1 ? restrictionsFact.getEqualsFnc(subElems[0]) :\r
987                                                restrictionsFact.getMinMaxFnc(subElems[0], subElems[1]);\r
988             });\r
989         };\r
990 \r
991 \r
992         var getTypes = function (node) {\r
993             var types = [];\r
994 \r
995             var getTypesRecursive = function (node, types) {\r
996                 types.push(node);\r
997 \r
998                 node.getChildren('type').forEach(function (child) {\r
999                     getTypesRecursive(child, types);\r
1000                 });\r
1001             };\r
1002 \r
1003             node.getChildren('type').forEach(function (child) {\r
1004                 //console.info('child', child);\r
1005                 getTypesRecursive(child, types);\r
1006             });\r
1007 \r
1008             return types;\r
1009         };\r
1010 \r
1011         var wrapper = {\r
1012             wrap: function (node) {\r
1013                 if (this.hasOwnProperty(node.type)) {\r
1014                     this[node.type](node);\r
1015                 }\r
1016             },\r
1017             wrapAll: function (node) {\r
1018                 var self = this;\r
1019                 self.wrap(node);\r
1020                 node.children.forEach(function (child) {\r
1021                     self.wrapAll(child);\r
1022                 });\r
1023             },\r
1024             checkKeyDuplicity: function (listData, refKey) {\r
1025                 return checkListElemKeys(listData, refKey);\r
1026             },\r
1027             leaf: function (node) {\r
1028                 node.value = '';\r
1029                 node.valueIsValid = true;\r
1030                 node.typeChild = node.getChildren('type')[0];\r
1031 \r
1032                 node.buildRequest = function (builder, req, module) {\r
1033                     var value = node.typeChild.getValue(),\r
1034                         labelWithModule = (module !== node.module ? node.module + ':' : '') + node.label;\r
1035 \r
1036                     if(node.isKey()) {\r
1037                         eventDispatcher.dispatch(constants.EV_FILL_PATH, node, value);\r
1038                     }\r
1039 \r
1040                     if (value) {\r
1041                         builder.insertPropertyToObj(req, labelWithModule, value);\r
1042                         return true;\r
1043                     }\r
1044 \r
1045                     return false;\r
1046                 };\r
1047 \r
1048                 node.fill = function (name, data) {\r
1049                     var match = '';\r
1050 \r
1051                     match = comparePropToElemByName(name, node.label);\r
1052                     if (match) {\r
1053                         node.value = data.toString();\r
1054                         if (node.typeChild) {\r
1055                             node.typeChild.fill(node.value);\r
1056                         }\r
1057                     }\r
1058                     return match;\r
1059                 };\r
1060 \r
1061                 node.clear = function () {\r
1062                     node.value = '';\r
1063 \r
1064                     if (node.typeChild) {\r
1065                         node.typeChild.clear();\r
1066                     }\r
1067                 };\r
1068 \r
1069                 node.isFilled = function () {\r
1070                     var filled = node.typeChild.getValue() ? true : false;\r
1071                     return filled;\r
1072                 };\r
1073 \r
1074                 node.checkValueType = function () {\r
1075                     node.valueIsValid = node.typeChild ? node.typeChild.check(node.value) : true;\r
1076                 };\r
1077 \r
1078                 node.isKey = function() {\r
1079                     return node.parent && node.parent.type === 'list' && node.parent.refKey && node.parent.refKey.indexOf(node) !== -1;\r
1080                 };\r
1081             },\r
1082             type: function (node) {\r
1083                 typeWrapper.wrapAll(node);\r
1084             },\r
1085             length: function (node) {\r
1086                 node.restrictions = parseRestrictText(node.label);\r
1087             },\r
1088             range: function (node) {\r
1089                 node.restrictions = parseRestrictText(node.label);\r
1090             },\r
1091             pattern: function (node) {\r
1092                 node.restrictions = [restrictionsFact.getReqexpValidationFnc(node.label)];\r
1093             },\r
1094             // enum: function (node) {\r
1095             // },\r
1096             // bit: function (node) {\r
1097             // },\r
1098             // position: function (node) {\r
1099             // },\r
1100             container: function (node) {\r
1101                 node.expanded = false;\r
1102 \r
1103                 node.toggleExpand = function () {\r
1104                     node.expanded = !node.expanded;\r
1105                 };\r
1106 \r
1107                 node.buildRequest = function (builder, req, module) {\r
1108                     var added = false,\r
1109                         name = node.label,\r
1110                         objToAdd = builder.createObj(),\r
1111                         builderNodes = node.getChildren(null, null, constants.NODE_UI_DISPLAY),\r
1112                         checkEmptyContainer = function(type, obj) { //TODO: absolete after when statement is implemented\r
1113                             return !!(type === 'case' || !$.isEmptyObject(objToAdd));\r
1114                         },\r
1115                         checkPresence = function(containerNode) {\r
1116                             return containerNode.children.some(function(ch) {\r
1117                                 return ch.type === 'presence';\r
1118                             });\r
1119                         },\r
1120                         labelWithModule = (module !== node.module ? node.module + ':' : '') + node.label;\r
1121 \r
1122                     if (builderNodes.length) {\r
1123                         builderNodes.forEach(function (child) {\r
1124                             var childAdded = child.buildRequest(builder, objToAdd, node.module);\r
1125                             added = added || childAdded;\r
1126                         });\r
1127                     } else  { \r
1128                         added = true;\r
1129                     }\r
1130 \r
1131 \r
1132 \r
1133                     if (added && (checkEmptyContainer(node.parent ? node.parent.type : 'blanktype', objToAdd) || checkPresence(node))) {\r
1134                         builder.insertPropertyToObj(req, labelWithModule, objToAdd);\r
1135                     }\r
1136 \r
1137                     return added;\r
1138                 };\r
1139 \r
1140                 node.fill = function (name, data) {\r
1141                     var match = comparePropToElemByName(name, node.label),\r
1142                         nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);\r
1143 \r
1144                     if (match && nodesToFill.length) {\r
1145                         nodesToFill.forEach(function (child) {\r
1146                             for (var prop in data) {\r
1147                                 child.fill(prop, data[prop]);\r
1148                             }\r
1149                         });\r
1150 \r
1151                         node.expanded = match;\r
1152                     }\r
1153 \r
1154                     return match;\r
1155                 };\r
1156 \r
1157                 node.clear = function () {\r
1158                     var nodesToClear = node.getChildren(null, null, constants.NODE_UI_DISPLAY);\r
1159                     node.nodeType = constants.NODE_UI_DISPLAY;\r
1160 \r
1161                     if (nodesToClear.length) {\r
1162                         nodesToClear.forEach(function (child) {\r
1163                             child.clear();\r
1164                         });\r
1165                     }\r
1166                 };\r
1167 \r
1168                 node.isFilled = function () {\r
1169                     return node.getChildren(null, null, constants.NODE_UI_DISPLAY).some(function (child) {\r
1170                         return child.isFilled();\r
1171                     });\r
1172                 };\r
1173             },\r
1174             rpc: function (node) {\r
1175                 node.expanded = true;\r
1176                 node.buildRequest = function (builder, req, module) {\r
1177                     var added = false,\r
1178                         name = node.label,\r
1179                         objToAdd = builder.createObj(),\r
1180                         builderNodes = node.getChildren(null, null, constants.NODE_UI_DISPLAY),\r
1181                         labelWithModule = (module !== node.module ? node.module + ':' : '') + node.label;\r
1182 \r
1183                     if (builderNodes.length) {\r
1184                         builderNodes.forEach(function (child) {\r
1185                             var childAdded = child.buildRequest(builder, objToAdd, node.module);\r
1186                             added = added || childAdded;\r
1187                         });\r
1188                     } else {\r
1189                         added = true;\r
1190                         objToAdd = constants.NULL_DATA;\r
1191                     }\r
1192 \r
1193                     if (added) {\r
1194                         builder.insertPropertyToObj(req, labelWithModule, objToAdd);\r
1195                     }\r
1196 \r
1197                     return added;\r
1198                 };\r
1199 \r
1200                 node.fill = function (name, data) {\r
1201                     var filled = false,\r
1202                         nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);\r
1203 \r
1204                     nodesToFill.forEach(function (child) {\r
1205                         var childFilled = child.fill(name, data);\r
1206                         filled = filled || childFilled;\r
1207                     });\r
1208 \r
1209                     node.expanded = filled;\r
1210 \r
1211                     return filled;\r
1212                 };\r
1213 \r
1214                 node.clear = function () {\r
1215                     var nodesToClear = node.getChildren(null, null, constants.NODE_UI_DISPLAY);\r
1216                     \r
1217                     if (nodesToClear.length) {\r
1218                         nodesToClear.forEach(function (child) {\r
1219                             child.clear();\r
1220                         });\r
1221                     }\r
1222                 };\r
1223 \r
1224                 node.isFilled = function () {\r
1225                     return node.getChildren(null, null, constants.NODE_UI_DISPLAY).some(function (child) {\r
1226                         return child.isFilled();\r
1227                     });\r
1228                 };\r
1229 \r
1230             },\r
1231             input: function (node) {\r
1232                 node.expanded = true;\r
1233 \r
1234                 node.buildRequest = function (builder, req, module) {\r
1235                     var added = false,\r
1236                         name = node.label,\r
1237                         objToAdd = builder.createObj(),\r
1238                         builderNodes = node.getChildren(null, null, constants.NODE_UI_DISPLAY),\r
1239                         labelWithModule = (module !== node.module ? node.module + ':' : '') + node.label;\r
1240 \r
1241                     if (builderNodes.length) {\r
1242 \r
1243                         builderNodes.forEach(function (child) {\r
1244                             var childAdded = child.buildRequest(builder, objToAdd, node.module);\r
1245                             added = added || childAdded;\r
1246                         });\r
1247                     } else {\r
1248                         added = true;\r
1249                     }\r
1250 \r
1251                     if (added) {\r
1252                         builder.insertPropertyToObj(req, labelWithModule, objToAdd);\r
1253                     }\r
1254 \r
1255                     return added;\r
1256                 };\r
1257 \r
1258                 node.fill = function (name, data) {\r
1259                     var match = comparePropToElemByName(name, node.label),\r
1260                         nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);\r
1261 \r
1262                     if (match && nodesToFill.length) {\r
1263                         nodesToFill.forEach(function (child) {\r
1264                             for (var prop in data) {\r
1265                                 child.fill(prop, data[prop]);\r
1266                             }\r
1267                         });\r
1268                         node.expanded = match;\r
1269                     }\r
1270 \r
1271                     return match;\r
1272                 };\r
1273 \r
1274                 node.clear = function () {\r
1275                     var nodesToClear = node.getChildren(null, null, constants.NODE_UI_DISPLAY);\r
1276                     \r
1277                     if (nodesToClear.length) {\r
1278                         nodesToClear.forEach(function (child) {\r
1279                             child.clear();\r
1280                         });\r
1281                     }\r
1282                 };\r
1283 \r
1284                 node.isFilled = function () {\r
1285                     return node.getChildren(null, null, constants.NODE_UI_DISPLAY).some(function (child) {\r
1286                         return child.isFilled();\r
1287                     });\r
1288                 };\r
1289 \r
1290             },\r
1291             output: function (node) {\r
1292                 node.expanded = true;\r
1293 \r
1294                 node.buildRequest = function (builder, req) {\r
1295                     // var added = false,\r
1296                     //     name = node.label,\r
1297                     //     objToAdd = builder.createObj(),\r
1298                     //     builderNodes = node.getChildren(null, null, constants.NODE_UI_DISPLAY);\r
1299 \r
1300                     // if (builderNodes.length) {\r
1301                     //     builderNodes.forEach(function (child) {\r
1302                     //         var childAdded = child.buildRequest(builder, objToAdd);\r
1303                     //         added = added || childAdded;\r
1304                     //     });\r
1305                     // } else {\r
1306                     //     added = true;\r
1307                     // }\r
1308 \r
1309                     // if (added) {\r
1310                     //     builder.insertPropertyToObj(req, name, objToAdd);\r
1311                     // }\r
1312 \r
1313                     // return added;\r
1314                 };\r
1315 \r
1316                 node.fill = function (name, data) {\r
1317                     var match = comparePropToElemByName(name, node.label),\r
1318                         nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);\r
1319 \r
1320                     if (match && nodesToFill.length) {\r
1321                         nodesToFill.forEach(function (child) {\r
1322                             for (var prop in data) {\r
1323                                 child.fill(prop, data[prop]);\r
1324                             }\r
1325                         });\r
1326                         node.expanded = match;\r
1327                     }\r
1328 \r
1329                     return match;\r
1330                 };\r
1331 \r
1332                 node.clear = function () {\r
1333                     var nodesToClear = node.getChildren(null, null, constants.NODE_UI_DISPLAY);\r
1334 \r
1335                     if (nodesToClear.length) {\r
1336                         nodesToClear.forEach(function (child) {\r
1337                             child.clear();\r
1338                         });\r
1339                     }\r
1340                 };\r
1341 \r
1342                 node.isFilled = function () {\r
1343                     return node.getChildren(null, null, constants.NODE_UI_DISPLAY).some(function (child) {\r
1344                         return child.isFilled();\r
1345                     });\r
1346                 };\r
1347 \r
1348             },\r
1349             case: function (node) {\r
1350 \r
1351                 node.buildRequest = function (builder, req, module) {\r
1352                     var added = false;\r
1353 \r
1354                     node.getChildren(null, null, constants.NODE_UI_DISPLAY).forEach(function (child) {\r
1355                         var childAdded = child.buildRequest(builder, req, module);\r
1356                         added = added || childAdded;\r
1357                     });\r
1358 \r
1359                     return added;\r
1360                 };\r
1361 \r
1362                 node.fill = function (name, data) {\r
1363                     var filled = false,\r
1364                         nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);\r
1365 \r
1366                     nodesToFill.forEach(function (child) {\r
1367                         var childFilled = child.fill(name, data);\r
1368                         filled = filled || childFilled;\r
1369                     });\r
1370 \r
1371                     return filled;\r
1372                 };\r
1373 \r
1374                 node.clear = function () {\r
1375                     var nodesToClear = node.getChildren(null, null, constants.NODE_UI_DISPLAY);\r
1376 \r
1377                     nodesToClear.forEach(function (child) {\r
1378                         child.clear();\r
1379                     });\r
1380                 };\r
1381 \r
1382                 node.isFilled = function () {\r
1383                     return node.getChildren(null, null, constants.NODE_UI_DISPLAY).some(function (child) {\r
1384                         return child.isFilled();\r
1385                     });\r
1386                 };\r
1387             },\r
1388             choice: function (node) {\r
1389                 node.choice = null;\r
1390                 node.expanded = true;\r
1391 \r
1392                 node.buildRequest = function (builder, req, module) {\r
1393                     var added = false;\r
1394 \r
1395                     if (node.choice) {\r
1396                         added = node.choice.buildRequest(builder, req, module);\r
1397                     }\r
1398 \r
1399                     return added;\r
1400                 };\r
1401 \r
1402                 node.fill = function (name, data) {\r
1403                     var filled = false,\r
1404                             nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);\r
1405 \r
1406                     nodesToFill.forEach(function (child) {\r
1407                         var childFilled = child.fill(name, data);\r
1408 \r
1409                         if (childFilled) {\r
1410                             node.choice = child;\r
1411                         }\r
1412 \r
1413                         filled = filled || childFilled;\r
1414                         if (filled) {\r
1415                             return false;\r
1416                         }\r
1417                     });\r
1418 \r
1419                     return filled;\r
1420                 };\r
1421 \r
1422                 node.clear = function () {\r
1423                     node.nodeType = constants.NODE_UI_DISPLAY;\r
1424 \r
1425                     if (node.choice) {\r
1426                         node.choice.clear();\r
1427                         node.choice = null;\r
1428                     }\r
1429                 };\r
1430 \r
1431                 node.isFilled = function () {\r
1432                     return node.choice !== null;\r
1433                 };\r
1434             },\r
1435             'leaf-list': function (node) {\r
1436                 node.value = [];\r
1437                 node.expanded = true;\r
1438 \r
1439                 node.toggleExpand = function () {\r
1440                     node.expanded = !node.expanded;\r
1441                 };\r
1442 \r
1443                 node.addListElem = function () {\r
1444                     var newElement = {\r
1445                         value: ''\r
1446                     };\r
1447                     node.value.push(newElement);\r
1448                 };\r
1449 \r
1450                 node.removeListElem = function (elem) {\r
1451                     node.value.splice(node.value.indexOf(elem), 1);\r
1452                 };\r
1453 \r
1454                 node.buildRequest = function (builder, req, module) {\r
1455                     var valueArray = [],\r
1456                         labelWithModule = (module !== node.module ? node.module + ':' : '') + node.label;\r
1457 \r
1458                     for (var i = 0; i < node.value.length; i++) {\r
1459                         valueArray.push(node.value[i].value);\r
1460                     }\r
1461 \r
1462                     if (valueArray.length > 0) {\r
1463                         builder.insertPropertyToObj(req, labelWithModule, valueArray);\r
1464                         return true;\r
1465                     }\r
1466 \r
1467                     return false;\r
1468 \r
1469                 };\r
1470 \r
1471 \r
1472                 node.fill = function (name, array) {\r
1473                     var match = comparePropToElemByName(name, node.label),\r
1474                             newLeafListItem;\r
1475 \r
1476                     if (match) {\r
1477 \r
1478                         for (var i = 0; i < array.length; i++) {\r
1479                             newLeafListItem = {\r
1480                                 value: array[i]\r
1481                             };\r
1482                             node.value.push(newLeafListItem);\r
1483                         }\r
1484 \r
1485                     }\r
1486                     return match;\r
1487                 };\r
1488 \r
1489                 node.clear = function () {\r
1490                     node.nodeType = constants.NODE_UI_DISPLAY;\r
1491                     node.value = [];\r
1492                 };\r
1493 \r
1494                 node.isFilled = function () {\r
1495                     return node.value.length > 0;\r
1496                 };\r
1497 \r
1498             },\r
1499             key: function (node) {\r
1500                 // do this only on list, not on listElem because deepCopy on list doesn't copy property keys to listElem => don't do this when button for add new list is clicked\r
1501                 if (node.parent.hasOwnProperty('refKey')) {\r
1502                     var keyLabels = node.label.split(' '),\r
1503                         keyNodes = node.parent.getChildren(null, null, constants.NODE_UI_DISPLAY).filter(function (child) {\r
1504                             return keyLabels.indexOf(child.label) > -1;\r
1505                         }),\r
1506                         getRefKeyArray = function(keys){\r
1507                             var refKeyArray = [];\r
1508                             keyLabels.forEach(function(keyLabel){\r
1509                                 var nk = keys.filter(function(k){\r
1510                                     return keyLabel === k.label;\r
1511                                 });\r
1512 \r
1513                                 if ( nk.length ) {\r
1514                                     refKeyArray.push(nk[0]);\r
1515                                 }\r
1516                             });\r
1517                             return refKeyArray;\r
1518                         };\r
1519 \r
1520                     node.parent.refKey = getRefKeyArray(keyNodes);\r
1521                 }\r
1522             },\r
1523             config: function (node) {\r
1524                 node.parent.isConfigStm = (node.label === 'true');\r
1525             },\r
1526             list: function (node) {\r
1527                 node.refKey = [];\r
1528                 node.doubleKeyIndexes = [];\r
1529                 node.actElemStructure = null;\r
1530                 node.actElemIndex = -1;\r
1531                 node.listData = [];\r
1532                 node.expanded = true;\r
1533                 node.filters = [];\r
1534                 node.filterNodes = [];\r
1535                 node.searchedPath = [];\r
1536                 node.referenceNode = null;\r
1537                 node.filteredListData = [];\r
1538                 node.currentFilter = 0;\r
1539 \r
1540                 node.toggleExpand = function () {\r
1541                     node.expanded = !node.expanded;\r
1542                 };\r
1543 \r
1544                 node.createStructure = function () {\r
1545                     if (node.actElemStructure === null) {\r
1546                         var copy = node.deepCopy(['augmentionGroups', 'augmentationId']);\r
1547                         wrapper._listElem(copy);\r
1548                         node.actElemStructure = copy;\r
1549                         node.actElemStructure.getActElemIndex = node.getActElemIndex;\r
1550                     }\r
1551                 };\r
1552 \r
1553                 node.getActElemIndex = function() {\r
1554                     return node.actElemIndex;\r
1555                 };\r
1556 \r
1557                 node.addListElem = function () {\r
1558                     node.createStructure();\r
1559                     var newElemData = {};\r
1560                     node.listData.push(newElemData);\r
1561                     node.changeActElementData(node.listData.length - 1,true);\r
1562                 };\r
1563 \r
1564                 node.buildActElemData = function () {\r
1565                     var list = [],\r
1566                             result;\r
1567                     if (node.actElemStructure) {\r
1568                         node.actElemStructure.listElemBuildRequest(reqBuilder, list, node.module);\r
1569                         result = list[0] ? list[0] : {};\r
1570                     }\r
1571                     return result;\r
1572                 };\r
1573 \r
1574                 node.changeActElementData = function (index,fromAdd) {\r
1575                     var storeData = node.buildActElemData();\r
1576                     node.expanded = true;\r
1577 \r
1578                     if (node.actElemIndex > -1) { //we are changing already existing data\r
1579                         if(node.filteredListData && node.filteredListData.length){\r
1580                             node.listData[node.listData.indexOf(node.filteredListData[node.actElemIndex])] = storeData;\r
1581                             node.filteredListData[node.actElemIndex] = storeData;\r
1582                             if(fromAdd){\r
1583                                listFiltering.clearFilterData(node, true, false);\r
1584                             }\r
1585                         }else{\r
1586                             node.listData[node.actElemIndex] = storeData;\r
1587                         }\r
1588                     }\r
1589                     node.actElemIndex = index;\r
1590 \r
1591                     var actData = null;\r
1592                     if(!(node.filteredListData && node.filteredListData.length)){\r
1593                         actData = node.listData[node.actElemIndex];\r
1594                     }else{\r
1595                         actData = node.listData[node.listData.indexOf(node.filteredListData[node.actElemIndex])];\r
1596                     }\r
1597 \r
1598                     node.actElemStructure.clear();\r
1599                     for (var prop in actData) {\r
1600                         node.actElemStructure.fillListElement(prop, actData[prop]);\r
1601                     }\r
1602 \r
1603                     eventDispatcher.dispatch(constants.EV_LIST_CHANGED, node.actElemStructure);\r
1604                 };\r
1605 \r
1606                 node.removeListElem = function (elemIndex,fromFilter) {\r
1607 \r
1608                     if(fromFilter){\r
1609                         elemIndex = node.listData.indexOf(node.filteredListData[elemIndex]);\r
1610                     }\r
1611 \r
1612                     node.listData.splice(elemIndex, 1);\r
1613                     node.actElemIndex = node.listData.length - 1;\r
1614 \r
1615                     if(fromFilter){\r
1616                         listFiltering.clearFilterData(node,true,false);\r
1617                     }\r
1618 \r
1619                     if (node.actElemIndex === -1) {\r
1620                         node.actElemStructure = null;\r
1621                     } else {\r
1622                         var actData = node.listData[node.actElemIndex];\r
1623 \r
1624                         node.actElemStructure.clear();\r
1625                         for (var prop in actData) {\r
1626                             node.actElemStructure.fillListElement(prop, actData[prop]);\r
1627                         }\r
1628                     }\r
1629 \r
1630                     eventDispatcher.dispatch(constants.EV_LIST_CHANGED, node.actElemStructure);\r
1631                 };\r
1632 \r
1633                 node.buildRequest = function (builder, req, module) {\r
1634                     var added = false;\r
1635                     //store entered data\r
1636                     var storeData = node.buildActElemData(),\r
1637                         labelWithModule = (module !== node.module ? node.module + ':' : '') + node.label;\r
1638 \r
1639                     if (node.actElemIndex > -1) {\r
1640                         if(node.filteredListData && node.filteredListData.length){\r
1641                             node.listData[node.listData.indexOf(node.filteredListData[node.actElemIndex])] = storeData;\r
1642                             node.filteredListData[node.actElemIndex] = storeData;\r
1643                         }else{\r
1644                             node.listData[node.actElemIndex] = storeData;\r
1645                         }\r
1646                     }\r
1647 \r
1648                     added = node.listData.filter(function (data) {\r
1649                         return $.isEmptyObject(data) === false;\r
1650                     }).length > 0;\r
1651 \r
1652                     var buildedDataCopy = node.listData.slice().map(function (item) {\r
1653                                                 var newItem = {};\r
1654                                                 for(var prop in item){\r
1655                                                     if(prop != '$$hashKey'){\r
1656                                                         newItem[prop] = item[prop];\r
1657                                                     }\r
1658                                                 }\r
1659                                                 return newItem;\r
1660                                             }).filter(function(item){\r
1661                                                 return Object.keys(item).length !== 0;\r
1662                                             });\r
1663 \r
1664                     // check of listElems keyValues duplicity\r
1665                     if(node.filteredListData && node.filteredListData.length){\r
1666                         node.doubleKeyIndexes = wrapper.checkKeyDuplicity(node.filteredListData, node.refKey);\r
1667                     }else{\r
1668                         node.doubleKeyIndexes = wrapper.checkKeyDuplicity(node.listData, node.refKey);\r
1669                     }\r
1670 \r
1671                     if (added) {\r
1672                         builder.insertPropertyToObj(req, labelWithModule, buildedDataCopy);\r
1673                     }\r
1674 \r
1675                     return added;\r
1676                 };\r
1677 \r
1678                 node.fill = function (name, array) { //data is array\r
1679 \r
1680                     var match = comparePropToElemByName(name, node.label);\r
1681 \r
1682                     if (match && array.length) {\r
1683                         node.createStructure();\r
1684                         node.listData = array.slice();\r
1685                         node.actElemIndex = node.listData.length - 1;\r
1686                         for (var prop in node.listData[node.actElemIndex]) {\r
1687                             node.actElemStructure.fillListElement(prop, node.listData[node.actElemIndex][prop]);\r
1688                         }\r
1689                     }\r
1690 \r
1691                     return (match && array.length > 0);\r
1692                 };\r
1693 \r
1694                 node.clear = function () {\r
1695                     while (node.listData.length > 0) {\r
1696                         node.listData.pop();\r
1697                     }\r
1698                     while (node.filteredListData.length > 0) {\r
1699                         node.filteredListData.pop();\r
1700                     }\r
1701 \r
1702                     node.actElemIndex = -1;\r
1703                     node.actElemStructure = null;\r
1704                     node.nodeType = constants.NODE_UI_DISPLAY;\r
1705                 };\r
1706 \r
1707                 node.isFilled = function () {\r
1708                     return node.listData.length > 0;\r
1709                 };\r
1710 \r
1711                 node.createListName = function (index) {\r
1712                     var name = '',\r
1713                         val = '';\r
1714 \r
1715                     if(node.filteredListData && node.filteredListData.length){\r
1716                         currentList = node.filteredListData;\r
1717                     }else{\r
1718                         currentList = node.listData;\r
1719                     }\r
1720 \r
1721                     if (index > -1) {\r
1722                         node.actElemStructure.refKey.forEach(function (key) {\r
1723                             var keyLabel = '';\r
1724                             if(index === node.getActElemIndex()) {\r
1725                                 val = key.value !== '' ? key.label + ':' + key.value : '';\r
1726                             } else {\r
1727                                 var prop = '';\r
1728                                 if (!($.isEmptyObject(currentList[index]))) {\r
1729                                     if(currentList[index][key.label]) {\r
1730                                         prop = key.label;\r
1731                                     } else if(currentList[index][key.module + ':' + key.label]) {\r
1732                                         prop = key.module + ':' + key.label;\r
1733                                     }\r
1734                                     val = prop ? key.label + ':' + currentList[index][prop] : prop;\r
1735                                 }\r
1736                             }\r
1737 \r
1738                             name = name ? (name + (val ? (' ' + val) : '')) : (name + (val ? (' <' + val) : ''));\r
1739                         });\r
1740                     }\r
1741 \r
1742                     if (name) {\r
1743                         name = name + '>';\r
1744                     }\r
1745 \r
1746                     return name;\r
1747                 };\r
1748 \r
1749                 node.getNewFilterElement = function (){\r
1750                     return node.getChildrenForFilter().map(function(element){\r
1751                             nodeWrapperForFilter.init(element);\r
1752                             var copy = element.deepCopyForFilter();\r
1753                             wrapper.wrapAll(copy);\r
1754                             nodeWrapperForFilter.wrapForFilter(copy);\r
1755                         return copy;\r
1756                     });\r
1757                 };\r
1758             },\r
1759             _listElem: function (node) {\r
1760                 node.refKey = [];\r
1761 \r
1762                 node.listElemBuildRequest = function (builder, req, module) {\r
1763                     var added = false,\r
1764                         objToAdd = builder.createObj();\r
1765 \r
1766                     node.getChildren(null, null, constants.NODE_UI_DISPLAY).forEach(function (child) {\r
1767                         var childAdded = child.buildRequest(builder, objToAdd, node.module);\r
1768                         added = added || childAdded;\r
1769                     });\r
1770 \r
1771                     if (added) {\r
1772                         builder.insertObjToList(req, objToAdd);\r
1773                     }\r
1774 \r
1775                     return added;\r
1776                 };\r
1777 \r
1778                 node.fillListElement = function (name, data) {\r
1779                     var filled = false;\r
1780 \r
1781                     node.getChildren(null, null, constants.NODE_UI_DISPLAY).forEach(function (child) {\r
1782                         var childFilled = child.fill(name, data);\r
1783                         filled = filled || childFilled;\r
1784                     });\r
1785 \r
1786                     return filled;\r
1787                 };\r
1788 \r
1789                 node.isFilled = function () {\r
1790                     return node.getChildren(null, null, constants.NODE_UI_DISPLAY).some(function (child) {\r
1791                         return child.isFilled();\r
1792                     });\r
1793                 };\r
1794 \r
1795                 node.clear = function () {\r
1796                     var nodesToClear = node.getChildren(null, null, constants.NODE_UI_DISPLAY);\r
1797 \r
1798                     if (nodesToClear.length) {\r
1799                         nodesToClear.forEach(function (child) {\r
1800                             child.clear();\r
1801                         });\r
1802                     }\r
1803                 };\r
1804 \r
1805                 node.children.forEach(function (child) {\r
1806                     wrapper.wrapAll(child);\r
1807                 });\r
1808             }\r
1809         };\r
1810 \r
1811         wrapper.__test = {\r
1812             comparePropToElemByName: comparePropToElemByName,\r
1813             equalArrays: equalArrays,\r
1814             equalListElems: equalListElems,\r
1815             parseRestrictText: parseRestrictText,\r
1816             getTypes: getTypes,\r
1817             checkListElemKeys: checkListElemKeys\r
1818         };\r
1819 \r
1820         return wrapper;\r
1821     });\r
1822 \r
1823     yangUtils.factory('restrictionsFact', function () {\r
1824 \r
1825         var RestrictionObject = function(fnc, info) {\r
1826             this.info = info;\r
1827             this.check = fnc;\r
1828         };\r
1829 \r
1830         var convertToInteger = function(value) {\r
1831             var strVal = typeof value === 'string' ? value : value.toString(),\r
1832                 radix = strVal.indexOf('0x') === 0 ? 16 : strVal.indexOf('0') === 0 ? 8 : 10;\r
1833 \r
1834             return parseInt(strVal, radix);\r
1835         };\r
1836 \r
1837         var restrictions = {};\r
1838 \r
1839         restrictions.getEqualsFnc = function (target) {\r
1840             var intTarget = parseInt(target);\r
1841             \r
1842             return new RestrictionObject(\r
1843                 function (value) {\r
1844                     var intVal = convertToInteger(value);\r
1845                     return intVal === intTarget;\r
1846                 },\r
1847                 'Value must be equal to '+target\r
1848             );\r
1849         };\r
1850 \r
1851         restrictions.getMinMaxFnc = function (min, max) {\r
1852             var intMin = parseInt(min),\r
1853                 intMax = parseInt(max);\r
1854             \r
1855             return new RestrictionObject(\r
1856                 function (value) {\r
1857                     var intVal = convertToInteger(value);\r
1858                     return (intMin <= intVal) && (intVal <= intMax);\r
1859                 },\r
1860                 'Value must be in between '+min+' and '+max\r
1861             );\r
1862         };\r
1863 \r
1864         restrictions.getReqexpValidationFnc = function (patternString) {\r
1865             return new RestrictionObject(\r
1866                 function (value) {\r
1867                     var pattern = new RegExp(patternString);\r
1868                     return pattern.test(value.toString());\r
1869                 },\r
1870                 'Value must match '+patternString\r
1871             );\r
1872         };\r
1873 \r
1874         restrictions.getIsNumberFnc = function () {\r
1875             return new RestrictionObject(\r
1876                 function (value) {\r
1877                     var pattern = new RegExp('^[+-]?((0x[0-9A-Fa-f]+)|(0[0-9]+)|([0-9]+))$');\r
1878                     return pattern.test(value.toString());\r
1879                 },\r
1880                 'Value must be number (+/-, 0x and 0) prefixed are permitted'\r
1881             );\r
1882         };\r
1883 \r
1884         restrictions.getIsUNumberFnc = function () {\r
1885             return new RestrictionObject(\r
1886                 function (value) {\r
1887                     var pattern = new RegExp('^[+]?((0x[0-9A-Fa-f]+)|(0[0-9]+)|([0-9]+))$');\r
1888                     return pattern.test(value.toString());\r
1889                 },\r
1890                 'Value must be positive number (+, 0x and 0) prefixed are permitted'\r
1891             );\r
1892         };\r
1893 \r
1894         restrictions.getIsDecimalFnc = function () {\r
1895             return new RestrictionObject(\r
1896                 function (value) {\r
1897                     var pattern = new RegExp("^[-]?[1-9]?[0-9]+[.|,]?[0-9]*$");\r
1898                     return pattern.test(value.toString());\r
1899                 },\r
1900                 'Value must be decimal number - prefix is permitted'\r
1901             );\r
1902         };\r
1903 \r
1904         restrictions.isInArray = function (array) {\r
1905             return new RestrictionObject(\r
1906                 function (value) {\r
1907                     return array.some(function(arrVal) {\r
1908                         return arrVal === value;\r
1909                     });\r
1910                 },\r
1911                 'Value must be in ' + array.toString()\r
1912             );\r
1913         };\r
1914 \r
1915 \r
1916         return restrictions;\r
1917     });\r
1918 \r
1919     yangUtils.factory('yinParser', ['$http','syncFact', 'constants', 'arrayUtils', 'pathUtils', 'YangUIApis', 'nodeUtils', \r
1920         function ($http, syncFact, constants, arrayUtils, pathUtils, YangUIApis, nodeUtils) {\r
1921         var augmentType = 'augment';\r
1922         var path = './assets';\r
1923 \r
1924         var Module = function (name, revision, namespace) {\r
1925             this._name = name;\r
1926             this._revision = revision;\r
1927             this._namespace = namespace;\r
1928             this._statements = {};\r
1929             this._roots = [];\r
1930             this._augments = [];\r
1931 \r
1932             this.getRoots = function () {\r
1933                 return this._roots;\r
1934             };\r
1935 \r
1936             this.getImportByPrefix = function (prefix) {\r
1937                 var importNode = null;\r
1938 \r
1939                 if (this._statements.hasOwnProperty('import')) {\r
1940                     importNode = this._statements.import.filter(function (importItem) {\r
1941                         return importItem._prefix === prefix;\r
1942                     })[0];\r
1943                 }\r
1944 \r
1945                 return importNode;\r
1946             };\r
1947 \r
1948             this.getRawAugments = function () {\r
1949                 return this._augments;\r
1950             };\r
1951 \r
1952             this.getAugments = function () {\r
1953                 var self = this;\r
1954 \r
1955                 return this.getRawAugments().map(function (augNode) {\r
1956                     var prefixConverter = function (prefix) {\r
1957                             var importNode = self.getImportByPrefix(prefix);\r
1958                             return importNode ? importNode.label : null;\r
1959                         },\r
1960                         getDefaultModule = function() {\r
1961                             return null;\r
1962                         };\r
1963 \r
1964                     augNode.path = pathUtils.translate(augNode.pathString, prefixConverter, self._statements.import, getDefaultModule);\r
1965 \r
1966                     return new Augmentation(augNode);\r
1967                 });\r
1968             };\r
1969 \r
1970             this.addChild = function (node) {\r
1971                 if (!this._statements.hasOwnProperty(node.type)) {\r
1972                     this._statements[node.type] = [];\r
1973                 }\r
1974 \r
1975                 var duplicates = this._statements[node.type].filter(function (item) {\r
1976                     return node.label === item.label && node.nodeType === item.nodeType;\r
1977                 });\r
1978 \r
1979                 if (duplicates && duplicates.length > 0) {\r
1980                     console.warn('trying to add duplicate node', node, 'to module', this._statements);\r
1981                 } else {\r
1982                     this._statements[node.type].push(node);\r
1983 \r
1984                     if (nodeUtils.isRootNode(node.type)) {\r
1985                         this._roots.push(node);\r
1986                     }\r
1987 \r
1988                     if (node.type === 'augment') {\r
1989                         this._augments.push(node);\r
1990                     }\r
1991                 }\r
1992             };\r
1993 \r
1994             this.searchNode = function (type, name) {\r
1995                 var searchResults = null,\r
1996                         searchedNode = null;\r
1997 \r
1998                 if (this._statements[type]) {\r
1999                     searchResults = this._statements[type].filter(function (node) {\r
2000                         return name === node.label;\r
2001                     });\r
2002                 }\r
2003 \r
2004                 if (searchResults && searchResults.length === 0) {\r
2005                     //console.warn('no nodes with type', type, 'and name', name, 'found in', this);\r
2006                 } else if (searchResults && searchResults.length > 1) {\r
2007                     //console.warn('multiple nodes with type', type, 'and name', name, 'found in', this);\r
2008                 } else if (searchResults && searchResults.length === 1) {\r
2009                     searchedNode = searchResults[0];\r
2010                 }\r
2011 \r
2012                 return searchedNode;\r
2013             };\r
2014         };\r
2015 \r
2016         var Node = function (id, name, type, module, namespace, parent, nodeType, moduleRevision) {\r
2017             this.id = id;\r
2018             this.label = name;\r
2019             this.localeLabel = constants.LOCALE_PREFIX + name.toUpperCase();\r
2020             this.type = type;\r
2021             this.module = module;\r
2022             this.children = [];\r
2023             this.parent = parent;\r
2024             this.nodeType = nodeType;\r
2025             this.namespace = namespace;\r
2026             this.moduleRevision = moduleRevision;\r
2027 \r
2028             this.appendTo = function (parentNode) {\r
2029                 parentNode.addChild(this);\r
2030             };\r
2031 \r
2032             this.addChild = function (node) {\r
2033                 if (this.children.indexOf(node) === -1) {\r
2034                     this.children.push(node);\r
2035                     node.parent = this;\r
2036                 }\r
2037                 \r
2038             };\r
2039 \r
2040             this.deepCopy = function deepCopy(additionalProperties) {\r
2041                 var copy = new Node(this.id, this.label, this.type, this.module, this.namespace, null, this.nodeType, this.moduleRevision),\r
2042                     self = this;\r
2043 \r
2044                 additionalProperties = (additionalProperties || []).concat(['pathString']);\r
2045 \r
2046                 additionalProperties.forEach(function(prop) {\r
2047                     if (prop !== 'children' && self.hasOwnProperty(prop) && copy.hasOwnProperty(prop) === false) {\r
2048                         copy[prop] = self[prop];\r
2049                     }\r
2050                 });\r
2051 \r
2052                 this.children.forEach(function (child) {\r
2053                     var childCopy = child.deepCopy(additionalProperties);\r
2054                     childCopy.parent = copy;\r
2055                     copy.children.push(childCopy);\r
2056                 });\r
2057                 return copy;\r
2058             };\r
2059 \r
2060             this.getCleanCopy = function(){\r
2061                 return new Node(this.id, this.label, this.type, this.module, this.namespace, null, this.nodeType, this.moduleRevision);\r
2062             };\r
2063 \r
2064             this.getChildren = function (type, name, nodeType, property) {\r
2065                 var filteredChildren = this.children.filter(function (item) {\r
2066                     return (name != null ? name === item.label : true) && (type != null ? type === item.type : true) && (nodeType != null ? nodeType === item.nodeType : true);\r
2067                 });\r
2068 \r
2069                 if (property) {\r
2070                     return filteredChildren.filter(function (item) {\r
2071                         return item.hasOwnProperty(property);\r
2072                     }).map(function (item) {\r
2073                         return item[property];\r
2074                     });\r
2075                 } else {\r
2076                     return filteredChildren;\r
2077                 }\r
2078             };\r
2079 \r
2080         };\r
2081 \r
2082 \r
2083 \r
2084         var AugmentationsGroup = function(){\r
2085             this.obj = {};\r
2086 \r
2087             this.addAugumentation = function(augumentation){\r
2088                 this.obj[augumentation.id] = augumentation;\r
2089             };\r
2090         };\r
2091 \r
2092         var Augmentations = function(){\r
2093             this.groups = {};\r
2094 \r
2095             this.addGroup  = function(groupId){\r
2096                 this.groups[groupId] = !this.groups.hasOwnProperty(groupId) ? new AugmentationsGroup() : this.groups[groupId];\r
2097             };\r
2098 \r
2099             this.getAugmentation = function(node, augId) {\r
2100                 return this.groups[node.module + ':' + node.label] ? this.groups[node.module + ':' + node.label].obj[augId] : null;\r
2101             };\r
2102         };\r
2103 \r
2104         var Augmentation = function (node) {\r
2105             var self = this;\r
2106             this.node = node;\r
2107             this.path = (node.path ? node.path : []);\r
2108             this.id = node.module + ':' + node.label;\r
2109             this.expanded = true;\r
2110             // AUGMENT FIX\r
2111             //node.label = node.module + ':' + node.label;\r
2112 \r
2113 \r
2114             this.toggleExpand = function () {\r
2115                 this.expanded = !this.expanded;\r
2116             };\r
2117 \r
2118             this.setAugmentationGroup = function(targetNode, augumentations){\r
2119                 var targetNodeId = targetNode.module + ':' + targetNode.label;\r
2120                 targetNode.augmentionGroups = targetNode.augmentionGroups ? targetNode.augmentionGroups : [];\r
2121                 targetNode.augmentionGroups.push(self.id);\r
2122 \r
2123                 augumentations.addGroup(targetNodeId);\r
2124                 augumentations.groups[targetNodeId].addAugumentation(self);\r
2125             };\r
2126 \r
2127             this.apply = function (nodeList, augumentations) {\r
2128                 var targetNode = this.getTargetNodeToAugment(nodeList);\r
2129 \r
2130                 if (targetNode) {\r
2131                     this.setAugmentationGroup(targetNode, augumentations);\r
2132 \r
2133                     this.node.children.forEach(function (child) {\r
2134                         child.appendTo(targetNode);\r
2135                         child.augmentationId = self.id;\r
2136                         // AUGMENT FIX\r
2137                         // child.children.forEach(function (moduleChild) {\r
2138                         //     moduleChild.label = moduleChild.module + ':' + moduleChild.label;\r
2139                         // });\r
2140                     });\r
2141                 } else {\r
2142                     console.warn('can\'t find target node for augmentation ', this.getPathString());\r
2143                 }\r
2144             };\r
2145 \r
2146             this.getTargetNodeToAugment = function (nodeList) {\r
2147                 return pathUtils.search({children: nodeList}, this.path.slice());\r
2148             };\r
2149 \r
2150             this.getPathString = function () {\r
2151                 return this.path.map(function (elem) {\r
2152                     return elem.module + ':' + elem.name;\r
2153                 }).join('/');\r
2154             };\r
2155 \r
2156         };\r
2157 \r
2158         var parentTag = function (xml) {\r
2159             if (xml.get(0).tagName.toLowerCase() === 'module') {\r
2160                 return xml.get(0);\r
2161             } else {\r
2162                 return parentTag(xml.parent());\r
2163             }\r
2164         };\r
2165 \r
2166         var parseModule = function(data, callback) {\r
2167             var yangParser = new YangParser();\r
2168 \r
2169             var moduleName = $($.parseXML(data).documentElement).attr('name'),\r
2170                 moduleNamespace = $($.parseXML(data)).find('namespace').attr('uri'),\r
2171                 moduleoduleRevision = $($.parseXML(data)).find('revision').attr('date'),\r
2172                 moduleObj = new Module(moduleName, moduleoduleRevision, moduleNamespace);\r
2173 \r
2174             yangParser.setCurrentModuleObj(moduleObj);\r
2175             yangParser.parse($.parseXML(data).documentElement, moduleObj);\r
2176 \r
2177             yangParser.sync.waitFor(function () {\r
2178                 callback(moduleObj);\r
2179             });\r
2180         };\r
2181 \r
2182         var loadStaticModule = function(name, callback, errorCbk) {\r
2183             var yinPath = '/yang2xml/' + name + '.yang.xml';\r
2184             $http.get(path + yinPath).success(function(data) {\r
2185                     console.warn('cannot load '+ name + 'from controller, trying loading from static storage');\r
2186                     parseModule(data, callback);\r
2187             }).error(function() {\r
2188                 console.warn('cannot load file '+ yinPath + 'from static storage');\r
2189                 errorCbk();\r
2190                 return null;\r
2191             });\r
2192         };\r
2193 \r
2194         var parseYangMP = function parseYangMP(baseApiPath, name, rev, callback, errorCbk) {\r
2195             var path = baseApiPath + '/' + name + '/' + rev + '/schema';\r
2196 \r
2197             YangUIApis.getSingleModuleInfo(path).then(\r
2198                 function (data) {\r
2199                     if($.parseXML(data) !== null) {\r
2200                         parseModule(data, callback);\r
2201                     } else {\r
2202                         loadStaticModule(name, callback, errorCbk);\r
2203                     }\r
2204                 }, function () {\r
2205                     loadStaticModule(name, callback, errorCbk);\r
2206                 }\r
2207             );\r
2208         };\r
2209 \r
2210         var parseYang = function parseYang(name, rev, callback, errorCbk) {\r
2211             YangUIApis.getModuleSchema(name, rev).get().then(\r
2212                 function (data) {\r
2213                     if($.parseXML(data) !== null) {\r
2214                         parseModule(data, callback);\r
2215                     } else {\r
2216                         loadStaticModule(name, callback, errorCbk);\r
2217                     }\r
2218                 }, function () {\r
2219                     loadStaticModule(name, callback, errorCbk);\r
2220                 }\r
2221             );\r
2222         };\r
2223 \r
2224         var YangParser = function () {\r
2225             this.rootNodes = [];\r
2226             this.nodeIndex = 0;\r
2227             this.sync = syncFact.generateObj();\r
2228             this.moduleObj = null;\r
2229 \r
2230             this.setCurrentModuleObj = function (moduleObj) {\r
2231                 this.moduleObj = moduleObj;\r
2232             };\r
2233 \r
2234             this.createNewNode = function (name, type, parentNode, nodeType) {\r
2235                 var node = new Node(this.nodeIndex++, name, type, this.moduleObj._name, this.moduleObj._namespace, parentNode, nodeType, this.moduleObj._revision);\r
2236 \r
2237                 if (parentNode) {\r
2238                     parentNode.addChild(node);\r
2239                 }\r
2240 \r
2241                 return node;\r
2242             };\r
2243 \r
2244             this.parse = function (xml, parent) {\r
2245                 var self = this;\r
2246 \r
2247                 $(xml).children().each(function (_, item) {\r
2248                     var prop = item.tagName.toLowerCase();\r
2249                     if (self.hasOwnProperty(prop)) {\r
2250                         self[prop](item, parent);\r
2251                     } else {\r
2252                         // self.parse(this, parent);\r
2253                     }\r
2254                 });\r
2255             };\r
2256 \r
2257             this.config = function(xml, parent) {\r
2258                 var type = 'config',\r
2259                     name = $(xml).attr('value'),\r
2260                     nodeType = constants.NODE_ALTER,\r
2261                     node = this.createNewNode(name, type, parent, nodeType);\r
2262             };\r
2263 \r
2264             this.presence = function(xml, parent) {\r
2265                 var type = 'presence',\r
2266                     name = $(xml).attr('value'),\r
2267                     nodeType = constants.NODE_ALTER,\r
2268                     node = this.createNewNode(name, type, parent, nodeType);\r
2269             };\r
2270 \r
2271             this.leaf = function (xml, parent) {\r
2272                 var type = 'leaf',\r
2273                     name = $(xml).attr('name'),\r
2274                     nodeType = constants.NODE_UI_DISPLAY,\r
2275                     node = this.createNewNode(name, type, parent, nodeType);\r
2276 \r
2277                 this.parse(xml, node);\r
2278             };\r
2279 \r
2280             this['leaf-list'] = function (xml, parent) {\r
2281                 var type = 'leaf-list',\r
2282                     name = $(xml).attr('name'),\r
2283                     nodeType = constants.NODE_UI_DISPLAY,\r
2284                     node = this.createNewNode(name, type, parent, nodeType);\r
2285 \r
2286                 this.parse(xml, node);\r
2287             };\r
2288 \r
2289             this.container = function (xml, parent) {\r
2290                 var type = 'container',\r
2291                     name = $(xml).attr('name'),\r
2292                     nodeType = constants.NODE_UI_DISPLAY,\r
2293                     node = this.createNewNode(name, type, parent, nodeType);\r
2294 \r
2295                 this.parse(xml, node);\r
2296             };\r
2297 \r
2298             this.choice = function (xml, parent) {\r
2299                 var type = 'choice',\r
2300                     name = $(xml).attr('name'),\r
2301                     nodeType = constants.NODE_UI_DISPLAY,\r
2302                     node = this.createNewNode(name, type, parent, nodeType);\r
2303 \r
2304                 this.parse(xml, node);\r
2305             };\r
2306 \r
2307             this.case = function (xml, parent) {\r
2308                 var type = 'case',\r
2309                     name = $(xml).attr('name'),\r
2310                     nodeType = constants.NODE_UI_DISPLAY,\r
2311                     node = this.createNewNode(name, type, parent, nodeType);\r
2312 \r
2313                 this.parse(xml, node);\r
2314             };\r
2315 \r
2316             this.list = function (xml, parent) {\r
2317                 var type = 'list',\r
2318                     name = $(xml).attr('name'),\r
2319                     nodeType = constants.NODE_UI_DISPLAY,\r
2320                     node = this.createNewNode(name, type, parent, nodeType);\r
2321 \r
2322                 this.parse(xml, node);\r
2323             };\r
2324 \r
2325 \r
2326             this.key = function (xml, parent) {\r
2327                 var type = 'key',\r
2328                     name = $(xml).attr('value'),\r
2329                     nodeType = constants.NODE_ALTER,\r
2330                     node = this.createNewNode(name, type, parent, nodeType);\r
2331 \r
2332                 this.parse(xml, node);\r
2333             };\r
2334 \r
2335             this.description = function (xml, parent) {\r
2336                 var type = 'description',\r
2337                     name = $(xml).attr('text') ? $(xml).attr('text') : $(xml).children('text:first').text(),\r
2338                     nodeType = constants.NODE_ALTER,\r
2339                     node = this.createNewNode(name, type, parent, nodeType);\r
2340 \r
2341                 this.parse(xml, node);\r
2342             };\r
2343 \r
2344             this.typedef = function (xml, parent, typedefName) {\r
2345                 var type = 'typedef',\r
2346                     name = $(xml).attr('name'),\r
2347                     nodeType = constants.NODE_LINK_TARGET,\r
2348                     node = this.createNewNode(name, type, parent, nodeType);\r
2349 \r
2350                 this.parse(xml, node);\r
2351             };\r
2352 \r
2353             this.grouping = function (xml, parent, groupingName) {\r
2354                 var type = 'grouping',\r
2355                     name = $(xml).attr('name'),\r
2356                     nodeType = constants.NODE_LINK_TARGET,\r
2357                     node = this.createNewNode(name, type, parent, nodeType);\r
2358 \r
2359                 this.parse(xml, node);\r
2360             };\r
2361 \r
2362             this.uses = function (xml, parent) {\r
2363                 var type = 'uses',\r
2364                     name = $(xml).attr('name'),\r
2365                     nodeType = constants.NODE_LINK,\r
2366                     node = this.createNewNode(name, type, parent, nodeType);\r
2367 \r
2368                 this.parse(xml, node);\r
2369             };\r
2370 \r
2371             this.import = function (xml, parent) {\r
2372                 var type = 'import',\r
2373                     name = $(xml).attr('module'),\r
2374                     nodeType = constants.NODE_ALTER,\r
2375                     node = this.createNewNode(name, type, parent, nodeType);\r
2376 \r
2377                 node._prefix = $(xml).children('prefix:first').attr('value');\r
2378                 node._revisionDate = $(xml).children('revision-date:first').attr('date');\r
2379             };\r
2380 \r
2381             this.augment = function (xml, parent) {\r
2382                 var type = augmentType,\r
2383                     nodeType = constants.NODE_ALTER,\r
2384                     augmentIndentifier = $(xml).children("ext\\:augment-identifier:first").attr("ext:identifier"),\r
2385                     name = augmentIndentifier ? augmentIndentifier : 'augment' + (this.nodeIndex + 1).toString(),\r
2386                     pathString = $(xml).attr('target-node'),\r
2387                     augmentRoot = this.createNewNode(name, type, parent, nodeType);\r
2388 \r
2389                 augmentRoot.pathString = pathString;\r
2390                 this.parse(xml, augmentRoot);\r
2391             };\r
2392 \r
2393 \r
2394             this.rpc = function (xml, parent) {\r
2395                 var type = 'rpc',\r
2396                     name = $(xml).attr('name'),\r
2397                     nodeType = constants.NODE_UI_DISPLAY,\r
2398                     node = this.createNewNode(name, type, parent, nodeType);\r
2399 \r
2400                 this.parse(xml, node);\r
2401             };\r
2402 \r
2403             this.input = function (xml, parent) {\r
2404                 var type = 'input',\r
2405                     name = 'input',\r
2406                     nodeType = constants.NODE_UI_DISPLAY,\r
2407                     node = this.createNewNode(name, type, parent, nodeType);\r
2408 \r
2409                 this.parse(xml, node);\r
2410             };\r
2411 \r
2412             this.output = function (xml, parent) {\r
2413                 var type = 'output',\r
2414                     name = 'output',\r
2415                     nodeType = constants.NODE_UI_DISPLAY,\r
2416                     node = this.createNewNode(name, type, parent, nodeType);\r
2417 \r
2418                 this.parse(xml, node);\r
2419             };\r
2420 \r
2421             this.pattern = function (xml, parent) {\r
2422                 var type = 'pattern',\r
2423                     name = $(xml).attr('value'),\r
2424                     nodeType = constants.NODE_RESTRICTIONS;\r
2425 \r
2426                 this.createNewNode(name, type, parent, nodeType);\r
2427             };\r
2428 \r
2429             this.range = function (xml, parent) {\r
2430                 var type = 'range',\r
2431                     name = $(xml).attr('value'),\r
2432                     nodeType = constants.NODE_RESTRICTIONS;\r
2433 \r
2434                 this.createNewNode(name, type, parent, nodeType);\r
2435             };\r
2436 \r
2437             this.length = function (xml, parent) {\r
2438                 var type = 'length',\r
2439                     name = $(xml).attr('value'),\r
2440                     nodeType = constants.NODE_RESTRICTIONS;\r
2441 \r
2442                 this.createNewNode(name, type, parent, nodeType);\r
2443             };\r
2444 \r
2445             this.enum = function (xml, parent) {\r
2446                 var type = 'enum',\r
2447                     name = $(xml).attr('name'),\r
2448                     nodeType = constants.NODE_ALTER;\r
2449 \r
2450                 this.createNewNode(name, type, parent, nodeType);\r
2451             };\r
2452 \r
2453             this.bit = function (xml, parent) {\r
2454                 var type = 'bit',\r
2455                     name = $(xml).attr('name'),\r
2456                     nodeType = constants.NODE_ALTER,\r
2457                     node = this.createNewNode(name, type, parent, nodeType);\r
2458 \r
2459                 this.parse(xml, node);\r
2460             };\r
2461 \r
2462             this.position = function (xml, parent) {\r
2463                 var type = 'position',\r
2464                     name = $(xml).attr('value'),\r
2465                     nodeType = constants.NODE_ALTER;\r
2466 \r
2467                 this.createNewNode(name, type, parent, nodeType);\r
2468             };\r
2469 \r
2470             this.type = function (xml, parent) {\r
2471                 var type = 'type',\r
2472                     name = $(xml).attr('name'),\r
2473                     nodeType = constants.NODE_ALTER,\r
2474                     node = this.createNewNode(name, type, parent, nodeType);\r
2475 \r
2476                 this.parse(xml, node);\r
2477             };\r
2478         };\r
2479 \r
2480         return {\r
2481             parseYang: parseYang,\r
2482             parseYangMP: parseYangMP,\r
2483             yangParser: new YangParser(),\r
2484             Augmentations: Augmentations,\r
2485             Module: Module,\r
2486             __test: {\r
2487                 path: path,\r
2488                 parentTag: parentTag,\r
2489                 yangParser: new YangParser(),\r
2490                 Augmentation: Augmentation,\r
2491                 Module: Module\r
2492             }\r
2493         };\r
2494     }]);\r
2495 \r
2496     yangUtils.factory('apiBuilder', function (arrayUtils, pathUtils, nodeUtils, YangUtilsRestangular) {\r
2497 \r
2498         var ab = {};\r
2499 \r
2500         var Api = function(basePath, module, revision, subApis) {\r
2501             this.basePath = basePath;\r
2502             this.module = module;\r
2503             this.revision = revision;\r
2504             this.subApis = subApis || [];\r
2505 \r
2506             this.addSubApis = function(subApis) {\r
2507                 var self = this;\r
2508                 subApis.forEach(function(sa) {\r
2509                     sa.parent = self;\r
2510                     self.subApis.push(sa);\r
2511                 });\r
2512             };\r
2513         };\r
2514 \r
2515         var SubApi = function (pathTemplateString, operations, node, storage, parent) {\r
2516             this.node = node;\r
2517             this.pathTemplateString = pathTemplateString;\r
2518             this.operations = operations;\r
2519             this.storage = storage;\r
2520             this.custFunct = [];\r
2521             this.parent = parent ? parent : null;\r
2522 \r
2523             this.pathArray = (function(st, path) {\r
2524                 var pathString = (st ? st + '/' : '') + path;\r
2525                 return pathUtils.translate(pathString);\r
2526             }) (this.storage, this.pathTemplateString);\r
2527 \r
2528             this.equals = function(pathArray, compareIdentifierValues) {\r
2529                 return this.pathArray.every(function(pa, i) {\r
2530                     pa.equals(pathArray[i], compareIdentifierValues);\r
2531                 });\r
2532             };\r
2533 \r
2534             this.buildApiRequestString = function () {\r
2535                 return pathUtils.translatePathArray(this.pathArray).join('/');\r
2536             };\r
2537 \r
2538             this.addCustomFunctionality = function (label, callback, viewStr, hideButtonOnSelect) {\r
2539                 var funct = custFunct.createNewFunctionality(label, this.node, callback, viewStr, hideButtonOnSelect);\r
2540 \r
2541                 if (funct) {\r
2542                     this.custFunct.push(funct);\r
2543                 }\r
2544             };\r
2545 \r
2546             this.clone = function(options) {\r
2547                 var getOption = function(optName) {\r
2548                         var res = null;\r
2549                         if(options) {\r
2550                             res = options[optName] || null;\r
2551                         }\r
2552                         return  res;\r
2553                     },\r
2554                     clone = new SubApi(getOption('pathTemplateString') || this.pathTemplateString, \r
2555                                        getOption('operations') || this.operations, \r
2556                                        getOption('withoutNode') ? null : this.node, \r
2557                                        getOption('storage') || this.storage, \r
2558                                        getOption('parent') || this.parent);\r
2559 \r
2560                 if(getOption('clonePathArray')) {\r
2561                     clone.pathArray = this.pathArray.map(function(pe) {\r
2562                         return pe.clone();\r
2563                     });\r
2564                 }\r
2565                 \r
2566                 return clone;\r
2567             };\r
2568         };\r
2569 \r
2570         var removeDuplicatedApis = function(apis) {\r
2571             var toRemove = [],\r
2572                 sortApisByRevision = function(a, b) {\r
2573                     var dateA = new Date(a.revision+'Z'),\r
2574                         dateB = new Date(b.revision+'Z');\r
2575 \r
2576                     return dateB - dateA;\r
2577                 };\r
2578 \r
2579             apis.forEach(function(a) {\r
2580                 if(toRemove.indexOf(a) === -1) {\r
2581                     var sortedApis = apis.filter(function(af) {\r
2582                         return a.module === af.module;\r
2583                     }).sort(sortApisByRevision);\r
2584 \r
2585                     toRemove = toRemove.concat(sortedApis.slice(1));\r
2586                 }\r
2587             });\r
2588 \r
2589             toRemove.forEach(function(a) {\r
2590                 apis.splice(apis.indexOf(a), 1);\r
2591             });\r
2592 \r
2593             return apis;\r
2594         };\r
2595 \r
2596         var isConfigNode = function(node) {\r
2597             var result = false;\r
2598 \r
2599             if(node.hasOwnProperty('isConfigStm')) {\r
2600                 result = node.isConfigStm;\r
2601             } else if(node.parent) {\r
2602                 result = isConfigNode(node.parent);\r
2603             }\r
2604 \r
2605             return result;\r
2606         };\r
2607 \r
2608         var addNodePathStr = function(node) {\r
2609             return (!node.parent || (node.parent.module !== node.module) ? node.module + ':' : '') + node.label;\r
2610         };\r
2611 \r
2612         var getBasePath = function() {\r
2613             return YangUtilsRestangular.configuration.baseUrl + '/restconf/';\r
2614         };\r
2615 \r
2616         var getApiByModuleRevision = function(apis, module, revision) {\r
2617             return apis.filter(function(a) {\r
2618                 return a.module === module && a.revision === revision;\r
2619             })[0];\r
2620         };\r
2621 \r
2622         var getKeyIndentifiers = function(keys) {\r
2623             return keys.map(function (k) {\r
2624                 return '{' + k.label + '}';\r
2625             });\r
2626         };\r
2627 \r
2628         var getStoragesByNodeType = function(node) {\r
2629             var storages = [];\r
2630             if(nodeUtils.isRootNode(node.type)) {\r
2631                 if(node.type === 'rpc') {\r
2632                     storages.push('operations');\r
2633                 } else {\r
2634                     storages.push('operational');\r
2635                     if(isConfigNode(node)) {\r
2636                         storages.push('config');\r
2637                     }\r
2638                 }\r
2639             }\r
2640 \r
2641             return storages;\r
2642         };\r
2643 \r
2644         var getOperationsByStorage = function(storage) {\r
2645             var operations =  [];\r
2646             if(storageOperations.hasOwnProperty(storage)) {\r
2647                 operations = storageOperations[storage];\r
2648             }\r
2649 \r
2650             return operations;\r
2651         };\r
2652 \r
2653         storageOperations = {};\r
2654 \r
2655         storageOperations.config = ['GET', 'PUT', 'POST', 'DELETE'];\r
2656         storageOperations.operational = ['GET'];\r
2657         storageOperations.operations = ['POST'];\r
2658 \r
2659         var nodePathStringCreator = {};\r
2660 \r
2661         nodePathStringCreator.list = function(node, pathstr) {\r
2662             return pathstr + addNodePathStr(node) + '/' + (node.refKey.length ? (getKeyIndentifiers(node.refKey).join('/') + '/') : '');\r
2663         };\r
2664 \r
2665         nodePathStringCreator.container = function(node, pathstr) {\r
2666             return pathstr + addNodePathStr(node) + '/';\r
2667         };\r
2668 \r
2669         nodePathStringCreator.rpc = function(node, pathstr) {\r
2670             return pathstr + addNodePathStr(node) + '/';\r
2671         };\r
2672 \r
2673         var createSubApis = function(node, pathstr) {\r
2674             var storages = getStoragesByNodeType(node);\r
2675 \r
2676             return storages.map(function(storage) {\r
2677                 var subApi = new SubApi(pathstr, getOperationsByStorage(storage), node, storage);\r
2678                 return subApi;\r
2679             });\r
2680         };\r
2681 \r
2682         var nodeChildrenProcessor = function(node, pathstr, subApis) {\r
2683             if(nodeUtils.isRootNode(node.type) && nodePathStringCreator.hasOwnProperty(node.type)) {\r
2684                 var templateStr = nodePathStringCreator[node.type](node, pathstr),\r
2685                     newSubApis = createSubApis(node, templateStr);\r
2686 \r
2687                 arrayUtils.pushElementsToList(subApis, newSubApis);\r
2688 \r
2689                 node.children.forEach(function(ch) {\r
2690                     nodeChildrenProcessor(ch, templateStr, subApis);\r
2691                 });\r
2692             }\r
2693         };\r
2694 \r
2695         //utility function\r
2696         printApis = function(apis) {\r
2697             var co = '';\r
2698             apis.forEach(function(a) {\r
2699                 a.subApis.forEach(function(sa) {\r
2700                     co += (sa.storage + '/' + sa.pathTemplateString + '\n');\r
2701                 });\r
2702             });\r
2703 \r
2704             // console.info(co);\r
2705         };\r
2706 \r
2707         ab.processAllRootNodes = function(nodes) {\r
2708             var apis = [];\r
2709 \r
2710             nodes.forEach(function(node) {\r
2711                 var api = getApiByModuleRevision(apis, node.module, node.moduleRevision),\r
2712                     newApi = false;\r
2713 \r
2714                 if(!api) {\r
2715                     api = new Api(getBasePath(), node.module, node.moduleRevision);\r
2716                     newApi = true;\r
2717                 }\r
2718 \r
2719                 api.addSubApis(ab.processSingleRootNode(node));\r
2720 \r
2721                 if(newApi) {\r
2722                     apis.push(api);\r
2723                 }\r
2724             });\r
2725 \r
2726             apis = removeDuplicatedApis(apis);\r
2727 \r
2728             printApis(apis);\r
2729 \r
2730             return apis;\r
2731         };\r
2732 \r
2733         ab.processSingleRootNode = function(node) {\r
2734             var templateStr = nodePathStringCreator[node.type](node, ''),\r
2735                 subApis = createSubApis(node, templateStr);\r
2736 \r
2737             node.children.forEach(function(ch) {\r
2738                 nodeChildrenProcessor(ch, templateStr, subApis);\r
2739             });\r
2740 \r
2741             return subApis;\r
2742         };\r
2743 \r
2744         ab.Api = Api;\r
2745         ab.SubApi = SubApi;\r
2746 \r
2747         return ab;\r
2748     });\r
2749 \r
2750     yangUtils.factory('moduleConnector', function (constants) {\r
2751 \r
2752         var isBuildInType = function (type) {\r
2753             return ['int8', 'int16', 'int32', 'int64', 'uint8', 'uint16', 'uint32', 'uint64',\r
2754                     'decimal64', 'string', 'boolean', 'enumeration', 'bits', 'binary',\r
2755                     'leafref', 'identityref', 'empty', 'union', 'instance-identifier'].indexOf(type) > -1;\r
2756         };\r
2757 \r
2758         moduleConnector = {};\r
2759 \r
2760         var linkFunctions = {};\r
2761         linkFunctions.uses = function (usesNode, currentModule) {\r
2762             var targetType = 'grouping';\r
2763             return function (modules) {\r
2764                 var data = findLinkedStatement(usesNode, targetType, currentModule, modules),\r
2765                     node = data.node,\r
2766                     module = data.module,\r
2767                     changed = false;\r
2768 \r
2769                 if (node && module) {\r
2770                     usesNode.parent.children.splice(usesNode.parent.children.indexOf(usesNode), 1); //delete uses node\r
2771                     for (var i = 0; i < node.children.length; i++) {\r
2772                         applyLinks(node.children[i], module, modules);\r
2773                     }\r
2774                     appendChildren(usesNode.parent, node);\r
2775                     changed = true;\r
2776                 }\r
2777 \r
2778                 return changed;\r
2779             };\r
2780         };\r
2781 \r
2782         linkFunctions.type = function (typeNode, currentModule) {\r
2783             var targetType = 'typedef';\r
2784 \r
2785             if (isBuildInType(typeNode.label) === false) {\r
2786                 return function (modules) {\r
2787                     var data = findLinkedStatement(typeNode, targetType, currentModule, modules),\r
2788                         node = data.node ? data.node.getChildren('type')[0] : null,\r
2789                         changed = false;\r
2790 \r
2791                     if (node) {\r
2792                         typeNode.parent.children.splice(typeNode.parent.children.indexOf(typeNode), 1); //delete referencing type node\r
2793                         typeNode.parent.addChild(node);\r
2794                         changed = true;\r
2795                     }\r
2796 \r
2797                     return changed;\r
2798                 };\r
2799             } else {\r
2800                 return function (modules) {\r
2801                     return false;\r
2802                 };\r
2803             }\r
2804         };\r
2805 \r
2806         findLinkedStatement = function (node, targetType, currentModule, modules) {\r
2807             var sourceNode,\r
2808                 sourceModule,\r
2809                 link = node.label;\r
2810 \r
2811             if (link.indexOf(':') > -1) {\r
2812                 var parts = link.split(':'),\r
2813                     targetImport = currentModule.getImportByPrefix(parts[0]);\r
2814 \r
2815                 sourceModule = targetImport ? searchModule(modules, targetImport.label, targetImport.revisionDate) : null;\r
2816                 sourceNode = sourceModule ? sourceModule.searchNode(targetType, parts[1]) : null;\r
2817             } else {\r
2818                 sourceModule = searchModule(modules, node.module, node.moduleRevision);\r
2819                 sourceNode = sourceModule ? sourceModule.searchNode(targetType, link) : null;\r
2820             }\r
2821 \r
2822             return {node: sourceNode, module: sourceModule};\r
2823         };\r
2824 \r
2825         var appendChildren = function (targetNode, sourceNode) {\r
2826             sourceNode.children.forEach(function (child) {\r
2827                 targetNode.addChild(child);\r
2828             });\r
2829         };\r
2830 \r
2831         var searchModule = function (modules, moduleName, moduleRevision) {\r
2832             var searchResults = modules.filter(function (item) {\r
2833                     return (moduleName === item._name && (moduleRevision ? moduleRevision === item._revision : true));\r
2834                 }),\r
2835                 targetModule = (searchResults && searchResults.length) ? searchResults[0] : null;\r
2836 \r
2837             return targetModule;\r
2838         };\r
2839         var applyLinks = function (node, module, modules) {\r
2840             var changed = false;\r
2841             if (linkFunctions.hasOwnProperty(node.type)) { //applying link function to uses.node\r
2842                 changed = linkFunctions[node.type](node, module)(modules);\r
2843             }\r
2844 \r
2845             for (var i = 0; i < node.children.length; i++) {\r
2846                 if (applyLinks(node.children[i], module, modules)) {\r
2847                     i--; //need to repeat current index because we are deleting uses nodes, so in case there are more uses in row, it would skip second one\r
2848                 }\r
2849             }\r
2850 \r
2851             return changed;\r
2852         };\r
2853 \r
2854         var interConnectModules = function (modules) {\r
2855             var rootNodes = [],\r
2856                 augments = [];\r
2857 \r
2858             modules.forEach(function (module) {\r
2859                 module.getRoots().concat(module.getRawAugments()).forEach(function (node) {\r
2860                     applyLinks(node, module, modules);\r
2861                 });\r
2862             });\r
2863 \r
2864             modules.forEach(function (module) {\r
2865                 module._roots = module.getRoots().map(function (node) {\r
2866                     copy = node.deepCopy();\r
2867                     return applyModuleRevision(copy, module._name, module._revision);\r
2868                 });\r
2869 \r
2870                 module._augments = module.getRawAugments().map(function (node) {\r
2871                     copy = node.deepCopy();\r
2872                     return applyModuleRevision(copy, module._name, module._revision);\r
2873                 });\r
2874             });\r
2875 \r
2876             return modules;\r
2877         };\r
2878 \r
2879         var applyModuleRevision = function (node, module, revision) {\r
2880             node.module = module;\r
2881             node.moduleRevision = revision;\r
2882 \r
2883             node.children.map(function (child) {\r
2884                 return applyModuleRevision(child, module, revision);\r
2885             });\r
2886 \r
2887             return node;\r
2888         };\r
2889 \r
2890         moduleConnector.processModuleObjs = function (modules) {\r
2891             var rootNodes = [],\r
2892                 augments = [],\r
2893                 connectedModules = interConnectModules(modules.slice());\r
2894 \r
2895             connectedModules.forEach(function (module) {\r
2896                 rootNodes = rootNodes.concat(module.getRoots());\r
2897                 augments = augments.concat(module.getAugments());\r
2898             });\r
2899 \r
2900             return {rootNodes: rootNodes, augments: augments};\r
2901         };\r
2902 \r
2903         moduleConnector.__test = {\r
2904             isBuildInType: isBuildInType,\r
2905             linkFunctions: linkFunctions,\r
2906             findLinkedStatement: findLinkedStatement,\r
2907             appendChildren: appendChildren,\r
2908             searchModule: searchModule,\r
2909             applyLinks: applyLinks,\r
2910             interConnectModules: interConnectModules,\r
2911             applyModuleRevision: applyModuleRevision\r
2912         };\r
2913 \r
2914         return moduleConnector;\r
2915     });\r
2916 \r
2917     yangUtils.factory('dataBackuper', function () {\r
2918         var bck = {};\r
2919 \r
2920         bck.storedData = {};\r
2921 \r
2922         var getKey = function(key) {\r
2923             return key || 'DEFAULT';\r
2924         };\r
2925 \r
2926         bck.storeFromScope = function(variables, scope, key) {\r
2927             var data = {};\r
2928             key = getKey(key);\r
2929 \r
2930             variables.forEach(function(k) {\r
2931                 if(scope.hasOwnProperty(k)) {\r
2932                     data[k] = scope[k];\r
2933                 } else {\r
2934                     console.warn('scope doesn\'t have variable',k);\r
2935                 }\r
2936             });\r
2937             bck.storedData[key] = data;\r
2938         };\r
2939 \r
2940         bck.getToScope = function(variables, scope, key) {\r
2941             var data = {};\r
2942 \r
2943             key = getKey(key);\r
2944             if(bck.storedData.hasOwnProperty(key)) {\r
2945                 data = bck.storedData[key];\r
2946 \r
2947                 variables.forEach(function(k) {\r
2948                     if(data.hasOwnProperty(k)) {\r
2949                         scope[k] = data[k];\r
2950                     } else {\r
2951                         console.warn('storet data doesn\'t have variable',k);\r
2952                     }\r
2953                 });\r
2954             }\r
2955         };\r
2956 \r
2957         return bck;\r
2958     });\r
2959 \r
2960     yangUtils.factory('mountPointsConnector', function (YangUIApis, nodeWrapper, yangUtils, constants, eventDispatcher, apiBuilder, yinParser, pathUtils) {\r
2961 \r
2962         var mountPrefix = constants.MPPREFIX,\r
2963             mountPointLabel = 'Mount point';\r
2964 \r
2965         mp = {};\r
2966 \r
2967         mp.createMPRootNode = function(mpNodes) {\r
2968             var node = null,\r
2969                 yangParser = yinParser.yangParser;\r
2970 \r
2971             yangParser.setCurrentModuleObj(new yinParser.Module('yang-ext', null, null));\r
2972             node = yangParser.createNewNode('mount','container',null, constants.NODE_UI_DISPLAY);\r
2973             nodeWrapper.wrapAll(node);\r
2974 \r
2975             node.buildRequest = function (builder, req, module) {\r
2976               var added = false,\r
2977                   name = node.label,\r
2978                   builderNodes = node.getChildren(null, null, constants.NODE_UI_DISPLAY);\r
2979 \r
2980               if (builderNodes.length) {\r
2981                   builderNodes.forEach(function (child) {\r
2982                       var childAdded = child.buildRequest(builder, req, module);\r
2983                   });\r
2984               }\r
2985 \r
2986               return added;\r
2987             };\r
2988 \r
2989             node.fill = function(name, data) {\r
2990                 var nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);\r
2991 \r
2992                 nodesToFill.forEach(function (child) {\r
2993                     var childFilled = child.fill(name, data);\r
2994                 });\r
2995             };\r
2996 \r
2997 \r
2998             mpNodes.forEach(function(mp){\r
2999                 node.addChild(mp);\r
3000             });\r
3001 \r
3002             return node;\r
3003         };\r
3004 \r
3005         var addPathElemsToPathArray = function(pathElems, pathArray, index) {\r
3006             var updatedPath = pathArray.slice();\r
3007 \r
3008             pathElems.forEach(function(pe, offset) {\r
3009                 // pe.disabled = true; //add disabled flag so user won't be able to change it in the UI\r
3010                 updatedPath.splice(index + offset, 0, pe);\r
3011             });\r
3012 \r
3013             return updatedPath;\r
3014         };\r
3015 \r
3016         mp.alterMpPath = function(path) {\r
3017             var pathParts = path.split('/'),\r
3018                 restconfIndex = pathUtils.findIndexOfStrInPathStr(pathParts, 'restconf'),\r
3019                 mpIndex = pathUtils.findIndexOfStrInPathStr(pathParts, mountPrefix),\r
3020                 mpPath = path.slice(),\r
3021                 mpPathParts = '';\r
3022 \r
3023             if(mpIndex !== -1){\r
3024                 mpPathParts = pathParts.slice(mpIndex);\r
3025 \r
3026                 var unshiftIndex = restconfIndex !== -1 ? restconfIndex + 1 : 0;\r
3027 \r
3028                 mpPathParts.unshift(pathParts[unshiftIndex]);\r
3029                 mpPath = mpPathParts.join('/');\r
3030             }\r
3031 \r
3032             return mpPath;\r
3033         };\r
3034 \r
3035         //function for adding path to mountpoint + yang:ext-mount to mount point patharray so the request string will be built correctly\r
3036         mp.updateMountPointApis = function(basePathArray, mpApis) {\r
3037             var actualPath = basePathArray.slice(1); //we don't want to have config/operational storage in path\r
3038             // actualPath.push(pathUtils.createPathElement(mountPrefix, null, null, false)); //we want to push yang-ext:mount to the path - not if we have yang-ext:mount rootNode\r
3039 \r
3040             mpApis.forEach(function(api) {\r
3041                 api.subApis.forEach(function(subApi) {\r
3042                     subApi.pathArray = addPathElemsToPathArray(actualPath, subApi.pathArray, 1);\r
3043                 });\r
3044             });\r
3045         };\r
3046 \r
3047         mp.getMPModulesAPI = function(api) {\r
3048             var apiArray = api.split('/'),\r
3049                 yangExtMountStr = mountPrefix;\r
3050 \r
3051             if(apiArray[apiArray.length - 1] !== yangExtMountStr) {\r
3052                 apiArray.push(yangExtMountStr);\r
3053             }\r
3054 \r
3055             return apiArray.slice(1).join('/');\r
3056         };\r
3057 \r
3058         mp.discoverMountPoints = function(api, getModulesCbk, callback) {\r
3059             var modulesCbk = getModulesCbk || function() { return []; },\r
3060                 mpNodes = [],\r
3061                 baseApiPath = mp.getMPModulesAPI(api);\r
3062                 \r
3063             YangUIApis.getCustomModules(baseApiPath).then(\r
3064                 function (data) {\r
3065                     yangUtils.processModulesMP(data.modules, baseApiPath, function (result, augments) {\r
3066                         eventDispatcher.dispatch(constants.EV_SRC_MAIN, 'Linking modules to Apis');\r
3067                         var allRootNodes = result.map(function (node) {\r
3068                             var copy = node.deepCopy(['augmentionGroups', 'augmentationId']);\r
3069 \r
3070                             nodeWrapper.wrapAll(copy);\r
3071                             return copy;\r
3072                         });\r
3073 \r
3074                         var moduleNames = data.modules.module.map(function(m) {\r
3075                             return m.name;\r
3076                         });\r
3077 \r
3078                         allRootNodes.forEach(function(n) {\r
3079                             if(moduleNames.indexOf(n.module) > -1 && ['container','list'].indexOf(n.type) > -1) {\r
3080                                 mpNodes.push(n);\r
3081                             }\r
3082                         });\r
3083 \r
3084                         console.info('loaded mount point nodes', mpNodes);\r
3085                         callback(mpNodes, augments);\r
3086                     });\r
3087                 }, function (result) {\r
3088                     console.error('Error getting Mount point data:', result);\r
3089                     callback([]);\r
3090                 }\r
3091             );\r
3092         };\r
3093         \r
3094         mp.createCustomButton = function(label, show, click){\r
3095             return {\r
3096                 label: label, \r
3097                 show: show,\r
3098                 onclick: click\r
3099             };\r
3100         };\r
3101         \r
3102 \r
3103         return mp;\r
3104     });\r
3105 \r
3106     yangUtils.factory('yangUtils', function (yinParser, nodeWrapper, reqBuilder, syncFact, constants, pathUtils, moduleConnector, YangUIApis, eventDispatcher, apiBuilder) {\r
3107 \r
3108         var utils = {};\r
3109 \r
3110         utils.stripAngularGarbage = function(obj, prop) {\r
3111             var strippedObj = {},\r
3112                 propsToRemove = ['$$hashKey', 'route', 'reqParams', 'parentResource', 'restangularCollection'],\r
3113                 removeGarbage = function(obj) {\r
3114                     propsToRemove.forEach(function(p) {\r
3115                         delete obj[p];\r
3116                     });\r
3117 \r
3118                     return obj;\r
3119                 };\r
3120 \r
3121             if(obj.hasOwnProperty(prop)) {\r
3122                 strippedObj[prop] = obj[prop];\r
3123             } else {\r
3124                 strippedObj = removeGarbage(obj);\r
3125             }\r
3126 \r
3127             return strippedObj;\r
3128         };\r
3129 \r
3130         utils.switchConfigOper = function(apiStr, swtichTo) {\r
3131             var c = 'config',\r
3132                 o = 'operational',\r
3133                 str = apiStr;\r
3134 \r
3135             if(apiStr.indexOf(c) === 0) {\r
3136                 str = swtichTo + apiStr.slice(c.length);\r
3137             } else if(apiStr.indexOf(o) === 0) {\r
3138                 str =  swtichTo + apiStr.slice(o.length);\r
3139             } \r
3140 \r
3141             return str;\r
3142         };\r
3143 \r
3144         utils.generateNodesToApis = function (callback, errorCbk) {\r
3145             var allRootNodes = [],\r
3146                 topLevelSync = syncFact.generateObj(),\r
3147                 reqAll = topLevelSync.spawnRequest('all'),\r
3148                 allAugmentationGroups = {};\r
3149 \r
3150             YangUIApis.getAllModules().get().then(\r
3151                 function (data) {\r
3152                     utils.processModules(data.modules, function (result, aGroups) {\r
3153                         allAugmentationGroups = aGroups;\r
3154                         allRootNodes = result.map(function (node) {\r
3155                             var copy = node.deepCopy(['augmentionGroups', 'augmentationId']);\r
3156 \r
3157                             nodeWrapper.wrapAll(copy);\r
3158                             return copy;\r
3159                         });\r
3160                         topLevelSync.removeRequest(reqAll);\r
3161                     });\r
3162                 }, function (result) {\r
3163                     console.error('Error getting API data:', result);\r
3164                     topLevelSync.removeRequest(reqAll);\r
3165                 }\r
3166             );\r
3167 \r
3168             topLevelSync.waitFor(function () {\r
3169                 try {\r
3170                     eventDispatcher.dispatch(constants.EV_SRC_MAIN, 'Building apis');\r
3171                     var abApis = apiBuilder.processAllRootNodes(allRootNodes);\r
3172                     callback(abApis, allRootNodes, allAugmentationGroups);\r
3173                 } catch (e) {\r
3174                     errorCbk(e);\r
3175                     throw(e); //do not lose debugging info\r
3176                 }\r
3177             });\r
3178 \r
3179         };\r
3180 \r
3181         utils.generateApiTreeData = function (apis) {\r
3182             var newElem = function (pathElem, array) {\r
3183                     var getIdentifierStr = function(path){\r
3184                             return path.identifiers.map(function(identifier){\r
3185                                 return '{' + identifier.label + '}';\r
3186                             }).join(' ');\r
3187                         },\r
3188                         element = {\r
3189                             label: pathElem.name,\r
3190                             module: pathElem.module,\r
3191                             identifier: pathElem.hasIdentifier() ? getIdentifierStr(pathElem) : '',\r
3192                             identifiersLength: pathElem.identifiers.length,\r
3193                             children: []\r
3194                         };\r
3195 \r
3196                     array.push(element);\r
3197                 },\r
3198                 fillPath = function (path, array, indexSubApi, indexApi, itemSub, childIndex) {\r
3199                     var existElem = false,\r
3200                         arrayIndex = null,\r
3201                         currentPathItem = path[childIndex],\r
3202                         continueProcessing = false;\r
3203 \r
3204                     if (childIndex < path.length) {\r
3205                         if (array.length > 0) {\r
3206                             existElem = array.some(function (arrayItem, index) {\r
3207                                 var condition = arrayItem.label === currentPathItem.name;\r
3208                                 if (condition) {\r
3209                                     arrayIndex = index;\r
3210                                 }\r
3211 \r
3212                                 return condition;\r
3213                             });\r
3214 \r
3215                             if (!existElem) {\r
3216                                 newElem(currentPathItem, array);\r
3217                             }\r
3218                         } else {\r
3219                             newElem(currentPathItem, array);\r
3220                         }\r
3221 \r
3222                         arrayIndex = arrayIndex !== null ? arrayIndex : array.length - 1;\r
3223                         var isContinuing = fillPath(path, array[arrayIndex].children, indexSubApi, indexApi, itemSub, childIndex+1);\r
3224                         if (isContinuing === false) {\r
3225                             array[arrayIndex].indexApi = indexApi;\r
3226                             array[arrayIndex].indexSubApi = indexSubApi;\r
3227                         }\r
3228 \r
3229                         continueProcessing = true;\r
3230                     }\r
3231 \r
3232                     return continueProcessing;\r
3233                 },\r
3234                 getApisAndPath = function (item, indexApi) {\r
3235                     var childrenArray = [];\r
3236 \r
3237                     item.subApis.map(function (itemSub, indexSubApi) {\r
3238                         var childIndex = 0;\r
3239                         fillPath(itemSub.pathArray, childrenArray, indexSubApi, indexApi, itemSub, childIndex);\r
3240                     });\r
3241 \r
3242                     return childrenArray;\r
3243                 },\r
3244                 dataTree = apis.map(function (item, indexApi) {\r
3245                     var apisPath = getApisAndPath(item, indexApi);\r
3246 \r
3247                     return {\r
3248                         label: item.module + (item.revision ? ' rev.' + item.revision : ''),\r
3249                         module: item.module,\r
3250                         revision: item.revision,\r
3251                         children: apisPath\r
3252                     };\r
3253                 }),\r
3254                 sortedDataTree = dataTree.sort(function(a, b) {\r
3255                     var sortRes = 0;\r
3256                     if(a.label < b.label) {\r
3257                         sortRes = -1;\r
3258                     }\r
3259                     if(a.label > b.label) {\r
3260                         sortRes = 1;\r
3261                     }\r
3262                     return sortRes;\r
3263                 });\r
3264 \r
3265             return sortedDataTree;\r
3266         };\r
3267 \r
3268         utils.processModules = function (loadedModules, callback) {\r
3269             var modules = [],\r
3270                 rootNodes = [],\r
3271                 augments = [],\r
3272                 syncModules = syncFact.generateObj(),\r
3273                 augmentionGroups = new yinParser.Augmentations();\r
3274 \r
3275             eventDispatcher.dispatch(constants.EV_SRC_MAIN, 'Processing modules');\r
3276             loadedModules.module.forEach(function (module) {\r
3277                 var reqId = syncModules.spawnRequest(module.name);\r
3278 \r
3279                 yinParser.parseYang(module.name, module.revision, function (module) {\r
3280                     modules.push(module);\r
3281                     syncModules.removeRequest(reqId);\r
3282                 }, function () {\r
3283                     syncModules.removeRequest(reqId);\r
3284                 });\r
3285             });\r
3286 \r
3287             syncModules.waitFor(function () {\r
3288                 eventDispatcher.dispatch(constants.EV_SRC_MAIN, 'Linking uses and typedefs');\r
3289                 processedData = moduleConnector.processModuleObjs(modules);\r
3290                 rootNodes = processedData.rootNodes;\r
3291                 augments = processedData.augments;\r
3292 \r
3293                 eventDispatcher.dispatch(constants.EV_SRC_MAIN, 'Linking augments');\r
3294 \r
3295                 var sortedAugments = augments.sort(function (a, b) {\r
3296                     return a.path.length - b.path.length;\r
3297                 });\r
3298 \r
3299                 sortedAugments.map(function (elem) {\r
3300                     elem.apply(rootNodes, augmentionGroups);\r
3301                 });\r
3302 \r
3303                 callback(rootNodes, augmentionGroups);\r
3304             });\r
3305         };\r
3306 \r
3307         utils.processModulesMP = function (loadedModules, basePath, callback) {\r
3308             var modules = [],\r
3309                 rootNodes = [],\r
3310                 augments = [],\r
3311                 syncModules = syncFact.generateObj(),\r
3312                 augmentionGroups = new yinParser.Augmentations();\r
3313 \r
3314             eventDispatcher.dispatch(constants.EV_SRC_MAIN, 'Processing modules');\r
3315             loadedModules.module.forEach(function (module) {\r
3316                 var reqId = syncModules.spawnRequest(module.name);\r
3317                 \r
3318                 yinParser.parseYangMP(basePath, module.name, module.revision, function (module) {\r
3319                     modules.push(module);\r
3320                     syncModules.removeRequest(reqId);\r
3321                 }, function () {\r
3322                     syncModules.removeRequest(reqId);\r
3323                 });\r
3324             });\r
3325 \r
3326             syncModules.waitFor(function () {\r
3327                 eventDispatcher.dispatch(constants.EV_SRC_MAIN, 'Linking uses and typedefs');\r
3328                 processedData = moduleConnector.processModuleObjs(modules);\r
3329                 rootNodes = processedData.rootNodes;\r
3330                 augments = processedData.augments;\r
3331 \r
3332                 eventDispatcher.dispatch(constants.EV_SRC_MAIN, 'Linking augments');\r
3333 \r
3334                 var sortedAugments = augments.sort(function (a, b) {\r
3335                     return a.path.length - b.path.length;\r
3336                 });\r
3337 \r
3338                 sortedAugments.map(function (elem) {\r
3339                     elem.apply(rootNodes, augmentionGroups);\r
3340                 });\r
3341 \r
3342                 callback(rootNodes, augmentionGroups);\r
3343             });\r
3344         };\r
3345 \r
3346         utils.getRequestString = function (node) {\r
3347             var request = reqBuilder.createObj(),\r
3348                 reqStr = '';\r
3349 \r
3350             node.buildRequest(reqBuilder, request, node.module);\r
3351 \r
3352             if (request && $.isEmptyObject(request) === false) {\r
3353                 reqStr = reqBuilder.resultToString(request);\r
3354             }\r
3355             return reqStr;\r
3356         };\r
3357 \r
3358         utils.transformTopologyData = function (data, callback) {\r
3359             var links = [],\r
3360                 nodes = [],\r
3361                 getNodeIdByText = function getNodeIdByText(inNodes, text) {\r
3362                     var nodes = inNodes.filter(function (item, index) {\r
3363                         return item.label === text;\r
3364                     }),\r
3365                             nodeId;\r
3366 \r
3367                     if (nodes.length > 0 && nodes[0]) {\r
3368                         nodeId = nodes[0].id;\r
3369                     } else {\r
3370                         return null;\r
3371                     }\r
3372 \r
3373                     return nodeId;\r
3374                 };\r
3375 \r
3376 \r
3377             if (data['network-topology'] && data['network-topology'].topology.length) {\r
3378                 var topoData = callback ? callback(data['network-topology'].topology) : data['network-topology'].topology[0],\r
3379                     nodeId = 0,\r
3380                     linkId = 0;\r
3381 \r
3382                 nodes = topoData.hasOwnProperty('node') ? topoData.node.map(function (nodeData) {\r
3383                     return {'id': (nodeId++).toString(), 'label': nodeData["node-id"], group: nodeData["node-id"].indexOf('host') === 0 ? 'host' : 'switch', value: 20, title: 'Name: <b>' + nodeData["node-id"] + '</b><br>Type: Switch'};\r
3384                 }) : [];\r
3385 \r
3386                 links = topoData.hasOwnProperty('link') ? topoData.link.map(function (linkData) {\r
3387                     var srcId = getNodeIdByText(nodes, linkData.source["source-node"]),\r
3388                             dstId = getNodeIdByText(nodes, linkData.destination["dest-node"]),\r
3389                             srcPort = linkData.source["source-tp"],\r
3390                             dstPort = linkData.destination["dest-tp"];\r
3391                     if (srcId != null && dstId != null) {\r
3392                         return {id: (linkId++).toString(), 'from': srcId, 'to': dstId, title: 'Source Port: <b>' + srcPort + '</b><br>Dest Port: <b>' + dstPort + '</b>'};\r
3393                     }\r
3394                 }) : [];\r
3395             }\r
3396 \r
3397             return {nodes: nodes, links: links};\r
3398         };\r
3399 \r
3400         utils.objectHandler = function(obj, objCbk, vauleCbk, arrayCbk){\r
3401             if ( Array.isArray(obj) ) {\r
3402               if (angular.isFunction(arrayCbk)) {\r
3403                 arrayCbk(obj);\r
3404               }\r
3405                   \r
3406               obj.forEach(function(item){\r
3407                 utils.objectHandler(item, objCbk, vauleCbk);\r
3408               });\r
3409             } else {\r
3410               if ( obj !== null && Object.keys(obj).length > 0 && typeof obj !== 'string' ) {\r
3411                   if (angular.isFunction(objCbk)) {\r
3412                     objCbk(obj);\r
3413                   }\r
3414 \r
3415                   for(var property in obj){\r
3416                     utils.objectHandler(obj[property], objCbk, vauleCbk);\r
3417                   }\r
3418               } else {\r
3419                 if (angular.isFunction(vauleCbk)) {\r
3420                   vauleCbk(obj);\r
3421                 }\r
3422               }\r
3423             }\r
3424         };\r
3425 \r
3426         var checkSupApiIdentifiers = function(subApi){\r
3427                 var pathElement = subApi.pathArray[subApi.pathArray.length-1];\r
3428                 return pathElement.hasIdentifier() ? pathElement.identifiers : [];\r
3429             },\r
3430             postRequestData = function(requestData, reqString, subApi){\r
3431                 var identifiersArray = checkSupApiIdentifiers(subApi),\r
3432                     lastPathElement = function(path){\r
3433                         return path.split('/').pop().split(':').pop();\r
3434                     };\r
3435 \r
3436                 if ( identifiersArray.length ) {\r
3437                     var pathArray = reqString.split('/'),\r
3438                         reqObj = null;\r
3439 \r
3440                     identifiersArray.forEach(function(){\r
3441                         pathArray.pop();\r
3442                     });\r
3443 \r
3444                     reqString = pathArray.join('/');\r
3445                     requestItem = requestData[lastPathElement(reqString)] ? requestData[lastPathElement(reqString)].filter(function(item){\r
3446                         return identifiersArray.every(function(i){\r
3447                                     return item[i.label] === i.value;\r
3448                                 });\r
3449                       }) : [];\r
3450                     \r
3451                     return requestItem.length ? requestItem[0] : {};\r
3452                 } else {\r
3453                     return requestData[lastPathElement(reqString)];\r
3454                 }\r
3455             };\r
3456 \r
3457         utils.prepareRequestData = function(requestData, operation, reqString, subApi){\r
3458             var preparedData = requestData;\r
3459 \r
3460             if(operation === 'GET'){\r
3461                 preparedData = null;\r
3462             }\r
3463             else if(operation === 'POST'){\r
3464                 return postRequestData(requestData, reqString, subApi);\r
3465             }\r
3466 \r
3467             return preparedData;\r
3468         };\r
3469 \r
3470         utils.prepareOperation = function(operation){\r
3471             return operation === 'DELETE' ? 'REMOVE' : operation;\r
3472         };\r
3473 \r
3474         utils.prepareHeaders = function(requestData){\r
3475             return requestData === constants.NULL_DATA ? { "Content-Type": undefined} : { "Content-Type": "application/yang.data+json"};\r
3476         };\r
3477 \r
3478         utils.errorMessages = {\r
3479             'method' : \r
3480                     {\r
3481                         'GET': {\r
3482                             '401':'YANGUI_ERROR_GET_401',\r
3483                             '403':'YANGUI_ERROR_GET_403',\r
3484                             '404':'YANGUI_ERROR_GET_404',\r
3485                             '500':'YANGUI_ERROR_GET_500',\r
3486                             '503':'YANGUI_ERROR_GET_503'\r
3487                         },\r
3488                         'POST': {\r
3489                             '500':'YANGUI_ERROR_GET_500',\r
3490                             '503':'YANGUI_ERROR_GET_503'\r
3491                         },\r
3492                         'PUT': {\r
3493                             '500':'YANGUI_ERROR_GET_500',\r
3494                             '503':'YANGUI_ERROR_GET_503'\r
3495                         },\r
3496                         'DELETE': {\r
3497                             '500':'YANGUI_ERROR_GET_500',\r
3498                             '503':'YANGUI_ERROR_GET_503'\r
3499                         }\r
3500                     }\r
3501             };\r
3502 \r
3503         utils.__test = {\r
3504         };\r
3505 \r
3506         return utils;\r
3507 \r
3508     });\r
3509 \r
3510     yangUtils.factory('constants', function () {\r
3511         return  {\r
3512             NODE_UI_DISPLAY: 1,\r
3513             NODE_ALTER: 2,\r
3514             NODE_CONDITIONAL: 3,\r
3515             NODE_RESTRICTIONS: 4,\r
3516             NODE_LINK: 5,\r
3517             NODE_LINK_TARGET: 6,\r
3518             LOCALE_PREFIX: 'YANGUI_FORM_',\r
3519             EV_SRC_MAIN: 'EV_SRC_MAIN',\r
3520             EV_FILL_PATH: 'EV_FILL_PATH',\r
3521             EV_LIST_CHANGED: 'EV_LIST_CHANGED',\r
3522             EV_PARAM_EDIT_SUCC: 'EV_PARAM_EDIT_SUCC',\r
3523             MPPREFIX: 'yang-ext:mount',\r
3524             NULL_DATA: null\r
3525         };\r
3526     });\r
3527 \r
3528     yangUtils.factory('designUtils', function () {\r
3529         var d = {};\r
3530 \r
3531         d.setDraggablePopups = function(){\r
3532             $( ".draggablePopup" ).draggable({\r
3533                 opacity: 0.35,\r
3534                 containment: "#page-wrapper",\r
3535                 cancel: 'pre, input, textarea, span, select'\r
3536             });\r
3537 \r
3538             $(function() {\r
3539                 $( ".resizable-se" ).resizable({ handles: 'se' });\r
3540                 $( ".resizable-s" ).resizable({ handles: 's', minHeight: 200 });\r
3541               });\r
3542         };\r
3543 \r
3544         d.getHistoryPopUpWidth = function(){\r
3545             var getWidth = function(){\r
3546                 return $('.topologyContainer.previewContainer.historyPopUp').width();\r
3547             };\r
3548 \r
3549 \r
3550             if ( getWidth() !== null ) {\r
3551                 $('.topologyContainer.previewContainer.historyPopUp').css({'marginLeft':'-'+(getWidth()/2)+'px'});\r
3552             }\r
3553         };\r
3554 \r
3555         d.triggerWindowResize = function (timeout) {\r
3556             var t = timeout ? timeout : 1;\r
3557 \r
3558             setTimeout(function(){\r
3559                 $(window).trigger('resize');\r
3560             }, t);\r
3561 \r
3562 \r
3563         };\r
3564 \r
3565         return d;\r
3566     });\r
3567 \r
3568     yangUtils.factory('handleFile', function () {\r
3569         var f = {};\r
3570 \r
3571         f.downloadFile = function(filename, data, format, charset, successCbk, errorCbk){\r
3572             try{\r
3573                 var blob = new Blob([data], { type:"application/"+format+"; "+charset+";"});\r
3574                 downloadLink = angular.element("<a></a>");\r
3575 \r
3576                 downloadLink.attr('href', window.URL.createObjectURL(blob));\r
3577                 downloadLink.attr('download', filename);\r
3578                 downloadLink[0].click();\r
3579                 successCbk();\r
3580              }catch(e) {\r
3581                 errorCbk(e);\r
3582              }\r
3583         };\r
3584 \r
3585         return f;\r
3586     });\r
3587 });\r