X-Git-Url: https://osm.etsi.org/gitweb/?p=osm%2FUI.git;a=blobdiff_plain;f=skyquake%2Fplugins%2Fcomposer%2Fsrc%2Fsrc%2Flibraries%2Futils.js;h=75afab33a17fb9766b635ea4a95656fbfe6aa84e;hp=01e6675b6907e6f205ca0f6860048d98d5efdd8a;hb=132f9b77e1c32b82eb1c27cea048a5c1f2bfcb56;hpb=e29efc315df33d546237e270470916e26df391d6 diff --git a/skyquake/plugins/composer/src/src/libraries/utils.js b/skyquake/plugins/composer/src/src/libraries/utils.js index 01e6675b6..75afab33a 100644 --- a/skyquake/plugins/composer/src/src/libraries/utils.js +++ b/skyquake/plugins/composer/src/src/libraries/utils.js @@ -1,5 +1,5 @@ /* - * + * * Copyright 2016 RIFT.IO Inc * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -71,7 +71,7 @@ export default { }, obj); resolvedObj[name] = value; }, - updatePathValue(obj, path, value) { + updatePathValue(obj, path, value, isCase) { // todo: replace implementation of assignPathValue with this impl and // remove updatePathValue (only need one function, not both) // same as assignPathValue except removes property if value is undefined @@ -92,18 +92,27 @@ export default { if (isArray) { r[p] = r[p].filter((d, i) => i !== index); } else { - delete r[p][name]; + if(isCase) { + delete r[name]; + } else { + delete r[p][name]; + } } } - return r[p]; + if(isCase) { + return r; + } else { + return r[p]; + } + }, obj); if (!isRemove) { resolvedObj[name] = value; } }, - removePathValue(obj, path) { + removePathValue(obj, path, isCase) { // note updatePathValue removes value if third argument is undefined - return this.updatePathValue(obj, path); + return this.updatePathValue(obj, path, undefined, isCase); }, suffixAsInteger: (field) => { @@ -114,6 +123,248 @@ export default { }; }, - toBiggestValue: (maxIndex, curIndex) => Math.max(maxIndex, curIndex) + toBiggestValue: (maxIndex, curIndex) => Math.max(maxIndex, curIndex), + + isRelativePath (path) { + if (path.split('/')[0] == '..') { + return true; + } + return false; + }, + + getResults (topLevelObject, pathArray) { + let objectCopy = _.cloneDeep(topLevelObject); + let i = pathArray.length; + let results = []; + + while(pathArray[pathArray.length - i]) { + if (_.isArray(objectCopy[pathArray[pathArray.length - i]])) { + if (i == 2) { + results = _.map(objectCopy[pathArray[pathArray.length - i]], pathArray[pathArray.length - 1]); + } else { + objectCopy = objectCopy[pathArray[pathArray.length - i]]; + } + } else if (_.isArray(objectCopy)) { + objectCopy.map((object) => { + if (_.isArray(object[pathArray[pathArray.length - i]])) { + if (i == 2) { + results = results.concat(_.map(object[pathArray[pathArray.length - i]], pathArray[pathArray.length - 1])); + } + } + }) + } + i--; + } + + return results; + }, + + getAbsoluteResults (topLevelObject, pathArray) { + let i = pathArray.length; + let objectCopy = _.cloneDeep(topLevelObject); + let results = []; + + let fragment = pathArray[pathArray.length - i] + + while (fragment) { + if (i == 1) { + // last fragment + if (_.isArray(objectCopy)) { + // results will be obtained from a map + results = _.map(objectCopy, fragment); + } else { + // object + if (fragment.match(/\[.*\]/g)) { + // contains a predicate + // shouldn't reach here + console.log('Something went wrong while resolving a leafref. Reached a leaf with predicate.'); + } else { + // contains no predicate + results.push(objectCopy[fragment]); + } + } + } else { + if (_.isArray(objectCopy)) { + // is array + objectCopy = _.map(objectCopy, fragment); + + // If any of the deeper object is an array, flatten the entire list. + // This would usually be a bad leafref going out of its scope. + // Log it too + for (let i = 0; i < objectCopy.length; i++) { + if (_.isArray(objectCopy[i])) { + objectCopy = _.flatten(objectCopy); + console.log('This might be a bad leafref. Verify with backend team.') + break; + } + } + } else { + // is object + if (fragment.match(/\[.*\]/g)) { + // contains a predicate + let predicateStr = fragment.match(/\[.*\]/g)[0]; + // Clip leading [ and trailing ] + predicateStr = predicateStr.substr(1, predicateStr.length - 2); + const predicateKeyValue = predicateStr.split('='); + const predicateKey = predicateKeyValue[0]; + const predicateValue = predicateKeyValue[1]; + // get key for object to search into + let key = fragment.split('[')[0]; + let searchObject = {}; + searchObject[predicateKey] = predicateValue; + let found = _.find(objectCopy[key], searchObject); + if (found) { + objectCopy = found; + } else { + // check for numerical value + if (predicateValue != "" && + predicateValue != null && + predicateValue != NaN && + predicateValue != Infinity && + predicateValue != -Infinity) { + let numericalPredicateValue = _.toNumber(predicateValue); + if (_.isNumber(numericalPredicateValue)) { + searchObject[predicateKey] = numericalPredicateValue; + found = _.find(objectCopy[key], searchObject); + } + } + if (found) { + objectCopy = found; + } else { + return []; + } + } + } else { + // contains no predicate + objectCopy = objectCopy[fragment]; + if (!objectCopy) { + // contains no value + break; + } + } + } + } + i--; + fragment = pathArray[pathArray.length - i]; + } + + return results; + }, + + resolveCurrentPredicate (leafRefPath, container, pathCopy) { + if (leafRefPath.indexOf('current()') != -1) { + // contains current + + // Get the relative path from current + let relativePath = leafRefPath.match("current\\(\\)\/(.*)\]"); + let relativePathArray = relativePath[1].split('/'); + + while (relativePathArray[0] == '..') { + pathCopy.pop(); + relativePathArray.shift(); + } + + // Supports only one relative path up + // To support deeper paths, will need to massage the string more + // i.e. change '/'' to '.' + const searchPath = pathCopy.join('.').concat('.', relativePathArray[0]); + const searchValue = this.resolvePath(container.model, searchPath); + + const predicateStr = leafRefPath.match("(current.*)\]")[1]; + leafRefPath = leafRefPath.replace(predicateStr, searchValue); + } + return leafRefPath; + }, + + resolveLeafRefPath (catalogs, leafRefPath, fieldKey, path, container) { + let pathCopy = _.clone(path); + // Strip any prefixes + let leafRefPathCopy = leafRefPath.replace(/[\w\d]*:/g, ''); + // Strip any spaces + leafRefPathCopy = leafRefPathCopy.replace(/\s/g, ''); + + // resolve any current paths + leafRefPathCopy = this.resolveCurrentPredicate(leafRefPathCopy, container, pathCopy); + + // Split on delimiter (/) + const pathArray = leafRefPathCopy.split('/'); + let fieldKeyArray = fieldKey.split(':'); + let results = []; + // Check if relative path or not + // TODO: Below works but + // better to convert the pathCopy to absolute/rooted path + // and use the absolute module instead + if (this.isRelativePath(leafRefPathCopy)) { + let i = pathArray.length; + while (pathArray[pathArray.length - i] == '..') { + fieldKeyArray.splice(-1, 1); + if (!isNaN(Number(fieldKeyArray[fieldKeyArray.length - 1]))) { + // found a number, so an index. strip it + fieldKeyArray.splice(-1, 1); + } + i--; + } + + // traversed all .. - now traverse down + if (fieldKeyArray.length == 1) { + for (let key in catalogs) { + for (let subKey in catalogs[key]) { + let found = _.find(catalogs[key][subKey], {id: fieldKeyArray[0]}); + if (found) { + results = this.getAbsoluteResults(found, pathArray.splice(-i, i)); + return results; + } + } + } + } else if (fieldKeyArray.length == 2) { + for (let key in catalogs) { + for (let subKey in catalogs[key]) { + let found = _.find(catalogs[key][subKey], {id: fieldKeyArray[0]}); + if (found) { + for (let foundKey in found) { + // let topLevel = _.find(found[foundKey], {id: fieldKeyArray[1]}); + if (foundKey == fieldKeyArray[1]) { + results = this.getAbsoluteResults(found[foundKey], pathArray.splice(-i, i)); + return results; + } + } + } + } + } + } else if (fieldKeyArray.length == 3) { + for (let key in catalogs) { + for (let subKey in catalogs[key]) { + let found = _.find(catalogs[key][subKey], {id: fieldKeyArray[0]}); + if (found) { + for (let foundKey in found) { + let topLevel = _.find(found[foundKey], {id: fieldKeyArray[1]}); + if (topLevel) { + results = this.getAbsoluteResults(topLevel, pathArray.splice(-i, i)); + return results; + } + } + } + } + } + } else { + // not supported - too many levels deep ... maybe some day + console.log('The relative path is from a node too many levels deep from root. This is not supported at the time'); + } + } else { + // absolute path + if (pathArray[0] == "") { + pathArray.splice(0, 1); + } + + let catalogKey = pathArray[0]; + let topLevelObject = {}; + + topLevelObject[catalogKey] = catalogs[catalogKey]; + + results = this.getAbsoluteResults(topLevelObject, pathArray); + + return results; + } + } }