988f215a721bd232c8f58538200dfb614d5da1d4
[sdc.git] / common-app-api / src / main / java / org / openecomp / sdc / common / util / ValidationUtils.java
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
21 package org.openecomp.sdc.common.util;
22
23 import com.google.common.base.CharMatcher;
24 import org.apache.commons.lang3.StringEscapeUtils;
25 import org.apache.commons.lang3.StringUtils;
26 import org.apache.commons.lang3.math.NumberUtils;
27 import org.apache.commons.lang3.text.WordUtils;
28 import org.apache.commons.validator.routines.UrlValidator;
29 import org.jsoup.Jsoup;
30 import org.jsoup.safety.Whitelist;
31
32 import java.util.Arrays;
33 import java.util.HashSet;
34 import java.util.LinkedHashSet;
35 import java.util.List;
36 import java.util.Set;
37 import java.util.regex.Pattern;
38
39 public class ValidationUtils {
40     public static final Integer COMPONENT_NAME_MAX_LENGTH = 1024;
41     public static final Pattern COMPONENT_NAME_PATTERN = Pattern
42             .compile("^[\\w][\\w \\.\\-\\_\\:\\+]{0," + (COMPONENT_NAME_MAX_LENGTH - 1) + "}$");
43     public static final Integer ADDITIONAL_INFORMATION_KEY_MAX_LENGTH = 50;
44     public static final Pattern ADDITIONAL_INFORMATION_KEY_PATTERN = Pattern
45             .compile("^[\\w\\s\\.\\-\\_]{1," + COMPONENT_NAME_MAX_LENGTH + "}$");
46     public static final Integer RSI_NAME_MAX_LENGTH = 1024;
47     public static final Pattern RSI_NAME_PATTERN = Pattern
48             .compile("^[\\w \\s\\.\\-\\_\\:\\+]{1," + RSI_NAME_MAX_LENGTH + "}$");
49     public static final Integer COMMENT_MAX_LENGTH = 256;
50
51     public static final Integer ICON_MAX_LENGTH = 25;
52     public static final Pattern ICON_PATTERN = Pattern.compile("^[\\w\\-]{1," + ICON_MAX_LENGTH + "}$");
53     public static final Integer PROJECT_CODE_MAX_LEGTH = 50;
54     public static final Pattern PROJECT_CODE_PATTERN = Pattern.compile("^[\\s\\w_.-]{5,50}$");
55
56     public static final Integer CONNTACT_ID_MAX_LENGTH = 50;
57     public static final Pattern CONTACT_ID_PATTERN = Pattern.compile("^[\\s\\w_.-]{1,50}$");
58     public static final Pattern OCTET_PATTERN = Pattern.compile("%[a-fA-F0-9]{2}");
59     public static final Pattern NONE_UTF8_PATTERN = Pattern.compile("[^\\x00-\\x7F]+");
60     public static final Pattern URL_INVALIDE_PATTERN = Pattern.compile("[,#?&@$<>~^`\\\\\\[\\]{}|\")(*!+=;%]+"); // ,#?&@$<>~^`\\[]{}|")(*!
61
62     public static final Pattern ENGLISH_PATTERN = Pattern.compile("^[\\p{Graph}\\x20]+$");
63     public static final Integer COMPONENT_DESCRIPTION_MAX_LENGTH = 1024;
64     public static final Integer SERVICE_TYPE_MAX_LENGTH = 400;
65     public static final Integer SERVICE_ROLE_MAX_LENGTH = 400;
66
67     public static final Integer TAG_MAX_LENGTH = 1024;
68     public static final Integer TAG_LIST_MAX_LENGTH = 1024;
69     public static final Integer VENDOR_NAME_MAX_LENGTH = 60;
70     public static final Pattern VENDOR_NAME_PATTERN = Pattern
71             .compile("^[\\x20-\\x21\\x23-\\x29\\x2B-\\x2E\\x30-\\x39\\x3B\\x3D\\x40-\\x5B\\x5D-\\x7B\\x7D-\\xFF]+$");
72     public static final Integer VENDOR_RELEASE_MAX_LENGTH = 25;
73     public static final Pattern VENDOR_RELEASE_PATTERN = Pattern
74             .compile("^[\\x20-\\x21\\x23-\\x29\\x2B-\\x2E\\x30-\\x39\\x3B\\x3D\\x40-\\x5B\\x5D-\\x7B\\x7D-\\xFF]+$");
75     public static final Integer RESOURCE_VENDOR_MODEL_NUMBER_MAX_LENGTH = 65;
76
77     public static final Pattern CLEAN_FILENAME_PATTERN = Pattern.compile("[\\x00-\\x1f\\x80-\\x9f\\x5c/<?>\\*:|\"/]+");
78
79     public static final Pattern DASH_PATTERN = Pattern.compile("[-]+");
80     public static final Pattern UNDERSCORE_PATTERN = Pattern.compile("[_]+");
81     public static final Pattern PLUS_PATTERN = Pattern.compile("[+]+");
82     public static final Pattern SPACE_PATTERN = Pattern.compile("[ ]+");
83     public static final Pattern AMP_PATTERN = Pattern.compile("[&]+");
84     public static final Pattern DOT_PATTERN = Pattern.compile("[\\.]+");
85     public static final Pattern APOST_PATTERN = Pattern.compile("[']+");
86     public static final Pattern HASHTAG_PATTERN = Pattern.compile("[#]+");
87     public static final Pattern EQUAL_PATTERN = Pattern.compile("[=]+");
88     public static final Pattern COLON_PATTERN = Pattern.compile("[:]+");
89     public static final Pattern AT_PATTERN = Pattern.compile("[@]+");
90     public static final Pattern AND_PATTERN = Pattern.compile(" [aA][Nn][Dd] ");
91     public static final Set<String> CATEGORY_CONJUNCTIONS = new HashSet<>(
92             Arrays.asList("of", "to", "for", "as", "a", "an", "the"));
93
94     public static final Pattern COST_PATTERN = Pattern.compile("^[0-9]{1,5}\\.[0-9]{1,3}$");
95     public static final Pattern ARTIFACT_LABEL_PATTERN = Pattern.compile("^[a-zA-Z0-9 \\-+]+$");
96     public static final Integer ARTIFACT_LABEL_LENGTH = 255;
97     public static final Pattern ARTIFACT_DISPLAY_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9][a-zA-Z0-9 &\\.'#=:@_\\-+]+$");
98     public static final Pattern CATEGORY_LABEL_PATTERN = Pattern.compile("^[a-zA-Z0-9][a-zA-Z0-9 &\\.'#=:@_\\-+]+$");
99     public static final Integer CATEGORY_LABEL_MIN_LENGTH = 3;
100     public static final Integer CATEGORY_LABEL_MAX_LENGTH = 25;
101
102     public static final Pattern COMPONENT_NAME_DELIMETER_PATTERN = Pattern.compile("[\\.\\-\\_]+");
103     public static final Pattern COMPONENT_INCTANCE_NAME_DELIMETER_PATTERN = Pattern.compile("[\\.\\-]+");
104     public static final Pattern PRODUCT_NAME_DELIMETER_PATTERN = Pattern.compile("[\\.\\-\\_&=#@':\\[\\]\\+]+");
105     public static final Integer CONSUMER_NAME_MAX_LENGTH = 255;
106     // public static final Pattern CONSUMER_NAME_PATTERN =
107     // Pattern.compile("^[\\w]{1}?[\\w\\.\\-]{0," + CONSUMER_NAME_MAX_LENGTH +
108     // "}?$");
109     public static final Pattern CONSUMER_NAME_PATTERN = Pattern.compile("^[\\w]+[\\w\\.\\-]*$");
110     public static final Integer CONSUMER_SALT_LENGTH = 32;
111     public static final Integer CONSUMER_PASSWORD_LENGTH = 64;
112     public static final Pattern CONSUMER_PASS_SALT_PATTERN = Pattern.compile("^[a-z0-9]+$");
113     public static final Pattern FLOAT_PATTERN = Pattern.compile("^[\\d]+[\\.]{1}[\\d]+$");
114     public static final Pattern CERTIFIED_VERSION_PATTERN = Pattern.compile("^[1-9][0-9]*\\.0$");
115     public static final Pattern MINOR_VERSION_PATTERN = Pattern.compile("^0\\.[1-9][0-9]*$");
116     public static final Pattern TAGS_PATTERN = Pattern.compile("<[^><]*>");
117
118     public static final Integer ARTIFACT_NAME_LENGTH = 255;
119     public static final Integer API_URL_LENGTH = 100;
120     public static final Integer ARTIFACT_DESCRIPTION_MAX_LENGTH = 256;
121
122     public static final Integer PRODUCT_FULL_NAME_MIN_LENGTH = 4;
123     public static final Integer PRODUCT_FULL_NAME_MAX_LENGTH = 100;
124     public static final Integer FORWARDING_PATH_NAME_MAX_LENGTH = 100;
125     public static final Pattern FORWARDING_PATH_NAME_PATTERN = Pattern.compile("^[\\w][\\w \\.\\-\\_\\:\\+]{0," + (FORWARDING_PATH_NAME_MAX_LENGTH - 1) + "}$");
126
127     public static final Integer POLICY_MAX_LENGTH = 1024;
128     public static final Pattern POLICY_NAME_PATTERN = Pattern
129             .compile("^[\\w][\\w \\.\\-\\_\\:\\+]{0," + (POLICY_MAX_LENGTH - 1) + "}$");
130
131     public static boolean validateArtifactLabel(String label) {
132         return ARTIFACT_LABEL_PATTERN.matcher(label).matches();
133     }
134
135     public static boolean validateArtifactDisplayName(String displayName) {
136         return ARTIFACT_DISPLAY_NAME_PATTERN.matcher(displayName).matches();
137     }
138
139     public static boolean validateCategoryDisplayNameFormat(String label) {
140         boolean res = true;
141         if (label != null) {
142             label = label.trim();
143             res = CATEGORY_LABEL_PATTERN.matcher(label).matches();
144         }
145         return res;
146     }
147
148     public static String normalizeCategoryName4Display(String str) {
149         if (str != null) {
150             str = str.trim();
151             str = DASH_PATTERN.matcher(str).replaceAll("-");
152             str = UNDERSCORE_PATTERN.matcher(str).replaceAll("_");
153             str = AMP_PATTERN.matcher(str).replaceAll("&");
154             str = PLUS_PATTERN.matcher(str).replaceAll("+");
155             str = DOT_PATTERN.matcher(str).replaceAll(".");
156             str = APOST_PATTERN.matcher(str).replaceAll("'");
157             str = HASHTAG_PATTERN.matcher(str).replaceAll("#");
158             str = EQUAL_PATTERN.matcher(str).replaceAll("=");
159             str = COLON_PATTERN.matcher(str).replaceAll(":");
160             str = AT_PATTERN.matcher(str).replaceAll("@");
161             str = normaliseWhitespace(str);
162             str = AND_PATTERN.matcher(str).replaceAll(" & ");
163
164             // Case normalizing
165             StringBuilder sb = new StringBuilder();
166             String[] split = str.split(" ");
167             for (int i = 0; i < split.length; i++) {
168                 String splitted = split[i];
169                 String lowerCase = splitted.toLowerCase();
170                 // BANK OF AMERICA --> BANK of AMERICA ("of" is lowercased), but
171                 // OF BANK OF AMERICA --> OF BANK of AMERICA (first "OF" is not
172                 // lowercased because it's first word)
173                 // Agreed with Ella, 26/11/15
174                 if ((i > 0) && CATEGORY_CONJUNCTIONS.contains(lowerCase)) {
175                     sb.append(lowerCase);
176                 } else {
177                     sb.append(WordUtils.capitalize(splitted));
178                 }
179                 sb.append(" ");
180             }
181             str = sb.toString().trim();
182         }
183         return str;
184     }
185
186     public static String normalizeCategoryName4Uniqueness(String str) {
187         return str.toLowerCase();
188     }
189
190     public static boolean validateCategoryDisplayNameLength(String label) {
191         return (label != null && label.length() >= CATEGORY_LABEL_MIN_LENGTH
192                 && label.length() <= CATEGORY_LABEL_MAX_LENGTH);
193     }
194
195     public static boolean validateProductFullNameLength(String fullName) {
196         return (fullName != null && fullName.length() >= PRODUCT_FULL_NAME_MIN_LENGTH
197                 && fullName.length() <= PRODUCT_FULL_NAME_MAX_LENGTH);
198     }
199
200     public static boolean validateArtifactLabelLength(String label) {
201         return label.length() > 0 && label.length() <= ARTIFACT_LABEL_LENGTH;
202     }
203
204     public static boolean validateResourceInstanceNameLength(String resourceInstanceName) {
205         return resourceInstanceName.length() <= RSI_NAME_MAX_LENGTH;
206     }
207
208     public static boolean validateResourceInstanceName(String resourceInstanceName) {
209         return RSI_NAME_PATTERN.matcher(resourceInstanceName).matches();
210     }
211
212     public static boolean validateUrlLength(String url) {
213         return url.length() <= API_URL_LENGTH;
214     }
215
216     public static boolean validateArtifactNameLength(String artifactName) {
217         return (artifactName.length() <= ARTIFACT_NAME_LENGTH && artifactName.length() > 0);
218     }
219
220     public static boolean validateComponentNamePattern(String componentName) {
221         return COMPONENT_NAME_PATTERN.matcher(componentName).matches();
222     }
223
224     public static boolean validateComponentNameLength(String componentName) {
225         return componentName.length() <= COMPONENT_NAME_MAX_LENGTH;
226     }
227
228     public static boolean validateIcon(String icon) {
229         return ICON_PATTERN.matcher(icon).matches();
230     }
231
232     public static boolean validateIconLength(String icon) {
233         return icon.length() <= ICON_MAX_LENGTH;
234     }
235
236     public static boolean validateProjectCode(String projectCode) {
237         return PROJECT_CODE_PATTERN.matcher(projectCode).matches();
238     }
239
240     public static boolean validateProjectCodeLegth(String projectCode) {
241         return projectCode.length() <= PROJECT_CODE_MAX_LEGTH;
242     }
243
244     public static boolean validateContactId(String contactId) {
245         return CONTACT_ID_PATTERN.matcher(contactId).matches();
246     }
247
248     public static boolean validateCost(String cost) {
249         return COST_PATTERN.matcher(cost).matches();
250     }
251
252     public static String removeHtmlTags(String str) {
253         return Jsoup.clean(str, Whitelist.none());
254     }
255
256     public static String removeAllTags(String htmlText) {
257
258         return TAGS_PATTERN.matcher(htmlText).replaceAll("").trim();
259     }
260
261     public static String normaliseWhitespace(String str) {
262         StringBuilder sb = new StringBuilder(str.length());
263         appendNormalisedWhitespace(sb, str, false);
264         return sb.toString();
265     }
266
267     private static void appendNormalisedWhitespace(StringBuilder accum, String string, boolean stripLeading) {
268         boolean lastWasWhite = false;
269         boolean reachedNonWhite = false;
270
271         int len = string.length();
272         int c;
273         for (int i = 0; i < len; i += Character.charCount(c)) {
274             c = string.codePointAt(i);
275             if (isWhitespace(c)) {
276                 if ((stripLeading && !reachedNonWhite) || lastWasWhite) {
277                     continue;
278                 }
279                 accum.append(' ');
280                 lastWasWhite = true;
281             } else {
282                 accum.appendCodePoint(c);
283                 lastWasWhite = false;
284                 reachedNonWhite = true;
285             }
286         }
287     }
288
289     private static boolean isWhitespace(int c) {
290         return c == ' ';
291     }
292
293     public static String stripOctets(String str) {
294         return OCTET_PATTERN.matcher(str).replaceAll("");
295     }
296
297     public static String removeNoneUtf8Chars(String input) {
298         return NONE_UTF8_PATTERN.matcher(input).replaceAll("");
299     }
300
301     public static boolean validateIsEnglish(String input) {
302         return ENGLISH_PATTERN.matcher(input).matches();
303     }
304
305     public static boolean validateIsAscii(String input) {
306
307         return CharMatcher.ASCII.matchesAllOf(input);
308     }
309
310     public static String convertHtmlTagsToEntities(String input) {
311         return StringEscapeUtils.escapeHtml4(input);
312     }
313
314     public static List<String> removeDuplicateFromList(List<String> list) {
315         Set<String> hs = new LinkedHashSet<>(list);
316         list.clear();
317         list.addAll(hs);
318         return list;
319
320     }
321
322     public static boolean validateTagLength(String tag) {
323         if (tag != null) {
324             return tag.length() <= TAG_MAX_LENGTH;
325         }
326         return false;
327     }
328
329     public static boolean validateTagListLength(int tagListLength) {
330         return tagListLength <= TAG_LIST_MAX_LENGTH;
331     }
332
333     public static boolean validateDescriptionLength(String description) {
334         return description.length() <= COMPONENT_DESCRIPTION_MAX_LENGTH;
335     }
336
337     public static boolean validateStringNotEmpty(String value) {
338         if ((value == null) || (value.isEmpty())) {
339             return false;
340         }
341         return true;
342     }
343
344     public static boolean validateListNotEmpty(List<?> list) {
345         if ((list == null) || (list.isEmpty())) {
346             return false;
347         }
348         return true;
349     }
350
351     public static boolean validateVendorName(String vendorName) {
352         return VENDOR_NAME_PATTERN.matcher(vendorName).matches();
353     }
354
355     public static boolean validateVendorNameLength(String vendorName) {
356         return vendorName.length() <= VENDOR_NAME_MAX_LENGTH;
357     }
358
359     public static boolean validateResourceVendorModelNumberLength(String resourceVendorModelNumber) {
360         return resourceVendorModelNumber.length() <= RESOURCE_VENDOR_MODEL_NUMBER_MAX_LENGTH;
361     }
362
363     public static boolean validateVendorRelease(String vendorRelease) {
364         return VENDOR_RELEASE_PATTERN.matcher(vendorRelease).matches();
365     }
366
367     public static boolean validateVendorReleaseLength(String vendorRelease) {
368         return vendorRelease.length() <= VENDOR_RELEASE_MAX_LENGTH;
369     }
370
371     public static boolean validateServiceTypeLength(String serviceType) {
372         return serviceType.length() <= SERVICE_TYPE_MAX_LENGTH;
373     }
374
375     public static boolean validateServiceRoleLength(String serviceRole) {
376         return serviceRole.length() <= SERVICE_ROLE_MAX_LENGTH;
377     }
378
379
380     public static boolean hasBeenCertified(String version) {
381         return NumberUtils.toDouble(version) >= 1;
382     }
383
384     public static String normaliseComponentName(String name) {
385         String[] split = splitComponentName(name);
386         StringBuilder sb = new StringBuilder();
387         for (String splitElement : split) {
388             sb.append(splitElement);
389         }
390         return sb.toString();
391
392     }
393
394     public static String normalizeComponentInstanceName(String name) {
395         String[] split = splitComponentInstanceName(name);
396         StringBuilder sb = new StringBuilder();
397         for (String splitElement : split) {
398             sb.append(splitElement);
399         }
400         return sb.toString();
401
402     }
403
404     private static String[] splitComponentName(String name) {
405         String normalizedName = name.toLowerCase();
406         normalizedName = COMPONENT_NAME_DELIMETER_PATTERN.matcher(normalizedName).replaceAll(" ");
407         return normalizedName.split(" ");
408     }
409
410     private static String[] splitComponentInstanceName(String name) {
411         String normalizedName = name.toLowerCase();
412         normalizedName = COMPONENT_INCTANCE_NAME_DELIMETER_PATTERN.matcher(normalizedName).replaceAll(" ");
413         return normalizedName.split(" ");
414     }
415
416     public static String convertToSystemName(String name) {
417         String[] split = splitComponentName(name);
418         StringBuilder sb = new StringBuilder();
419         for (String splitElement : split) {
420             String capitalize = WordUtils.capitalize(splitElement);
421             sb.append(capitalize);
422         }
423         return sb.toString();
424     }
425
426     public static String normalizeFileName(String filename) {
427         // String[] split = filename.split(Pattern.quote(File.separator));
428         // String name = "";
429         //
430         // name = split[split.length - 1];
431         return cleanFileName(filename);
432
433     }
434
435     private static String cleanFileName(String str) {
436         str = CLEAN_FILENAME_PATTERN.matcher(str).replaceAll("");
437         str = normaliseWhitespace(str);
438         str = SPACE_PATTERN.matcher(str).replaceAll("-");
439         str = DASH_PATTERN.matcher(str).replaceAll("-");
440         str = StringUtils.strip(str, "-_ .");
441
442         return str;
443     }
444
445     public static boolean validateUrl(String url) {
446
447         UrlValidator urlValidator = new UrlValidator();
448         if (!urlValidator.isValid(url)) {
449             return false;
450         }
451         if (NONE_UTF8_PATTERN.matcher(url).find()) {
452             return false;
453         }
454
455         if (URL_INVALIDE_PATTERN.matcher(url).find()) {
456             return false;
457         }
458         return true;
459
460     }
461
462     public static String cleanArtifactDisplayName(String strIn) {
463         String str = DASH_PATTERN.matcher(strIn).replaceAll("-");
464         str = UNDERSCORE_PATTERN.matcher(str).replaceAll("_");
465         str = PLUS_PATTERN.matcher(str).replaceAll("+");
466         str = normaliseWhitespace(str);
467         str = str.trim();
468         // str = str.replaceAll(" ", "");
469
470         return str;
471     }
472
473     public static String normalizeArtifactLabel(String strIn) {
474
475         String str = DASH_PATTERN.matcher(strIn).replaceAll("");
476         str = UNDERSCORE_PATTERN.matcher(str).replaceAll("");
477         str = PLUS_PATTERN.matcher(str).replaceAll("");
478         str = SPACE_PATTERN.matcher(str).replaceAll("");
479         str = DOT_PATTERN.matcher(str).replaceAll("");
480         str = str.toLowerCase();
481
482         return str;
483     }
484
485     public static boolean validateAdditionalInformationKeyName(String str) {
486         return ADDITIONAL_INFORMATION_KEY_PATTERN.matcher(str).matches();
487     }
488
489     public static String normalizeAdditionalInformation(String str) {
490         if (str != null) {
491             str = DASH_PATTERN.matcher(str).replaceAll("-");
492             str = UNDERSCORE_PATTERN.matcher(str).replaceAll("_");
493             str = normaliseWhitespace(str);
494         }
495         return str;
496     }
497
498     public static boolean validateLength(String str, int length) {
499         if (str == null) {
500             return true;
501         }
502         return str.length() <= length;
503     }
504
505     public static boolean validateConsumerName(String consumerName) {
506         return CONSUMER_NAME_PATTERN.matcher(consumerName).matches();
507     }
508
509     public static boolean isUTF8Str(String str) {
510         if (NONE_UTF8_PATTERN.matcher(str).find()) {
511             return false;
512         }
513         return true;
514     }
515
516     public static boolean validateConsumerPassSalt(String consumerSalt) {
517         return CONSUMER_PASS_SALT_PATTERN.matcher(consumerSalt).matches();
518     }
519
520     public static boolean isFloatNumber(String number) {
521         return FLOAT_PATTERN.matcher(number).matches();
522     }
523
524     public static boolean validateCertifiedVersion(String version) {
525         return (version != null && CERTIFIED_VERSION_PATTERN.matcher(version).matches());
526     }
527
528     public static boolean validateMinorVersion(String version) {
529         return (version != null && MINOR_VERSION_PATTERN.matcher(version).matches());
530     }
531
532     public static String normaliseProductName(String name) {
533         String[] split = splitComponentName(PRODUCT_NAME_DELIMETER_PATTERN, name);
534         StringBuilder sb = new StringBuilder();
535         for (String splitElement : split) {
536             sb.append(splitElement);
537         }
538         return sb.toString();
539
540     }
541
542     private static String[] splitComponentName(Pattern pattern, String name) {
543         String normalizedName = name.toLowerCase();
544         normalizedName = pattern.matcher(normalizedName).replaceAll(" ");
545         return normalizedName.split(" ");
546     }
547
548     public static String removeHtmlTagsOnly(String htmlText) {
549         return HtmlCleaner.stripHtml(htmlText, false);
550     }
551
552     public static boolean validateForwardingPathNamePattern(String forwardingPathName) {
553         return FORWARDING_PATH_NAME_PATTERN.matcher(forwardingPathName).matches();
554     }
555 }