1 define([], function () {
4 function YinParserService($http, SyncService, constants, PathUtilsService, YangUiApisService, NodeUtilsService){
5 var augmentType = 'augment';
8 var Module = function (name, revision, namespace) {
10 this._revision = revision;
11 this._namespace = namespace;
12 this._statements = {};
16 this.getRoots = function () {
20 this.getImportByPrefix = function (prefix) {
21 var importNode = null;
23 if (this._statements.hasOwnProperty('import')) {
24 importNode = this._statements.import.filter(function (importItem) {
25 return importItem._prefix === prefix;
32 this.getRawAugments = function () {
33 return this._augments;
36 this.getAugments = function () {
39 return this.getRawAugments().map(function (augNode) {
40 var prefixConverter = function (prefix) {
41 var importNode = self.getImportByPrefix(prefix);
42 return importNode ? importNode.label : null;
44 getDefaultModule = function() {
48 augNode.path = PathUtilsService.translate(augNode.pathString, prefixConverter, self._statements.import, getDefaultModule);
50 return new Augmentation(augNode);
54 this.addChild = function (node) {
55 if (!this._statements.hasOwnProperty(node.type)) {
56 this._statements[node.type] = [];
59 var duplicates = this._statements[node.type].filter(function (item) {
60 return node.label === item.label && node.nodeType === item.nodeType;
63 if (duplicates && duplicates.length > 0) {
64 console.warn('trying to add duplicate node', node, 'to module', this._statements);
66 this._statements[node.type].push(node);
68 if (NodeUtilsService.isRootNode(node.type)) {
69 this._roots.push(node);
72 if (node.type === 'augment') {
73 this._augments.push(node);
78 this.searchNode = function (type, name) {
79 var searchResults = null,
82 if (this._statements[type]) {
83 searchResults = this._statements[type].filter(function (node) {
84 return name === node.label;
88 if (searchResults && searchResults.length === 0) {
89 //console.warn('no nodes with type', type, 'and name', name, 'found in', this);
90 } else if (searchResults && searchResults.length > 1) {
91 //console.warn('multiple nodes with type', type, 'and name', name, 'found in', this);
92 } else if (searchResults && searchResults.length === 1) {
93 searchedNode = searchResults[0];
100 var Node = function (id, name, type, module, namespace, parent, nodeType, moduleRevision) {
103 this.localeLabel = constants.LOCALE_PREFIX + name.toUpperCase();
105 this.module = module;
107 this.parent = parent;
108 this.nodeType = nodeType;
109 this.namespace = namespace;
110 this.moduleRevision = moduleRevision;
112 this.appendTo = function (parentNode) {
113 parentNode.addChild(this);
116 this.addChild = function (node) {
117 if (this.children.indexOf(node) === -1) {
118 this.children.push(node);
124 this.deepCopy = function deepCopy(additionalProperties) {
125 var copy = new Node(this.id, this.label, this.type, this.module, this.namespace, null, this.nodeType, this.moduleRevision),
128 additionalProperties = (additionalProperties || []).concat(['pathString']);
130 additionalProperties.forEach(function(prop) {
131 if (prop !== 'children' && self.hasOwnProperty(prop) && copy.hasOwnProperty(prop) === false) {
132 copy[prop] = self[prop];
136 this.children.forEach(function (child) {
137 var childCopy = child.deepCopy(additionalProperties);
138 childCopy.parent = copy;
139 copy.children.push(childCopy);
144 this.getCleanCopy = function(){
145 return new Node(this.id, this.label, this.type, this.module, this.namespace, null, this.nodeType, this.moduleRevision);
148 this.getChildren = function (type, name, nodeType, property) {
149 var filteredChildren = this.children.filter(function (item) {
150 return (name != null ? name === item.label : true) && (type != null ? type === item.type : true) && (nodeType != null ? nodeType === item.nodeType : true);
154 return filteredChildren.filter(function (item) {
155 return item.hasOwnProperty(property);
156 }).map(function (item) {
157 return item[property];
160 return filteredChildren;
168 var AugmentationsGroup = function(){
171 this.addAugumentation = function(augumentation){
172 this.obj[augumentation.id] = augumentation;
176 var Augmentations = function(){
179 this.addGroup = function(groupId){
180 this.groups[groupId] = !this.groups.hasOwnProperty(groupId) ? new AugmentationsGroup() : this.groups[groupId];
183 this.getAugmentation = function(node, augId) {
184 return this.groups[node.module + ':' + node.label] ? this.groups[node.module + ':' + node.label].obj[augId] : null;
188 var Augmentation = function (node) {
191 this.path = (node.path ? node.path : []);
192 this.id = node.module + ':' + node.label;
193 this.expanded = true;
195 //node.label = node.module + ':' + node.label;
198 this.toggleExpand = function () {
199 this.expanded = !this.expanded;
202 this.setAugmentationGroup = function(targetNode, augumentations){
203 var targetNodeId = targetNode.module + ':' + targetNode.label;
204 targetNode.augmentionGroups = targetNode.augmentionGroups ? targetNode.augmentionGroups : [];
205 targetNode.augmentionGroups.push(self.id);
207 augumentations.addGroup(targetNodeId);
208 augumentations.groups[targetNodeId].addAugumentation(self);
211 this.apply = function (nodeList, augumentations) {
212 var targetNode = this.getTargetNodeToAugment(nodeList);
215 this.setAugmentationGroup(targetNode, augumentations);
217 this.node.children.forEach(function (child) {
218 child.appendTo(targetNode);
219 child.augmentationId = self.id;
221 // child.children.forEach(function (moduleChild) {
222 // moduleChild.label = moduleChild.module + ':' + moduleChild.label;
226 console.warn('can\'t find target node for augmentation ', this.getPathString());
230 this.getTargetNodeToAugment = function (nodeList) {
231 return PathUtilsService.search({children: nodeList}, this.path.slice());
234 this.getPathString = function () {
235 return this.path.map(function (elem) {
236 return elem.module + ':' + elem.name;
242 var parentTag = function (xml) {
243 if (xml.get(0).tagName.toLowerCase() === 'module') {
246 return parentTag(xml.parent());
250 var parseModule = function(data, callback) {
251 var yangParser = new YangParser();
253 var moduleName = $($.parseXML(data).documentElement).attr('name'),
254 moduleNamespace = $($.parseXML(data)).find('namespace').attr('uri'),
255 moduleoduleRevision = $($.parseXML(data)).find('revision').attr('date'),
256 moduleObj = new Module(moduleName, moduleoduleRevision, moduleNamespace);
258 yangParser.setCurrentModuleObj(moduleObj);
259 yangParser.parse($.parseXML(data).documentElement, moduleObj);
261 yangParser.sync.waitFor(function () {
266 var loadStaticModule = function(name, callback, errorCbk) {
267 var yinPath = '/yang2xml/' + name + '.yang.xml';
268 $http.get(path + yinPath).success(function(data) {
269 console.warn('cannot load '+ name + 'from controller, trying loading from static storage');
270 parseModule(data, callback);
271 }).error(function() {
272 console.warn('cannot load file '+ yinPath + 'from static storage');
278 var parseYangMP = function parseYangMP(baseApiPath, name, rev, callback, errorCbk) {
279 var path = baseApiPath + '/' + name + '/' + rev + '/schema';
281 YangUiApisService.getSingleModuleInfo(path).then(
283 if($.parseXML(data) !== null) {
284 parseModule(data, callback);
286 loadStaticModule(name, callback, errorCbk);
289 loadStaticModule(name, callback, errorCbk);
294 var parseYang = function parseYang(name, rev, callback, errorCbk) {
295 YangUiApisService.getModuleSchema(name, rev).get().then(
297 if($.parseXML(data) !== null) {
298 parseModule(data, callback);
300 loadStaticModule(name, callback, errorCbk);
303 loadStaticModule(name, callback, errorCbk);
308 var YangParser = function () {
311 this.sync = SyncService.generateObj();
312 this.moduleObj = null;
314 this.setCurrentModuleObj = function (moduleObj) {
315 this.moduleObj = moduleObj;
318 this.createNewNode = function (name, type, parentNode, nodeType) {
319 var node = new Node(this.nodeIndex++, name, type, this.moduleObj._name, this.moduleObj._namespace, parentNode, nodeType, this.moduleObj._revision);
322 parentNode.addChild(node);
328 this.parse = function (xml, parent) {
331 $(xml).children().each(function (_, item) {
332 var prop = item.tagName.toLowerCase();
333 if (self.hasOwnProperty(prop)) {
334 self[prop](item, parent);
336 // self.parse(this, parent);
341 this.config = function(xml, parent) {
343 name = $(xml).attr('value'),
344 nodeType = constants.NODE_ALTER,
345 node = this.createNewNode(name, type, parent, nodeType);
348 this.presence = function(xml, parent) {
349 var type = 'presence',
350 name = $(xml).attr('value'),
351 nodeType = constants.NODE_ALTER,
352 node = this.createNewNode(name, type, parent, nodeType);
355 this.leaf = function (xml, parent) {
357 name = $(xml).attr('name'),
358 nodeType = constants.NODE_UI_DISPLAY,
359 node = this.createNewNode(name, type, parent, nodeType);
361 this.parse(xml, node);
364 this['leaf-list'] = function (xml, parent) {
365 var type = 'leaf-list',
366 name = $(xml).attr('name'),
367 nodeType = constants.NODE_UI_DISPLAY,
368 node = this.createNewNode(name, type, parent, nodeType);
370 this.parse(xml, node);
373 this.container = function (xml, parent) {
374 var type = 'container',
375 name = $(xml).attr('name'),
376 nodeType = constants.NODE_UI_DISPLAY,
377 node = this.createNewNode(name, type, parent, nodeType);
379 this.parse(xml, node);
382 this.choice = function (xml, parent) {
384 name = $(xml).attr('name'),
385 nodeType = constants.NODE_UI_DISPLAY,
386 node = this.createNewNode(name, type, parent, nodeType);
388 this.parse(xml, node);
391 this.case = function (xml, parent) {
393 name = $(xml).attr('name'),
394 nodeType = constants.NODE_UI_DISPLAY,
395 node = this.createNewNode(name, type, parent, nodeType);
397 this.parse(xml, node);
400 this.list = function (xml, parent) {
402 name = $(xml).attr('name'),
403 nodeType = constants.NODE_UI_DISPLAY,
404 node = this.createNewNode(name, type, parent, nodeType);
406 this.parse(xml, node);
410 this.key = function (xml, parent) {
412 name = $(xml).attr('value'),
413 nodeType = constants.NODE_ALTER,
414 node = this.createNewNode(name, type, parent, nodeType);
416 this.parse(xml, node);
419 this.description = function (xml, parent) {
420 var type = 'description',
421 name = $(xml).attr('text') ? $(xml).attr('text') : $(xml).children('text:first').text(),
422 nodeType = constants.NODE_ALTER,
423 node = this.createNewNode(name, type, parent, nodeType);
425 this.parse(xml, node);
428 this.typedef = function (xml, parent, typedefName) {
429 var type = 'typedef',
430 name = $(xml).attr('name'),
431 nodeType = constants.NODE_LINK_TARGET,
432 node = this.createNewNode(name, type, parent, nodeType);
434 this.parse(xml, node);
437 this.grouping = function (xml, parent, groupingName) {
438 var type = 'grouping',
439 name = $(xml).attr('name'),
440 nodeType = constants.NODE_LINK_TARGET,
441 node = this.createNewNode(name, type, parent, nodeType);
443 this.parse(xml, node);
446 this.uses = function (xml, parent) {
448 name = $(xml).attr('name'),
449 nodeType = constants.NODE_LINK,
450 node = this.createNewNode(name, type, parent, nodeType);
452 this.parse(xml, node);
455 this.import = function (xml, parent) {
457 name = $(xml).attr('module'),
458 nodeType = constants.NODE_ALTER,
459 node = this.createNewNode(name, type, parent, nodeType);
461 node._prefix = $(xml).children('prefix:first').attr('value');
462 node._revisionDate = $(xml).children('revision-date:first').attr('date');
465 this.augment = function (xml, parent) {
466 var type = augmentType,
467 nodeType = constants.NODE_ALTER,
468 augmentIndentifier = $(xml).children("ext\\:augment-identifier:first").attr("ext:identifier"),
469 name = augmentIndentifier ? augmentIndentifier : 'augment' + (this.nodeIndex + 1).toString(),
470 pathString = $(xml).attr('target-node'),
471 augmentRoot = this.createNewNode(name, type, parent, nodeType);
473 augmentRoot.pathString = pathString;
474 this.parse(xml, augmentRoot);
478 this.rpc = function (xml, parent) {
480 name = $(xml).attr('name'),
481 nodeType = constants.NODE_UI_DISPLAY,
482 node = this.createNewNode(name, type, parent, nodeType);
484 this.parse(xml, node);
487 this.input = function (xml, parent) {
490 nodeType = constants.NODE_UI_DISPLAY,
491 node = this.createNewNode(name, type, parent, nodeType);
493 this.parse(xml, node);
496 this.output = function (xml, parent) {
499 nodeType = constants.NODE_UI_DISPLAY,
500 node = this.createNewNode(name, type, parent, nodeType);
502 this.parse(xml, node);
505 this.pattern = function (xml, parent) {
506 var type = 'pattern',
507 name = $(xml).attr('value'),
508 nodeType = constants.NODE_RESTRICTIONS;
510 this.createNewNode(name, type, parent, nodeType);
513 this.range = function (xml, parent) {
515 name = $(xml).attr('value'),
516 nodeType = constants.NODE_RESTRICTIONS;
518 this.createNewNode(name, type, parent, nodeType);
521 this.length = function (xml, parent) {
523 name = $(xml).attr('value'),
524 nodeType = constants.NODE_RESTRICTIONS;
526 this.createNewNode(name, type, parent, nodeType);
529 this.enum = function (xml, parent) {
531 name = $(xml).attr('name'),
532 nodeType = constants.NODE_ALTER;
534 this.createNewNode(name, type, parent, nodeType);
537 this.bit = function (xml, parent) {
539 name = $(xml).attr('name'),
540 nodeType = constants.NODE_ALTER,
541 node = this.createNewNode(name, type, parent, nodeType);
543 this.parse(xml, node);
546 this.position = function (xml, parent) {
547 var type = 'position',
548 name = $(xml).attr('value'),
549 nodeType = constants.NODE_ALTER;
551 this.createNewNode(name, type, parent, nodeType);
554 this.type = function (xml, parent) {
556 name = $(xml).attr('name'),
557 nodeType = constants.NODE_ALTER,
558 node = this.createNewNode(name, type, parent, nodeType);
560 this.parse(xml, node);
565 parseYang: parseYang,
566 parseYangMP: parseYangMP,
567 yangParser: new YangParser(),
568 Augmentations: Augmentations,
572 parentTag: parentTag,
573 yangParser: new YangParser(),
574 Augmentation: Augmentation,
580 YinParserService.$inject=['$http','SyncService', 'constants', 'PathUtilsService', 'YangUiApisService', 'NodeUtilsService'];
582 return YinParserService;