@mnakhla/rocketrml
Version:
This is a forked rocketrml mapper for the RDF mapping language
412 lines (380 loc) • 11.6 kB
JavaScript
const fs = require('fs');
const dom = require('@xmldom/xmldom').DOMParser;
const prefixhelper = require('../helper/prefixHelper');
const functionHelper = require('../function/function');
const subjFunctionExecution = async (
Parser,
functionMap,
prefixes,
data,
index,
options,
) => {
const functionValue = functionMap.functionValue;
const definition = functionHelper.findDefinition(
data,
functionValue.predicateObjectMap,
prefixes,
);
const parameters = functionHelper.findParameters(
data,
functionValue.predicateObjectMap,
prefixes,
);
const params = await calculateParams(Parser, parameters, index, options);
return functionHelper.executeFunction(definition, params, options);
};
const calculateParams = async (
Parser,
parameters,
index,
options,
data,
prefixes,
) => {
const result = [];
await Promise.all(
parameters.map(async (p) => {
let temp = [];
if (p.type === 'constant') {
temp.push(p.data);
} else if (p.type === 'reference') {
temp = getDataFromParser(Parser, index, p.data, options);
} else if (p.type === 'template') {
let resolveTemplate = p.data;
const templateRegex = /(?:\{(.*?)\})/g;
let match = templateRegex.exec(p.data);
while (match) {
// Retrieve all matches of the regex group {myvar}
const variableValue = getDataFromParser(
Parser,
index,
match[1],
options,
);
resolveTemplate = resolveTemplate.replace(
`{${match[1]}}`,
variableValue.toString(),
);
match = templateRegex.exec(p.data);
}
temp.push(resolveTemplate);
} else if (p.type === 'functionValue') {
const definition = functionHelper.findDefinition(
data,
p.data.predicateObjectMap,
prefixes,
);
const functionParameters = functionHelper.findParameters(
data,
p.data.predicateObjectMap,
prefixes,
);
const calcParameters = await calculateParams(
Parser,
functionParameters,
index,
options,
);
const res = await functionHelper.executeFunction(
definition,
calcParameters,
options,
);
temp.push(res);
}
if (temp && temp.length === 1) {
temp = temp[0];
}
result[p.predicate] = temp;
result.push(temp);
}),
);
return result;
};
const cleanString = (path) => {
if (path.startsWith('.') || path.startsWith('/')) {
path = path.substr(1);
}
return path;
};
const setObjPredicate = (obj, predicate, dataSet, language, datatype) => {
dataSet = addArray(dataSet);
for (const data of dataSet) {
if (data === undefined) {
// eslint-disable-next-line no-continue
continue;
}
if (datatype) {
datatype = datatype['@id'] ? datatype['@id'] : datatype;
}
if (language || datatype) {
if (obj[predicate]) {
const newObj = {
'@type': datatype,
'@value': data,
'@language': language,
};
if (typeof obj[predicate] === 'object' && obj[predicate]['@value']) {
const temp = obj[predicate];
obj[predicate] = [];
obj[predicate].push(temp);
obj[predicate].push(newObj);
} else if (Array.isArray(obj[predicate])) {
obj[predicate].push(newObj);
} else {
const temp = {
'@value': obj[predicate],
};
obj[predicate] = [];
obj[predicate].push(temp);
obj[predicate].push(newObj);
}
} else {
obj[predicate] = {};
obj[predicate]['@value'] = data;
obj[predicate]['@type'] = datatype;
obj[predicate]['@language'] = language;
}
} else if (obj[predicate]) {
obj[predicate] = addArray(obj[predicate]);
obj[predicate].push(data);
} else {
obj[predicate] = data;
}
}
};
const locations = (substring, string) => {
const a = [];
let i = -1;
i = string.indexOf(substring, i + 1);
while (i >= 0) {
a.push(i);
i = string.indexOf(substring, i + 1);
}
return a;
};
const getConstant = (constant, prefixes) => {
if (constant['@id']) {
return prefixhelper.replacePrefixWithURL(constant['@id'], prefixes);
}
return constant;
};
const cutArray = (arr) => {
if (arr.length === 1) {
arr = arr[0];
}
return arr;
};
const addArray = (arr) => {
if (!Array.isArray(arr)) {
arr = [arr];
}
return arr;
};
const addToObj = (obj, pred, data) => {
if (obj[pred]) {
if (!Array.isArray(obj[pred])) {
const temp = obj[pred];
obj[pred] = [];
obj[pred].push(temp);
}
obj[pred].push(data);
} else {
obj[pred] = data;
}
};
const addToObjInId = (obj, pred, data) => {
if (obj[pred]) {
if (!Array.isArray(obj[pred])) {
const temp = obj[pred];
obj[pred] = [];
obj[pred].push(temp);
}
obj[pred].push({ '@id': data });
} else {
obj[pred] = { '@id': data };
}
};
const readFileStringSimple = (source, options) => {
let string;
if (options && options.inputFiles) {
if (!options.inputFiles[source]) {
throw `File ${source} not specified!`;
}
string = options.inputFiles[source];
} else {
consoleLogIf('Reading file...', options);
string = fs.readFileSync(source, 'utf-8');
}
return string;
};
const readFileJSONSimple = (source, options) => {
const jsonStr = readFileStringSimple(source, options);
const jsonObj = JSON.parse(jsonStr);
return jsonObj;
};
const readFileXMLSimple = (source, options) => {
let xmlStr = readFileStringSimple(source, options);
if (options && options.removeNameSpace) {
// remove namespace from data
consoleLogIf('Removing namespace..', options);
for (const key in options.removeNameSpace) {
const toDelete = `${key}="${options.removeNameSpace[key]}"`;
xmlStr = xmlStr.replace(toDelete, '');
}
}
consoleLogIf('Creating DOM...', options);
const doc = new dom().parseFromString(xmlStr);
consoleLogIf('DOM created!', options);
return doc;
};
const withCache = (fn, source, options) => {
if (!options.cache) {
options.cache = {};
}
if (options.cache[source]) {
consoleLogIf(`Reading from cache.. : ${source}`, options);
return options.cache[source];
}
const result = fn(source, options);
options.cache[source] = result;
return result;
};
const readFileJSON = (source, options) =>
withCache(readFileJSONSimple, source, options);
const readFileXML = (source, options) =>
withCache(readFileXMLSimple, source, options);
const readFileCSV = (source, options) =>
withCache(readFileStringSimple, source, options);
const readFileString = (source, options) =>
withCache(readFileStringSimple, source, options);
/* const pattern = new RegExp('^(https?:\\/\\/)?'
+ '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'
+ '((\\d{1,3}\\.){3}\\d{1,3}))'
+ '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'
+ '(\\?[;&a-z\\d%_.~+=-]*)?'
+ '(\\#[-a-z\\d_]*)?$', 'i'); */
const isURL = (str) => /\w+:(\/\/)[^\s]+/.test(str);
const addBase = (str, prefixes) => prefixes.base + str;
const escapeChar = (str) => {
str = replaceAll(str, '\\\\{', '#replaceOpenBr#');
str = replaceAll(str, '\\\\}', '#replaceClosingBr#');
return str;
};
const allPossibleCases = (arr) => {
if (arr.length === 0) {
return [];
}
if (arr.length === 1) {
return arr[0].map((e) => [e]);
}
const result = [];
const allCasesOfRest = allPossibleCases(arr.slice(1)); // recur with the rest of array
for (let i = 0; i < allCasesOfRest.length; i++) {
for (let j = 0; j < arr[0].length; j++) {
result.push([arr[0][j], ...allCasesOfRest[i]]);
}
}
return result;
};
const replaceEscapedChar = (str) => {
str = replaceAll(str, '#replaceOpenBr#', '{');
str = replaceAll(str, '#replaceClosingBr#', '}');
return str;
};
const replaceAll = (str, search, replacement) =>
str.replace(new RegExp(search, 'g'), replacement);
const toURIComponent = (str) => {
str = encodeURIComponent(str);
str = str.replace(/\(/g, '%28');
str = str.replace(/\)/g, '%29');
return str;
};
const createMeta = (obj) => {
if (!obj) {
obj = {};
}
if (!obj.$metadata) {
obj.$metadata = {};
}
if (!obj.$metadata.inputFiles) {
obj.$metadata.inputFiles = {};
}
return obj;
};
const consoleLogIf = (string, options) => {
if (options && options.verbose) {
// eslint-disable-next-line no-console
console.log(string);
}
};
const getPredicate = (mapping, prefixes) => {
let predicate;
if (mapping.predicate) {
if (Array.isArray(mapping.predicate)) {
predicate = [];
mapping.predicate.forEach((pre) => {
predicate.push(prefixhelper.replacePrefixWithURL(pre['@id'], prefixes));
});
} else {
predicate = prefixhelper.replacePrefixWithURL(
mapping.predicate['@id'],
prefixes,
);
}
} else if (mapping.predicateMap) {
// in predicateMap only constant allowed
if (Array.isArray(mapping.predicateMap)) {
predicate = [];
for (let temp of mapping.predicateMap) {
temp = temp.constant['@id'];
predicate.push(temp);
}
} else {
predicate = mapping.predicateMap;
predicate = getConstant(predicate.constant, prefixes);
}
} else {
throw 'Error: no predicate specified!';
}
return predicate;
};
const intersection = (arrOfArr) =>
arrOfArr.reduce((a, b) => a.filter((c) => b.includes(c)));
const getDataFromParser = (Parser, index, query, options) => {
let values = Parser.getData(index, query);
if (options.ignoreEmptyStrings === true) {
values = values.filter((v) => v.trim() !== '');
}
if (options.ignoreValues) {
values = values.filter((v) => !options.ignoreValues.includes(v));
}
return values;
};
module.exports.consoleLogIf = consoleLogIf;
module.exports.escapeChar = escapeChar;
module.exports.createMeta = createMeta;
module.exports.allPossibleCases = allPossibleCases;
module.exports.toURIComponent = toURIComponent;
module.exports.replaceEscapedChar = replaceEscapedChar;
module.exports.subjFunctionExecution = subjFunctionExecution;
module.exports.calculateParams = calculateParams;
module.exports.cleanString = cleanString;
module.exports.locations = locations;
module.exports.cutArray = cutArray;
module.exports.addArray = addArray;
module.exports.addToObj = addToObj;
module.exports.addToObjInId = addToObjInId;
module.exports.readFileJSON = readFileJSON;
module.exports.readFileCSV = readFileCSV;
module.exports.readFileXML = readFileXML;
module.exports.readFileString = readFileString;
module.exports.isURL = isURL;
module.exports.addBase = addBase;
module.exports.getConstant = getConstant;
module.exports.setObjPredicate = setObjPredicate;
// module.exports.getDatatypeFromPath = getDatatypeFromPath;
module.exports.getPredicate = getPredicate;
module.exports.intersection = intersection;
module.exports.getDataFromParser = getDataFromParser;