1 define([], function () {
4 function NodeWrapperService(constants, RequestBuilderService, RestrictionsService, TypeWrapperService,
5 ListFilteringService, EventDispatcherService, FilterNodeWrapperService){
11 checkKeyDuplicity: checkKeyDuplicity,
16 'leaf-list': leafList,
28 comparePropToElemByName: comparePropToElemByName,
29 equalArrays: equalArrays,
30 equalListElems: equalListElems,
31 parseRestrictText: parseRestrictText,
33 checkListElemKeys: checkListElemKeys,
40 * Service for wrapping list element
44 function _listElem(node) {
47 node.listElemBuildRequest = function (builder, req) {
49 objToAdd = builder.createObj();
51 node.getChildren(null, null, constants.NODE_UI_DISPLAY).forEach(function (child) {
52 var childAdded = child.buildRequest(builder, objToAdd, node.module);
53 added = added || childAdded;
57 builder.insertObjToList(req, objToAdd);
63 node.fillListElement = function (name, data) {
66 node.getChildren(null, null, constants.NODE_UI_DISPLAY).forEach(function (child) {
67 var childFilled = child.fill(name, data);
68 filled = filled || childFilled;
74 node.isFilled = function () {
75 return node.getChildren(null, null, constants.NODE_UI_DISPLAY).some(function (child) {
76 return child.isFilled();
80 node.clear = function () {
81 var nodesToClear = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
83 if (nodesToClear.length) {
84 nodesToClear.forEach(function (child) {
90 node.children.forEach(function (child) {
96 * Service for wrapping list yang element
101 node.doubleKeyIndexes = [];
102 node.actElemStructure = null;
103 node.actElemIndex = -1;
105 node.expanded = true;
107 node.filterNodes = [];
108 node.searchedPath = [];
109 node.referenceNode = null;
110 node.filteredListData = [];
111 node.currentFilter = 0;
113 node.toggleExpand = function () {
114 node.expanded = !node.expanded;
117 node.createStructure = function () {
118 if (node.actElemStructure === null) {
119 var copy = node.deepCopy(['augmentionGroups', 'augmentationId']);
121 node.actElemStructure = copy;
122 node.actElemStructure.getActElemIndex = node.getActElemIndex;
126 node.getActElemIndex = function () {
127 return node.actElemIndex;
130 node.addListElem = function () {
131 node.createStructure();
132 var newElemData = {};
133 node.listData.push(newElemData);
134 node.changeActElementData(node.listData.length - 1, true);
137 node.buildActElemData = function () {
141 if (node.actElemStructure) {
142 node.actElemStructure.listElemBuildRequest(RequestBuilderService, list, node.module);
143 result = list[0] ? list[0] : {};
148 node.changeActElementData = function (index, fromAdd) {
149 var storeData = node.buildActElemData();
150 node.expanded = true;
152 if (node.actElemIndex > -1) { // we are changing already existing data
153 if (node.filteredListData && node.filteredListData.length){
154 node.listData[node.listData.indexOf(node.filteredListData[node.actElemIndex])] = storeData;
155 node.filteredListData[node.actElemIndex] = storeData;
157 ListFilteringService.clearFilterData(node, true, false);
160 node.listData[node.actElemIndex] = storeData;
163 node.actElemIndex = index;
166 if (!(node.filteredListData && node.filteredListData.length)){
167 actData = node.listData[node.actElemIndex];
169 actData = node.listData[node.listData.indexOf(node.filteredListData[node.actElemIndex])];
172 node.actElemStructure.clear();
173 Object.keys(actData).forEach(function(prop) {
174 node.actElemStructure.fillListElement(prop, actData[prop]);
177 EventDispatcherService.dispatch(constants.EV_LIST_CHANGED, node.actElemStructure);
180 node.removeListElem = function (elemIndex, fromFilter) {
183 elemIndex = node.listData.indexOf(node.filteredListData[elemIndex]);
186 node.listData.splice(elemIndex, 1);
187 node.actElemIndex = node.listData.length - 1;
190 ListFilteringService.clearFilterData(node, true, false);
193 if (node.actElemIndex === -1) {
194 node.actElemStructure = null;
196 var actData = node.listData[node.actElemIndex];
198 node.actElemStructure.clear();
199 Object.keys(actData).forEach(function(prop) {
200 node.actElemStructure.fillListElement(prop, actData[prop]);
204 EventDispatcherService.dispatch(constants.EV_LIST_CHANGED, node.actElemStructure);
207 node.buildRequest = function (builder, req, module) {
209 // store entered data
210 var storeData = node.buildActElemData(),
211 labelWithModule = (module !== node.module ? node.module + ':' : '') + node.label;
213 if (node.actElemIndex > -1) {
214 if (node.filteredListData && node.filteredListData.length){
215 node.listData[node.listData.indexOf(node.filteredListData[node.actElemIndex])] = storeData;
216 node.filteredListData[node.actElemIndex] = storeData;
218 node.listData[node.actElemIndex] = storeData;
222 added = node.listData.filter(function (data) {
223 return $.isEmptyObject(data) === false;
226 var buildedDataCopy = node.listData.slice().map(function (item) {
228 Object.keys(item).forEach(function(prop) {
229 if (prop !== '$$hashKey'){
230 newItem[prop] = item[prop];
234 }).filter(function (item){
235 return Object.keys(item).length !== 0;
238 // check of listElems keyValues duplicity
239 if (node.filteredListData && node.filteredListData.length){
240 node.doubleKeyIndexes = checkKeyDuplicity(node.filteredListData, node.refKey);
242 node.doubleKeyIndexes = checkKeyDuplicity(node.listData, node.refKey);
246 builder.insertPropertyToObj(req, labelWithModule, buildedDataCopy);
252 node.fill = function (name, array) { // data is array
254 var match = comparePropToElemByName(name, node.label);
256 if (match && array.length) {
257 node.createStructure();
258 node.listData = array.slice();
259 node.actElemIndex = node.listData.length - 1;
261 Object.keys(node.listData[node.actElemIndex]).forEach(function(prop) {
262 node.actElemStructure.fillListElement(prop, node.listData[node.actElemIndex][prop]);
266 return (match && array.length > 0);
269 node.clear = function () {
270 while (node.listData.length > 0) {
273 while (node.filteredListData.length > 0) {
274 node.filteredListData.pop();
277 node.actElemIndex = -1;
278 node.actElemStructure = null;
279 node.nodeType = constants.NODE_UI_DISPLAY;
282 node.isFilled = function () {
283 return node.listData.length > 0;
286 node.createListName = function (index) {
291 if (node.filteredListData && node.filteredListData.length){
292 currentList = node.filteredListData;
294 currentList = node.listData;
298 node.actElemStructure.refKey.forEach(function (key) {
299 if (index === node.getActElemIndex()) {
300 val = key.value !== '' ? key.label + ':' + key.value : '';
303 if (!($.isEmptyObject(currentList[index]))) {
304 if (currentList[index][key.label]) {
306 } else if (currentList[index][key.module + ':' + key.label]) {
307 prop = key.module + ':' + key.label;
309 val = prop ? key.label + ':' + currentList[index][prop] : prop;
313 name = name ? (name + (val ? (' ' + val) : '')) : (name + (val ? (' <' + val) : ''));
324 node.getNewFilterElement = function (){
325 return node.getChildrenForFilter().map(function (element){
326 FilterNodeWrapperService.init(element);
327 var copy = element.deepCopyForFilter();
329 FilterNodeWrapperService.wrapForFilter(copy);
335 // TODO: add service's description
336 function config(node) {
337 node.parent.isConfigStm = (node.label === 'true');
340 // TODO: add service's description
342 // do this only on list, not on listElem because deepCopy on list doesn't copy property keys to
343 // listElem => don't do this when button for add new list is clicked
344 if (node.parent.hasOwnProperty('refKey')) {
345 var keyLabels = node.label.split(' '),
346 keyNodes = node.parent.getChildren(null, null, constants.NODE_UI_DISPLAY).filter(function (child) {
347 return keyLabels.indexOf(child.label) > -1;
349 getRefKeyArray = function (keys){
350 var refKeyArray = [];
351 keyLabels.forEach(function (keyLabel){
352 var nk = keys.filter(function (k){
353 return keyLabel === k.label;
357 refKeyArray.push(nk[0]);
363 node.parent.refKey = getRefKeyArray(keyNodes);
368 * Service for wrapping leaf list yang element
371 function leafList(node) {
373 node.expanded = true;
375 node.toggleExpand = function () {
376 node.expanded = !node.expanded;
379 node.addListElem = function () {
383 node.value.push(newElement);
386 node.removeListElem = function (elem) {
387 node.value.splice(node.value.indexOf(elem), 1);
390 node.buildRequest = function (builder, req, module) {
392 labelWithModule = (module !== node.module ? node.module + ':' : '') + node.label;
394 for (var i = 0; i < node.value.length; i++) {
395 valueArray.push(node.value[i].value);
398 if (valueArray.length > 0) {
399 builder.insertPropertyToObj(req, labelWithModule, valueArray);
408 node.fill = function (name, array) {
409 var match = comparePropToElemByName(name, node.label),
414 for (var i = 0; i < array.length; i++) {
418 node.value.push(newLeafListItem);
425 node.clear = function () {
426 node.nodeType = constants.NODE_UI_DISPLAY;
430 node.isFilled = function () {
431 return node.value.length > 0;
436 * Service for wrapping choice yang element
439 function choice(node) {
441 node.expanded = true;
443 node.buildRequest = function (builder, req, module) {
447 added = node.choice.buildRequest(builder, req, module);
453 node.fill = function (name, data) {
455 nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
457 nodesToFill.forEach(function (child) {
458 var childFilled = child.fill(name, data);
464 filled = filled || childFilled;
473 node.clear = function () {
474 node.nodeType = constants.NODE_UI_DISPLAY;
482 node.isFilled = function () {
483 return node.choice !== null;
488 * Service for wrapping case yang element
491 function caseYang(node) {
493 node.buildRequest = function (builder, req, module) {
496 node.getChildren(null, null, constants.NODE_UI_DISPLAY).forEach(function (child) {
497 var childAdded = child.buildRequest(builder, req, module);
498 added = added || childAdded;
504 node.fill = function (name, data) {
506 nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
508 nodesToFill.forEach(function (child) {
509 var childFilled = child.fill(name, data);
510 filled = filled || childFilled;
516 node.clear = function () {
517 var nodesToClear = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
519 nodesToClear.forEach(function (child) {
524 node.isFilled = function () {
525 return node.getChildren(null, null, constants.NODE_UI_DISPLAY).some(function (child) {
526 return child.isFilled();
532 * Service for wrapping output yang element
535 function output(node) {
536 node.expanded = true;
538 node.buildRequest = function (builder, req) {
542 node.fill = function (name, data) {
543 var match = comparePropToElemByName(name, node.label),
544 nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
546 if (match && nodesToFill.length) {
547 nodesToFill.forEach(function (child) {
548 Object.keys(data).forEach(function(prop) {
549 child.fill(prop, data[prop]);
552 node.expanded = match;
558 node.clear = function () {
559 var nodesToClear = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
561 if (nodesToClear.length) {
562 nodesToClear.forEach(function (child) {
568 node.isFilled = function () {
569 return node.getChildren(null, null, constants.NODE_UI_DISPLAY).some(function (child) {
570 return child.isFilled();
576 // TODO: add service's description
577 function input(node) {
578 node.expanded = true;
580 node.buildRequest = function (builder, req, module) {
582 objToAdd = builder.createObj(),
583 builderNodes = node.getChildren(null, null, constants.NODE_UI_DISPLAY),
584 labelWithModule = (module !== node.module ? node.module + ':' : '') + node.label;
586 if (builderNodes.length) {
588 builderNodes.forEach(function (child) {
589 var childAdded = child.buildRequest(builder, objToAdd, node.module);
590 added = added || childAdded;
597 builder.insertPropertyToObj(req, labelWithModule, objToAdd);
603 node.fill = function (name, data) {
604 var match = comparePropToElemByName(name, node.label),
605 nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
607 if (match && nodesToFill.length) {
608 nodesToFill.forEach(function (child) {
609 Object.keys(data).forEach(function(prop) {
610 child.fill(prop, data[prop]);
613 node.expanded = match;
619 node.clear = function () {
620 var nodesToClear = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
622 if (nodesToClear.length) {
623 nodesToClear.forEach(function (child) {
629 node.isFilled = function () {
630 return node.getChildren(null, null, constants.NODE_UI_DISPLAY).some(function (child) {
631 return child.isFilled();
638 * Service for wrapping rpc yang element
642 node.expanded = true;
643 node.buildRequest = function (builder, req, module) {
645 objToAdd = builder.createObj(),
646 builderNodes = node.getChildren(null, null, constants.NODE_UI_DISPLAY),
647 labelWithModule = (module !== node.module ? node.module + ':' : '') + node.label;
649 if (builderNodes.length) {
650 builderNodes.forEach(function (child) {
651 var childAdded = child.buildRequest(builder, objToAdd, node.module);
652 added = added || childAdded;
656 objToAdd = constants.NULL_DATA;
660 builder.insertPropertyToObj(req, labelWithModule, objToAdd);
666 node.fill = function (name, data) {
667 var match = comparePropToElemByName(name, node.label),
668 nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
670 if (match && nodesToFill.length) {
671 nodesToFill.forEach(function (child) {
672 Object.keys(data).forEach(function(prop) {
673 child.fill(prop, data[prop]);
678 node.expanded = match;
683 node.clear = function () {
684 var nodesToClear = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
686 if (nodesToClear.length) {
687 nodesToClear.forEach(function (child) {
693 node.isFilled = function () {
694 return node.getChildren(null, null, constants.NODE_UI_DISPLAY).some(function (child) {
695 return child.isFilled();
702 * Service for wrapping container yang element
705 function container(node) {
706 node.expanded = false;
708 node.toggleExpand = function () {
709 node.expanded = !node.expanded;
712 node.buildRequest = function (builder, req, module) {
714 objToAdd = builder.createObj(),
715 builderNodes = node.getChildren(null, null, constants.NODE_UI_DISPLAY),
716 labelWithModule = (module !== node.module ? node.module + ':' : '') + node.label;
718 if (builderNodes.length) {
719 builderNodes.forEach(function (child) {
720 var childAdded = child.buildRequest(builder, objToAdd, node.module);
721 added = added || childAdded;
727 if (added && (checkEmptyContainer(node.parent ? node.parent.type : 'blanktype', objToAdd) ||
728 checkPresence(node))) {
729 builder.insertPropertyToObj(req, labelWithModule, objToAdd);
734 // TODO: add function's description
735 function checkPresence(containerNode) {
736 return containerNode.children.some(function (ch) {
737 return ch.type === 'presence';
741 // TODO: add function's description
742 function checkEmptyContainer(type, obj) { // TODO: absolete after when statement is implemented
743 return !!(type === 'case' || !$.isEmptyObject(objToAdd));
747 node.fill = function (name, data) {
748 var match = comparePropToElemByName(name, node.label),
749 nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
751 if (match && nodesToFill.length) {
752 nodesToFill.forEach(function (child) {
753 Object.keys(data).forEach(function(prop) {
754 child.fill(prop, data[prop]);
758 node.expanded = match;
764 node.clear = function () {
765 var nodesToClear = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
766 node.nodeType = constants.NODE_UI_DISPLAY;
768 if (nodesToClear.length) {
769 nodesToClear.forEach(function (child) {
775 node.isFilled = function () {
776 return node.getChildren(null, null, constants.NODE_UI_DISPLAY).some(function (child) {
777 return child.isFilled();
783 * Service for set patern restriction from yang element
786 function pattern(node) {
787 node.restrictions = [RestrictionsService.getReqexpValidationFnc(node.label)];
791 * Service for set range restriction from yang element
794 function range(node) {
795 node.restrictions = parseRestrictText(node.label);
799 * Service for set length restriction from yang element
802 function length(node) {
803 node.restrictions = parseRestrictText(node.label);
807 * Service for wrapping type yang element
810 function type(node) {
811 TypeWrapperService.wrapAll(node);
815 * Service for wrapping leaf yang element
818 function leaf(node) {
820 node.valueIsValid = true;
821 node.typeChild = node.getChildren('type')[0];
823 node.buildRequest = function (builder, req, module) {
824 var value = node.typeChild.getValue(),
825 labelWithModule = (module !== node.module ? node.module + ':' : '') + node.label;
828 EventDispatcherService.dispatch(constants.EV_FILL_PATH, node, value);
832 builder.insertPropertyToObj(req, labelWithModule, value);
839 node.fill = function (name, data) {
842 match = comparePropToElemByName(name, node.label);
844 node.value = data.toString();
845 if (node.typeChild) {
846 node.typeChild.fill(node.value);
852 node.clear = function () {
855 if (node.typeChild) {
856 node.typeChild.clear();
860 node.isFilled = function () {
861 var filled = node.typeChild.getValue() ? true : false;
865 node.checkValueType = function () {
866 node.valueIsValid = node.typeChild ? node.typeChild.check(node.value) : true;
869 node.isKey = function () {
870 return node.parent &&
871 node.parent.type === 'list' &&
872 node.parent.refKey && node.parent.refKey.indexOf(node) !== -1;
877 * Service for wrapping single node
880 function wrap(node) {
881 if (service.hasOwnProperty(node.type)) {
882 service[node.type](node);
887 * Main service for wrapping nodes
890 function wrapAll(node) {
892 node.children.forEach(function (child) {
893 service.wrapAll(child);
897 // TODO: add service's description
898 function checkKeyDuplicity(listData, refKey) {
899 return checkListElemKeys(listData, refKey);
902 // TODO: add function's description
903 function comparePropToElemByName(propName, elemName) {
905 // return propName === elemName; // TODO also check by namespace - redundancy?
907 // TODO also check by namespace - redundancy?
908 return (propName.indexOf(':') > -1 ? propName.split(':')[1] : propName) === elemName;
911 // TODO: add function's description
912 function equalArrays(arrA, arrB) {
913 var match = (arrA.length === arrB.length) && arrA.length > 0;
917 while (i < arrA.length && match) {
918 var valMatch = arrA[i] === arrB[i];
919 match = match && valMatch;
926 // TODO: add function's description
927 function equalListElems(listElemA, listElemB, refKey) {
928 var keyValuesA = getKeyArrayValues(listElemA, refKey),
929 keyValuesB = getKeyArrayValues(listElemB, refKey);
931 return equalArrays(keyValuesA, keyValuesB);
933 // TODO: add function's description
934 function getKeyValue(data, label, module) {
935 if (data && data.hasOwnProperty(label)) {
937 } else if (data && data.hasOwnProperty(module + ':' + label)) {
938 return data[module + ':' + label];
944 // TODO: add function's description
945 function getKeyArrayValues(data, refKey) {
946 return refKey.map(function (key) {
947 return getKeyValue(data, key.label, key.module);
948 }).filter(function (item) {
949 return item !== null;
954 // TODO: add function's description
955 function checkListElemKeys(listData, refKey) {
956 var doubleKeyIndexes = [],
959 listData.forEach(function (item, index) {
960 var duplitactes = checkedElems.filter(function (checked) {
961 var isDuplicate = equalListElems(item, checked.item, refKey);
962 if (isDuplicate && doubleKeyIndexes.indexOf(checked.index) === -1) {
963 doubleKeyIndexes.push(checked.index);
968 if (duplitactes.length) {
969 // item is already in checkedElems so we don't need to push it again
970 doubleKeyIndexes.push(index);
972 checkedElems.push({ index: index, item: item });
976 return doubleKeyIndexes;
979 // TODO: add function's description
980 function parseRestrictText(text) {
981 return text.split('|').map(function (elem) {
982 var subElems = elem.split('..');
983 return subElems.length === 1 ? RestrictionsService.getEqualsFnc(subElems[0]) :
984 RestrictionsService.getMinMaxFnc(subElems[0], subElems[1]);
988 // TODO: add function's description
989 function getTypes(node) {
992 var getTypesRecursive = function (node, types) {
995 node.getChildren('type').forEach(function (child) {
996 getTypesRecursive(child, types);
1000 node.getChildren('type').forEach(function (child) {
1001 getTypesRecursive(child, types);
1008 NodeWrapperService.$inject = ['constants', 'RequestBuilderService', 'RestrictionsService', 'TypeWrapperService',
1009 'ListFilteringService', 'EventDispatcherService', 'FilterNodeWrapperService'];
1011 return NodeWrapperService;