Michael Lando | dd60339 | 2017-07-12 00:54:52 +0300 | [diff] [blame] | 1 | /*- |
| 2 | * ============LICENSE_START======================================================= |
| 3 | * SDC |
| 4 | * ================================================================================ |
| 5 | * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. |
| 6 | * ================================================================================ |
| 7 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 8 | * you may not use this file except in compliance with the License. |
| 9 | * You may obtain a copy of the License at |
| 10 | * |
| 11 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 12 | * |
| 13 | * Unless required by applicable law or agreed to in writing, software |
| 14 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 16 | * See the License for the specific language governing permissions and |
| 17 | * limitations under the License. |
| 18 | * ============LICENSE_END========================================================= |
| 19 | */ |
| 20 | |
Michael Lando | a544510 | 2018-03-04 14:53:33 +0200 | [diff] [blame] | 21 | import * as _ from "lodash"; |
| 22 | |
Michael Lando | ed64b5e | 2017-06-09 03:19:04 +0300 | [diff] [blame] | 23 | class basePattern { |
| 24 | pattern:RegExp; |
| 25 | base:number; |
| 26 | |
| 27 | constructor(pattern:RegExp, base:number) { |
| 28 | this.pattern = pattern; |
| 29 | this.base = base; |
| 30 | } |
| 31 | } |
| 32 | |
| 33 | export interface IMapRegex { |
| 34 | integer:RegExp; |
| 35 | boolean:RegExp; |
| 36 | float:RegExp; |
| 37 | string:RegExp; |
| 38 | } |
| 39 | |
| 40 | export class ValidationUtils { |
| 41 | |
| 42 | static '$inject' = [ |
| 43 | 'IntegerNoLeadingZeroValidationPattern', |
| 44 | 'FloatValidationPattern', |
| 45 | 'CommentValidationPattern', |
| 46 | 'BooleanValidationPattern', |
| 47 | 'NumberValidationPattern', |
| 48 | 'LabelValidationPattern', |
| 49 | ]; |
| 50 | private trueRegex:string = '[t][r][u][e]|[t]|[o][n]|[y]|[y][e][s]|[1]'; |
| 51 | private falseRegex:string = '[f][a][l][s][e]|[f]|[o][f][f]|[n]|[n][o]|[0]'; |
| 52 | private heatBooleanValidationPattern:RegExp = new RegExp('^(' + this.trueRegex + '|' + this.falseRegex + ')$'); |
| 53 | |
| 54 | |
| 55 | constructor(private IntegerNoLeadingZeroValidationPattern:RegExp, |
| 56 | private FloatValidationPattern:RegExp, |
| 57 | private CommentValidationPattern:RegExp, |
| 58 | private BooleanValidationPattern:RegExp, |
| 59 | private NumberValidationPattern:RegExp, |
| 60 | private LabelValidationPattern:RegExp) { |
| 61 | } |
| 62 | |
| 63 | public stripAndSanitize(text:string):string { |
| 64 | if (!text) { |
| 65 | return null; |
| 66 | } |
| 67 | return text.replace(/\s+/g, ' ').replace(/%[A-Fa-f0-9]{2}/g, '').trim(); |
| 68 | } |
| 69 | |
| 70 | public getValidationPattern = (validationType:string, parameterType?:string):RegExp => { |
| 71 | switch (validationType) { |
| 72 | case 'integer': |
| 73 | return this.IntegerNoLeadingZeroValidationPattern; |
| 74 | case 'float': |
| 75 | return this.FloatValidationPattern; |
| 76 | case 'number': |
| 77 | return this.NumberValidationPattern; |
| 78 | case 'string': |
| 79 | return this.CommentValidationPattern; |
| 80 | case 'boolean': |
| 81 | { |
| 82 | //Bug Fix DE197437 [Patch]Mismatch between BE to FE regarding supported characters in Boolean filed |
| 83 | if (parameterType && parameterType === 'heat') { |
| 84 | return this.heatBooleanValidationPattern; |
| 85 | } |
| 86 | else { |
| 87 | return this.BooleanValidationPattern; |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | case 'label': |
| 92 | return this.LabelValidationPattern; |
| 93 | case 'category': |
| 94 | return this.LabelValidationPattern; |
| 95 | default : |
| 96 | return null; |
| 97 | } |
| 98 | }; |
| 99 | |
| 100 | public getPropertyListPatterns():IMapRegex { |
| 101 | return { |
| 102 | integer: /^(0|[-+]?[1-9][0-9]*|[-+]?0x[0-9a-fA-F]+|[-+]?0o[0-7]+)(,?(0|[-+]?[1-9][0-9]*|[-+]?0x[0-9a-fA-F]+|[-+]?0o[0-7]+))*$/, |
| 103 | string: /^"[\u0000-\u0021\u0023-\u00BF]+"(\s*,?\s*"[\u0000-\u0021\u0023-\u00BF]+")*$/, |
| 104 | boolean: /^([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee])(,?([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee]))*$/, |
| 105 | float: /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?(,?[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?f?)*$/ |
| 106 | }; |
| 107 | } |
| 108 | |
| 109 | public getPropertyMapPatterns():IMapRegex { |
| 110 | return { |
| 111 | integer: /^"\w+"\s*:\s?(0|[-+]?[1-9][0-9]*|[-+]?0x[0-9a-fA-F]+|[-+]?0o[0-7]+)+(\s*,?\s*"\w+"\s?:\s?(0|[-+]?[1-9][0-9]*|[-+]?0x[0-9a-fA-F]+|[-+]?0o[0-7]+)+)*$/, |
| 112 | string: /^"\w+"\s?:\s?"[\u0000-\u0021\u0023-\u00BF]*"(\s*,?\s*"\w+"\s?:\s?"[\u0000-\u0021\u0023-\u00BF]*")*$/, |
| 113 | boolean: /^"\w+"\s?:\s?([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee])(\s*,?\s*"\w+"\s?:\s?([Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee]))*$/, |
| 114 | float: /^"\w+"\s?:\s?[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?f?(\s*,?\s*"\w+"\s?:\s?[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?f?)*$/ |
| 115 | }; |
| 116 | } |
| 117 | |
| 118 | public validateUniqueKeys(viewValue:string):boolean { |
| 119 | if (!viewValue) { |
| 120 | return true; //allow empty value |
| 121 | } |
| 122 | |
| 123 | let json:string = "{" + viewValue.replace(/\s\s+/g, ' ') + "}"; |
| 124 | try { |
| 125 | let obj:any = JSON.parse(json); |
| 126 | /* |
| 127 | //Method #1 : check json string length before & after parsing |
| 128 | let newJson:string = JSON.stringify(obj); |
| 129 | if (newJson.length < json.length) { |
| 130 | return false; |
| 131 | }*/ |
| 132 | |
| 133 | //Method #2 : check how many times we can find "KEY": in json string |
| 134 | let result:boolean = true; |
| 135 | Object.keys(obj).forEach((key:string) => { |
| 136 | result = result && json.split('"' + key + '":').length === 2; |
| 137 | }); |
| 138 | return result; |
| 139 | |
| 140 | } catch (e) { |
| 141 | return false; //not a valid JSON |
| 142 | } |
| 143 | |
| 144 | //return true; |
| 145 | } |
| 146 | |
| 147 | public validateJson = (json:string):boolean => { |
| 148 | try { |
| 149 | JSON.parse(json); |
| 150 | return true; |
| 151 | } catch (err) { |
| 152 | console.log('invalid json'); |
| 153 | return false; |
| 154 | } |
| 155 | }; |
| 156 | |
| 157 | public validateIntRange = (value:string):boolean => { |
| 158 | |
| 159 | let base8 = new basePattern(/^([-+]?0o[0-7]+)$/, 8); |
| 160 | let base10 = new basePattern(/^(0|[-+]?[1-9][0-9]*)$/, 10); |
| 161 | let base16 = new basePattern(/^([-+]?0x[0-9a-fA-F]+)$/, 16); |
| 162 | |
| 163 | let min:number = -0x80000000; |
| 164 | let max:number = 0x7fffffff; |
| 165 | let intPatterns:Array<basePattern> = [base8, base10, base16]; |
| 166 | let matchedBase = _.find(intPatterns, (item)=> { |
| 167 | return item.pattern.test(value); |
| 168 | }); |
| 169 | |
| 170 | let parsed:number = parseInt(value.replace('o', ''), matchedBase.base); |
| 171 | if (parsed) { |
| 172 | return min <= parsed && max >= parsed; |
| 173 | } |
| 174 | } |
| 175 | } |