UNPKG

@sap/odata-v4

Version:

OData V4.0 server library

113 lines (93 loc) 3.56 kB
'use strict'; 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;