@sap/odata-v4
Version:
OData V4.0 server library
113 lines (93 loc) • 3.56 kB
JavaScript
;
const UriSemanticError = require('../errors/UriSemanticError');
const KeyValueParser = require('./KeyValueParser');
const TokenKind = require('./UriTokenizer').TokenKind;
/**
* Parsing function parameters of an uri.
*
* @extends KeyValueParser
*/
class FunctionParameterParser extends KeyValueParser {
/**
* Creates an instance of FunctionParameterParser.
* @param {Edm} edm The Entity Data Model
* @param {Object} aliases Alias definitions
*/
constructor(edm, aliases) {
super(edm, aliases);
this._function = null;
this._uriParameters = [];
}
/**
* Parse the function parameters in the url.
*
* @param {string} boundFunctionOrFunctionImportName Name of the bound function or of the function import
* @param {EdmFunction[]} functions array of functions
* @param {UriTokenizer} tokenizer The current tokenizer
* @param {Function} getOverloadingFunctionFn Callback function how to get the overloaded function.
* The callback will be called with a Map object.
* @returns {UriParameter[]} an array with found parameters
*/
parse(boundFunctionOrFunctionImportName, functions, tokenizer, getOverloadingFunctionFn) {
this._function = null;
this._uriParameters = [];
if (!tokenizer.next(TokenKind.OPEN)) {
return null;
}
const testFunctionExists = (func, visitedParameters) => {
if (!func) {
throw new UriSemanticError(UriSemanticError.Message.FUNCTION_NOT_FOUND,
boundFunctionOrFunctionImportName, Array.from(visitedParameters.keys()).join(','));
}
};
if (tokenizer.next(TokenKind.CLOSE)) {
this._function = getOverloadingFunctionFn(new Map());
testFunctionExists(this._function, []);
return this._uriParameters;
}
const allAvailableParameterTypes = functions.reduce((prev, current) => {
current.getParameters().forEach(p => {
const name = p.getName();
const type = p.getType();
if (!prev.has(name)) {
prev.set(name, new Set());
}
if (p.isNullable()) {
prev.get(name).add('nullable');
}
return prev.get(name).add(type);
});
return prev;
}, new Map());
const visitedParameters = super.parse(
tokenizer,
parameterName => allAvailableParameterTypes.get(parameterName),
parameterTypeSet => Array.from(parameterTypeSet.values())
);
tokenizer.requireNext(TokenKind.CLOSE);
this._function = getOverloadingFunctionFn(visitedParameters);
testFunctionExists(this._function, visitedParameters);
visitedParameters.forEach((value, key) => {
const parameter = this._function.getParameter(key);
this._uriParameters.push(value.setEdmRef(parameter));
});
return this._uriParameters;
}
/**
* Returns the current overloaded function.
*
* @returns {?EdmFunction} the current overloaded function
*/
getFunction() {
return this._function;
}
/**
* Returns the current found function parameters.
*
* @returns {UriParameter[]} the current found function parameters
*/
getParameters() {
return this._uriParameters;
}
}
module.exports = FunctionParameterParser;