2 * ============LICENSE_START========================================================================
3 * ONAP : ccsdk feature sdnr wt odlux
4 * =================================================================================================
5 * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
6 * =================================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8 * in compliance with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software distributed under the License
13 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14 * or implied. See the License for the specific language governing permissions and limitations under
16 * ============LICENSE_END==========================================================================
19 import { YangRange, Operator, ViewElementNumber, ViewElementString, isViewElementNumber, isViewElementString } from '../models/uiModels';
21 export type validated = { isValid: boolean; error?: string };
23 export type validatedRange = { isValid: boolean; error?: string };
25 const rangeErrorStartNumber = 'The entered number must be';
26 const rangeErrorInnerMinTextNumber = 'greater or equals than';
27 const rangeErrorInnerMaxTextNumber = 'less or equals than';
28 const rangeErrorEndTextNumber = '.';
30 const rangeErrorStartString = 'The entered text must have';
31 const rangeErrorInnerMinTextString = 'no more than';
32 const rangeErrorInnerMaxTextString = 'less than';
33 const rangeErrorEndTextString = ' characters.';
35 let errorMessageStart = '';
36 let errorMessageMiddleMinPart = '';
37 let errorMessageMiddleMaxPart = '';
38 let errorMessageEnd = '';
40 const isYangRange = (val: YangRange | Operator<YangRange>): val is YangRange => (val as YangRange).min !== undefined;
42 const isYangOperator = (val: YangRange | Operator<YangRange>): val is Operator<YangRange> => (val as Operator<YangRange>).operation !== undefined;
44 const isRegExp = (val: RegExp | Operator<RegExp>): val is RegExp => (val as RegExp).source !== undefined;
46 const isRegExpOperator = (val: RegExp | Operator<RegExp>): val is Operator<RegExp> => (val as Operator<RegExp>).operation !== undefined;
48 const getRangeErrorMessagesRecursively = (value: Operator<YangRange>, data: number): string[] => {
49 let currentIteration: string[] = [];
51 // iterate over all elements
52 for (let i = 0; i < value.arguments.length; i++) {
53 const element = value.arguments[i];
58 let isNumberCorrect = false;
60 if (isYangRange(element)) {
62 //check found min values
63 if (!isNaN(element.min)) {
64 if (data < element.min) {
67 isNumberCorrect = true;
71 // check found max values
72 if (!isNaN(element.max)) {
73 if (data > element.max) {
76 isNumberCorrect = true;
80 // construct error messages
81 if (min != undefined) {
82 currentIteration.push(`${value.operation.toLocaleLowerCase()} ${errorMessageMiddleMinPart} ${min}`);
83 } else if (max != undefined) {
84 currentIteration.push(`${value.operation.toLocaleLowerCase()} ${errorMessageMiddleMaxPart} ${max}`);
88 } else if (isYangOperator(element)) {
90 //get error_message from expression
91 const result = getRangeErrorMessagesRecursively(element, data);
92 if (result.length === 0) {
93 isNumberCorrect = true;
95 currentIteration = currentIteration.concat(result);
98 // if its an OR operation, the number has been checked and min/max are empty (thus not violated)
99 // delete everything found (because at least one found is correct, therefore all are correct) and break from loop
100 if (min === undefined && max === undefined && isNumberCorrect && value.operation === 'OR') {
102 currentIteration.splice(0, currentIteration.length);
107 return currentIteration;
110 const createStartMessage = (element: string) => {
111 //remove leading or or and from text
112 if (element.startsWith('and')) {
113 element = element.replace('and', '');
114 } else if (element.startsWith('or')) {
115 element = element.replace('or', '');
117 return `${errorMessageStart} ${element}`;
120 const getRangeErrorMessages = (value: Operator<YangRange>, data: number): string => {
122 const currentIteration = getRangeErrorMessagesRecursively(value, data);
124 // build complete error message from found parts
125 let errorMessage = '';
126 if (currentIteration.length > 1) {
128 currentIteration.forEach((element, index) => {
130 errorMessage = createStartMessage(element);
131 } else if (index === currentIteration.length - 1) {
132 errorMessage += ` ${element}${errorMessageEnd}`;
134 errorMessage += `, ${element}`;
137 } else if (currentIteration.length == 1) {
138 errorMessage = `${createStartMessage(currentIteration[0])}${errorMessageEnd}`;
144 export const checkRange = (element: ViewElementNumber | ViewElementString, data: number): string => {
147 let expression = undefined;
149 if (isViewElementString(element)) {
150 expression = element.length;
152 errorMessageStart = rangeErrorStartString;
153 errorMessageMiddleMaxPart = rangeErrorInnerMaxTextString;
154 errorMessageMiddleMinPart = rangeErrorInnerMinTextString;
155 errorMessageEnd = rangeErrorEndTextString;
157 } else if (isViewElementNumber(element)) {
158 expression = element.range;
160 errorMessageStart = rangeErrorStartNumber;
161 errorMessageMiddleMaxPart = rangeErrorInnerMaxTextNumber;
162 errorMessageMiddleMinPart = rangeErrorInnerMinTextNumber;
163 errorMessageEnd = rangeErrorEndTextNumber;
167 if (isYangOperator(expression)) {
169 const errorMessage = getRangeErrorMessages(expression, data);
173 if (isYangRange(expression)) {
175 if (!isNaN(expression.min)) {
176 if (number < expression.min) {
177 return `${errorMessageStart} ${errorMessageMiddleMinPart} ${expression.min}${errorMessageEnd}`;
181 if (!isNaN(expression.max)) {
182 if (number > expression.max) {
183 return `${errorMessageStart} ${errorMessageMiddleMaxPart} ${expression.max}${errorMessageEnd}`;
192 const getRegexRecursively = (value: Operator<RegExp>, data: string): boolean[] => {
193 let currentItteration: boolean[] = [];
194 for (let i = 0; i < value.arguments.length; i++) {
195 const element = value.arguments[i];
196 if (isRegExp(element)) {
197 // if regex is found, add it to list
198 currentItteration.push(element.test(data));
199 } else if (isRegExpOperator(element)) {
200 //if RegexExpression is found, try to get regex from it
201 currentItteration = currentItteration.concat(getRegexRecursively(element, data));
205 if (value.operation === 'OR') {
206 // if one is true, all are true, all found items can be discarded
207 let result = currentItteration.find(element => element);
212 return currentItteration;
215 const isPatternValid = (value: Operator<RegExp>, data: string): boolean => {
217 const result = getRegexRecursively(value, data);
219 if (value.operation === 'AND') {
220 // if AND operation is executed...
221 // no element can be false
222 const check = result.find(element => element !== true);
228 // if OR operation is executed...
229 // ... just one element must be true
230 const check = result.find(element => element === true);
239 export const checkPattern = (expression: RegExp | Operator<RegExp> | undefined, data: string): validated => {
242 if (isRegExp(expression)) {
243 const isValid = expression.test(data);
245 return { isValid: isValid, error: 'The input is in a wrong format.' };
247 } else if (isRegExpOperator(expression)) {
248 const result = isPatternValid(expression, data);
251 return { isValid: false, error: 'The input is in a wrong format.' };
256 return { isValid: true };