001 /** 002 * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved. 003 * 004 * The contents of this file are subject to the terms of the Liferay Enterprise 005 * Subscription License ("License"). You may not use this file except in 006 * compliance with the License. You can obtain a copy of the License by 007 * contacting Liferay, Inc. See the License for the specific language governing 008 * permissions and limitations under the License, including but not limited to 009 * distribution rights of the Software. 010 * 011 * 012 * 013 */ 014 015 package com.liferay.portal.kernel.util; 016 017 import java.net.MalformedURLException; 018 import java.net.URL; 019 020 import java.util.regex.Matcher; 021 import java.util.regex.Pattern; 022 023 /** 024 * Provides utility methods related to data validation and format checking. 025 * 026 * @author Brian Wing Shun Chan 027 * @author Alysa Carver 028 */ 029 public class Validator { 030 031 /** 032 * Determines if the booleans are equal. 033 * 034 * @param boolean1 the first boolean 035 * @param boolean2 the second boolean 036 * @return <code>true</code> if the booleans are equal; <code>false</code> 037 * otherwise 038 */ 039 public static boolean equals(boolean boolean1, boolean boolean2) { 040 if (boolean1 == boolean2) { 041 return true; 042 } 043 else { 044 return false; 045 } 046 } 047 048 /** 049 * Determines if the bytes are equal. 050 * 051 * @param byte1 the first byte 052 * @param byte2 the second byte 053 * @return <code>true</code> if the bytes are equal; <code>false</code> 054 * otherwise 055 */ 056 public static boolean equals(byte byte1, byte byte2) { 057 if (byte1 == byte2) { 058 return true; 059 } 060 else { 061 return false; 062 } 063 } 064 065 /** 066 * Determines if the characters are equal. 067 * 068 * @param char1 the first character 069 * @param char2 the second character 070 * @return <code>true</code> if the characters are equal; <code>false</code> 071 * otherwise 072 */ 073 public static boolean equals(char char1, char char2) { 074 if (char1 == char2) { 075 return true; 076 } 077 else { 078 return false; 079 } 080 } 081 082 /** 083 * Determines if the doubles are equal. 084 * 085 * @param double1 the first double 086 * @param double2 the second double 087 * @return <code>true</code> if the doubles are equal; <code>false</code> 088 * otherwise 089 */ 090 public static boolean equals(double double1, double double2) { 091 if (Double.compare(double1, double2) == 0) { 092 return true; 093 } 094 else { 095 return false; 096 } 097 } 098 099 /** 100 * Determines if the floats are equal. 101 * 102 * @param float1 the first float 103 * @param float2 the second float 104 * @return <code>true</code> if the floats are equal; <code>false</code> 105 * otherwise 106 */ 107 public static boolean equals(float float1, float float2) { 108 if (Float.compare(float1, float2) == 0) { 109 return true; 110 } 111 else { 112 return false; 113 } 114 } 115 116 /** 117 * Determines if the integers are equal. 118 * 119 * @param int1 the first integer 120 * @param int2 the second integer 121 * @return <code>true</code> if the integers are equal; <code>false</code> 122 * otherwise 123 */ 124 public static boolean equals(int int1, int int2) { 125 if (int1 == int2) { 126 return true; 127 } 128 else { 129 return false; 130 } 131 } 132 133 /** 134 * Determines if the long integers are equal. 135 * 136 * @param long1 the first long integer 137 * @param long2 the second long integer 138 * @return <code>true</code> if the long integers are equal; 139 * <code>false</code> otherwise 140 */ 141 public static boolean equals(long long1, long long2) { 142 if (long1 == long2) { 143 return true; 144 } 145 else { 146 return false; 147 } 148 } 149 150 /** 151 * Determines if the objects are either equal, the same instance, or both 152 * <code>null</code>. 153 * 154 * @param obj1 the first object 155 * @param obj2 the second object 156 * @return <code>true</code> if the objects are either equal, the same 157 * instance, or both <code>null</code>; <code>false</code> otherwise 158 */ 159 public static boolean equals(Object obj1, Object obj2) { 160 if ((obj1 == null) && (obj2 == null)) { 161 return true; 162 } 163 else if ((obj1 == null) || (obj2 == null)) { 164 return false; 165 } 166 else { 167 return obj1.equals(obj2); 168 } 169 } 170 171 /** 172 * Determines if the short integers are equal. 173 * 174 * @param short1 the first short integer 175 * @param short2 the second short integer 176 * @return <code>true</code> if the short integers are equal; 177 * <code>false</code> otherwise 178 */ 179 public static boolean equals(short short1, short short2) { 180 if (short1 == short2) { 181 return true; 182 } 183 else { 184 return false; 185 } 186 } 187 188 /** 189 * Determines if the string is an email address. The only requirements are 190 * that the string consist of two parts separated by an @ symbol, and that 191 * it contain no whitespace. 192 * 193 * @param address the string to check 194 * @return <code>true</code> if the string is an email address; 195 * <code>false</code> otherwise 196 */ 197 public static boolean isAddress(String address) { 198 if (isNull(address)) { 199 return false; 200 } 201 202 String[] tokens = address.split(StringPool.AT); 203 204 if (tokens.length != 2) { 205 return false; 206 } 207 208 for (String token : tokens) { 209 for (char c : token.toCharArray()) { 210 if (Character.isWhitespace(c)) { 211 return false; 212 } 213 } 214 } 215 216 return true; 217 } 218 219 /** 220 * Determines if the string is an alphanumeric name, meaning it contains 221 * nothing but English letters, numbers, and spaces. 222 * 223 * @param name the string to check 224 * @return <code>true</code> if the string is an Alphanumeric name; 225 * <code>false</code> otherwise 226 */ 227 public static boolean isAlphanumericName(String name) { 228 if (isNull(name)) { 229 return false; 230 } 231 232 for (char c : name.trim().toCharArray()) { 233 if (!isChar(c) && !isDigit(c) && !Character.isWhitespace(c)) { 234 return false; 235 } 236 } 237 238 return true; 239 } 240 241 /** 242 * Determines if the character is in the ASCII character set. This includes 243 * characters with integer values between 32 and 126 (inclusive). 244 * 245 * @param c the character to check 246 * @return <code>true</code> if the character is in the ASCII character set; 247 * <code>false</code> otherwise 248 */ 249 public static boolean isAscii(char c) { 250 int i = c; 251 252 if ((i >= 32) && (i <= 126)) { 253 return true; 254 } 255 else { 256 return false; 257 } 258 } 259 260 /** 261 * Determines if the character is an upper or lower case English letter. 262 * 263 * @param c the character to check 264 * @return <code>true</code> if the character is an upper or lower case 265 * English letter; <code>false</code> otherwise 266 */ 267 public static boolean isChar(char c) { 268 int x = c; 269 270 if ((x >= _CHAR_BEGIN) && (x <= _CHAR_END)) { 271 return true; 272 } 273 274 return false; 275 } 276 277 /** 278 * Determines if string consists only of upper and lower case English 279 * letters. 280 * 281 * @param s the string to check 282 * @return <code>true</code> if the string consists only of upper and lower 283 * case English letters 284 */ 285 public static boolean isChar(String s) { 286 if (isNull(s)) { 287 return false; 288 } 289 290 for (char c : s.toCharArray()) { 291 if (!isChar(c)) { 292 return false; 293 } 294 } 295 296 return true; 297 } 298 299 /** 300 * Determines if the date is valid in the Gregorian calendar. 301 * 302 * @param month the month to check 303 * @param day the day to check 304 * @return <code>true</code> if the date is valid in the Gregorian calendar; 305 * <code>false</code> otherwise 306 */ 307 public static boolean isDate(int month, int day, int year) { 308 return isGregorianDate(month, day, year); 309 } 310 311 /** 312 * Determines if the character is a digit between 0 and 9 (inclusive). 313 * 314 * @param c the character to check 315 * @return <code>true</code> if the character is a digit between 0 and 9 316 * (inclusive); <code>false</code> otherwise 317 */ 318 public static boolean isDigit(char c) { 319 int x = c; 320 321 if ((x >= _DIGIT_BEGIN) && (x <= _DIGIT_END)) { 322 return true; 323 } 324 325 return false; 326 } 327 328 /** 329 * Determines if the string consists of only digits between 0 and 9 330 * (inclusive). 331 * 332 * @param s the string to check 333 * @return <code>true</code> if the string consists of only digits between 0 334 * and 9 (inclusive); <code>false</code> otherwise 335 */ 336 public static boolean isDigit(String s) { 337 if (isNull(s)) { 338 return false; 339 } 340 341 for (char c : s.toCharArray()) { 342 if (!isDigit(c)) { 343 return false; 344 } 345 } 346 347 return true; 348 } 349 350 /** 351 * Determines if the string is a valid domain name. See RFC-1034 (section 352 * 3), RFC-1123 (section 2.1), and RFC-952 (section B. Lexical grammar). 353 * 354 * @param domainName the string to check 355 * @return <code>true</code> if the string is a valid domain name; 356 * <code>false</code> otherwise 357 */ 358 public static boolean isDomain(String domainName) { 359 360 // See RFC-1034 (section 3), RFC-1123 (section 2.1), and RFC-952 361 // (section B. Lexical grammar) 362 363 if (isNull(domainName)) { 364 return false; 365 } 366 367 if (domainName.length() > 255) { 368 return false; 369 } 370 371 String[] domainNameArray = StringUtil.split( 372 domainName, StringPool.PERIOD); 373 374 for (String domainNamePart : domainNameArray) { 375 char[] domainNamePartCharArray = domainNamePart.toCharArray(); 376 377 for (int i = 0; i < domainNamePartCharArray.length; i++) { 378 char c = domainNamePartCharArray[i]; 379 380 if ((i == 0) && (c == CharPool.DASH)) { 381 return false; 382 } 383 else if ((i == (domainNamePartCharArray.length - 1)) && 384 (c == CharPool.DASH)) { 385 386 return false; 387 } 388 else if ((!isChar(c)) && (!isDigit(c)) && 389 (c != CharPool.DASH)) { 390 391 return false; 392 } 393 } 394 } 395 396 return true; 397 } 398 399 /** 400 * Determines if the string is a valid email address. 401 * 402 * @param emailAddress the string to check 403 * @return <code>true</code> if the string is a valid email address; 404 * <code>false</code> otherwise 405 */ 406 public static boolean isEmailAddress(String emailAddress) { 407 Matcher matcher = _emailAddressPattern.matcher(emailAddress); 408 409 return matcher.matches(); 410 } 411 412 /** 413 * Determines if the character is a special character in an email address. 414 * 415 * @param c the character to check 416 * @return <code>true</code> if the character is a special character in an 417 * email address; <code>false</code> otherwise 418 */ 419 public static boolean isEmailAddressSpecialChar(char c) { 420 421 // LEP-1445 422 423 for (int i = 0; i < _EMAIL_ADDRESS_SPECIAL_CHAR.length; i++) { 424 if (c == _EMAIL_ADDRESS_SPECIAL_CHAR[i]) { 425 return true; 426 } 427 } 428 429 return false; 430 } 431 432 /** 433 * Determines if the date is valid in the Gregorian calendar. 434 * 435 * @param month the month (0-based, meaning 0 for January) 436 * @param day the day of the month 437 * @param year the year 438 * @return <code>true</code> if the date is valid; <code>false</code> 439 * otherwise 440 */ 441 public static boolean isGregorianDate(int month, int day, int year) { 442 if ((month < 0) || (month > 11)) { 443 return false; 444 } 445 446 int[] months = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 447 448 if (month == 1) { 449 int febMax = 28; 450 451 if (((year % 4) == 0) && ((year % 100) != 0) || 452 ((year % 400) == 0)) { 453 454 febMax = 29; 455 } 456 457 if ((day < 1) || (day > febMax)) { 458 return false; 459 } 460 } 461 else if ((day < 1) || (day > months[month])) { 462 return false; 463 } 464 465 return true; 466 } 467 468 /** 469 * Determines if the string is a hexidecimal number. At present the only 470 * requirement is that the string is not <code>null</code>; it does not 471 * actually check the format of the string. 472 * 473 * @param s the string to check 474 * @return <code>true</code> if the string is a hexidecimal number; 475 * <code>false</code> otherwise 476 * @see #isNull(String) 477 */ 478 public static boolean isHex(String s) { 479 if (isNull(s)) { 480 return false; 481 } 482 483 return true; 484 } 485 486 /** 487 * Determines if the string is an HTML document. The only requirement is 488 * that it contain the opening and closing html tags. 489 * 490 * @param s the string to check 491 * @return <code>true</code> if the string is an HTML document; 492 * <code>false</code> otherwise 493 */ 494 public static boolean isHTML(String s) { 495 if (isNull(s)) { 496 return false; 497 } 498 499 if (((s.indexOf("<html>") != -1) || (s.indexOf("<HTML>") != -1)) && 500 ((s.indexOf("</html>") != -1) || (s.indexOf("</HTML>") != -1))) { 501 502 return true; 503 } 504 505 return false; 506 } 507 508 /** 509 * Determines if the string is a valid IPv4 IP address. 510 * 511 * @param ipAddress the string to check 512 * @return <code>true</code> if the string is an IPv4 IP address; 513 * <code>false</code> otherwise 514 */ 515 public static boolean isIPAddress(String ipAddress) { 516 Matcher matcher = _ipAddressPattern.matcher(ipAddress); 517 518 return matcher.matches(); 519 } 520 521 /** 522 * Determines if the date is valid in the Julian calendar. 523 * 524 * @param month the month (0-based, meaning 0 for January) 525 * @param day the day of the month 526 * @param year the year 527 * @return <code>true</code> if the date is valid; <code>false</code> 528 * otherwise 529 */ 530 public static boolean isJulianDate(int month, int day, int year) { 531 if ((month < 0) || (month > 11)) { 532 return false; 533 } 534 535 int[] months = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 536 537 if (month == 1) { 538 int febMax = 28; 539 540 if ((year % 4) == 0) { 541 febMax = 29; 542 } 543 544 if ((day < 1) || (day > febMax)) { 545 return false; 546 } 547 } 548 else if ((day < 1) || (day > months[month])) { 549 return false; 550 } 551 552 return true; 553 } 554 555 /** 556 * Determines if the string contains a valid number according to the Luhn 557 * algorithm, commonly used to validate credit card numbers. 558 * 559 * @param number the string to check 560 * @return <code>true</code> if the string contains a valid number according 561 * to the Luhn algorithm; <code>false</code> otherwise 562 */ 563 public static boolean isLUHN(String number) { 564 if (number == null) { 565 return false; 566 } 567 568 number = StringUtil.reverse(number); 569 570 int total = 0; 571 572 for (int i = 0; i < number.length(); i++) { 573 int x = 0; 574 575 if (((i + 1) % 2) == 0) { 576 x = Integer.parseInt(number.substring(i, i + 1)) * 2; 577 578 if (x >= 10) { 579 String s = String.valueOf(x); 580 581 x = Integer.parseInt(s.substring(0, 1)) + 582 Integer.parseInt(s.substring(1, 2)); 583 } 584 } 585 else { 586 x = Integer.parseInt(number.substring(i, i + 1)); 587 } 588 589 total = total + x; 590 } 591 592 if ((total % 10) == 0) { 593 return true; 594 } 595 else { 596 return false; 597 } 598 } 599 600 /** 601 * Determines if the string is a name, meaning it contains nothing but 602 * English letters and spaces. 603 * 604 * @param name the string to check 605 * @return <code>true</code> if the string is a name; <code>false</code> 606 * otherwise 607 */ 608 public static boolean isName(String name) { 609 if (isNull(name)) { 610 return false; 611 } 612 613 for (char c : name.trim().toCharArray()) { 614 if (!isChar(c) && !Character.isWhitespace(c)) { 615 return false; 616 } 617 } 618 619 return true; 620 } 621 622 /** 623 * Determines if the long number object is not <code>null</code>, meaning it 624 * is neither a <code>null</code> reference or zero. 625 * 626 * @param l the long number object to check 627 * @return <code>true</code> if the long number object is not 628 * <code>null</code>; <code>false</code> otherwise 629 */ 630 public static boolean isNotNull(Long l) { 631 return !isNull(l); 632 } 633 634 /** 635 * Determines if the object is not <code>null</code>, using the rules from 636 * {@link #isNotNull(Long)} or {@link #isNotNull(String)} if the object is 637 * one of these types. 638 * 639 * @param obj the object to check 640 * @return <code>true</code> if the object is not <code>null</code>; 641 * <code>false</code> otherwise 642 */ 643 public static boolean isNotNull(Object obj) { 644 return !isNull(obj); 645 } 646 647 /** 648 * Determines if the array is not <code>null</code>, meaning it is neither a 649 * <code>null</code> reference or empty. 650 * 651 * @param array the array to check 652 * @return <code>true</code> if the array is not <code>null</code>; 653 * <code>false</code> otherwise 654 */ 655 public static boolean isNotNull(Object[] array) { 656 return !isNull(array); 657 } 658 659 /** 660 * Determines if the string is not <code>null</code>, meaning it is not a 661 * <code>null</code> reference, nothing but spaces, or the string 662 * "<code>null</code>". 663 * 664 * @param s the string to check 665 * @return <code>true</code> if the string is not <code>null</code>; 666 * <code>false</code> otherwise 667 */ 668 public static boolean isNotNull(String s) { 669 return !isNull(s); 670 } 671 672 /** 673 * Determines if the long number object is <code>null</code>, meaning it is 674 * either a <code>null</code> reference or zero. 675 * 676 * @param l the long number object to check 677 * @return <code>true</code> if the long number object is <code>null</code>; 678 * <code>false</code> otherwise 679 */ 680 public static boolean isNull(Long l) { 681 if ((l == null) || (l.longValue() == 0)) { 682 return true; 683 } 684 else { 685 return false; 686 } 687 } 688 689 /** 690 * Determines if the object is <code>null</code>, using the rules from 691 * {@link #isNull(Long)} or {@link #isNull(String)} if the object is one of 692 * these types. 693 * 694 * @param obj the object to check 695 * @return <code>true</code> if the object is <code>null</code>; 696 * <code>false</code> otherwise 697 */ 698 public static boolean isNull(Object obj) { 699 if (obj instanceof Long) { 700 return isNull((Long)obj); 701 } 702 else if (obj instanceof String) { 703 return isNull((String)obj); 704 } 705 else if (obj == null) { 706 return true; 707 } 708 else { 709 return false; 710 } 711 } 712 713 /** 714 * Determines if the array is <code>null</code>, meaning it is either a 715 * <code>null</code> reference or empty. 716 * 717 * @param array the array to check 718 * @return <code>true</code> if the array is <code>null</code>; 719 * <code>false</code> otherwise 720 */ 721 public static boolean isNull(Object[] array) { 722 if ((array == null) || (array.length == 0)) { 723 return true; 724 } 725 else { 726 return false; 727 } 728 } 729 730 /** 731 * Determines if the string is <code>null</code>, meaning it is a 732 * <code>null</code> reference, nothing but spaces, or the string 733 * "<code>null</code>". 734 * 735 * @param s the string to check 736 * @return <code>true</code> if the string is <code>null</code>; 737 * <code>false</code> otherwise 738 */ 739 public static boolean isNull(String s) { 740 if (s == null) { 741 return true; 742 } 743 744 int counter = 0; 745 746 for (int i = 0; i < s.length(); i++) { 747 char c = s.charAt(i); 748 749 if (c == CharPool.SPACE) { 750 continue; 751 } 752 else if (counter > 3) { 753 return false; 754 } 755 756 if (counter == 0) { 757 if (c != CharPool.LOWER_CASE_N) { 758 return false; 759 } 760 } 761 else if (counter == 1) { 762 if (c != CharPool.LOWER_CASE_U) { 763 return false; 764 } 765 } 766 else if ((counter == 2) || (counter == 3)) { 767 if (c != CharPool.LOWER_CASE_L) { 768 return false; 769 } 770 } 771 772 counter++; 773 } 774 775 if ((counter == 0) || (counter == 4)) { 776 return true; 777 } 778 779 return false; 780 } 781 782 /** 783 * Determines if the string is a decimal integer number, meaning it contains 784 * nothing but decimal digits. 785 * 786 * @param number the string to check 787 * @return <code>true</code> if the string is a decimal integer number; 788 * <code>false</code> otherwise 789 */ 790 public static boolean isNumber(String number) { 791 if (isNull(number)) { 792 return false; 793 } 794 795 for (char c : number.toCharArray()) { 796 if (!isDigit(c)) { 797 return false; 798 } 799 } 800 801 return true; 802 } 803 804 /** 805 * Determines if the string is a valid password, meaning it is at least four 806 * characters long and contains only letters and decimal digits. 807 * 808 * @return <code>true</code> if the string is a valid password; 809 * <code>false</code> otherwise 810 */ 811 public static boolean isPassword(String password) { 812 if (isNull(password)) { 813 return false; 814 } 815 816 if (password.length() < 4) { 817 return false; 818 } 819 820 for (char c : password.toCharArray()) { 821 if (!isChar(c) && !isDigit(c)) { 822 return false; 823 } 824 } 825 826 return true; 827 } 828 829 /** 830 * Determines if the string is a valid phone number. The only requirement is 831 * that there are decimal digits in the string; length and format are not 832 * checked. 833 * 834 * @param phoneNumber the string to check 835 * @return <code>true</code> if the string is a valid phone number; 836 * <code>false</code> otherwise 837 */ 838 public static boolean isPhoneNumber(String phoneNumber) { 839 return isNumber(StringUtil.extractDigits(phoneNumber)); 840 } 841 842 /** 843 * Determines if the string is a valid URL based on the rules in {@link 844 * java.net.URL}. 845 * 846 * @param url the string to check 847 * @return <code>true</code> if the string is a valid URL; 848 * <code>false</code> otherwise 849 */ 850 public static boolean isUrl(String url) { 851 if (Validator.isNotNull(url)) { 852 if (url.indexOf(CharPool.COLON) == -1) { 853 return false; 854 } 855 856 try { 857 new URL(url); 858 859 return true; 860 } 861 catch (MalformedURLException murle) { 862 } 863 } 864 865 return false; 866 } 867 868 /** 869 * Determines if the string is a valid variable name in Java. 870 * 871 * @param variableName the string to check 872 * @return <code>true</code> if the string is a valid variable name in Java; 873 * <code>false</code> otherwise 874 */ 875 public static boolean isVariableName(String variableName) { 876 if (isNull(variableName)) { 877 return false; 878 } 879 880 Matcher matcher = _variableNamePattern.matcher(variableName); 881 882 if (matcher.matches()) { 883 return true; 884 } 885 else { 886 return false; 887 } 888 } 889 890 /** 891 * Determines if the string is a valid variable term, meaning it begins with 892 * "[$" and ends with "$]". 893 * 894 * @param s the string to check 895 * @return <code>true</code> if the string is a valid variable term; 896 * <code>false</code> otherwise 897 */ 898 public static boolean isVariableTerm(String s) { 899 if (s.startsWith(_VARIABLE_TERM_BEGIN) && 900 s.endsWith(_VARIABLE_TERM_END)) { 901 902 return true; 903 } 904 else { 905 return false; 906 } 907 } 908 909 /** 910 * Determines if the character is whitespace, meaning it is either the 911 * <code>null</code> character '0' or whitespace according to {@link 912 * java.lang.Character#isWhitespace(char)}. 913 * 914 * @param c the character to check 915 * @return <code>true</code> if the character is whitespace; 916 * <code>false</code> otherwise 917 */ 918 public static boolean isWhitespace(char c) { 919 int i = c; 920 921 if ((i == 0) || Character.isWhitespace(c)) { 922 return true; 923 } 924 else { 925 return false; 926 } 927 } 928 929 /** 930 * Determines if the string is an XML document. The only requirement is that 931 * it contain either the xml start tag "<?xml" or the empty document tag 932 * "<root />". 933 * 934 * @param s the string to check 935 * @return <code>true</code> if the string is an XML document; 936 * <code>false</code> otherwise 937 */ 938 public static boolean isXml(String s) { 939 if (s.startsWith(_XML_BEGIN) || s.startsWith(_XML_EMPTY)) { 940 return true; 941 } 942 else { 943 return false; 944 } 945 } 946 947 private static final int _CHAR_BEGIN = 65; 948 949 private static final int _CHAR_END = 122; 950 951 private static final int _DIGIT_BEGIN = 48; 952 953 private static final int _DIGIT_END = 57; 954 955 private static final char[] _EMAIL_ADDRESS_SPECIAL_CHAR = new char[] { 956 '.', '!', '#', '$', '%', '&', '\'', '*', '+', '-', '/', '=', '?', '^', 957 '_', '`', '{', '|', '}', '~' 958 }; 959 960 private static final String _VARIABLE_TERM_BEGIN = "[$"; 961 962 private static final String _VARIABLE_TERM_END = "$]"; 963 964 private static final String _XML_BEGIN = "<?xml"; 965 966 private static final String _XML_EMPTY = "<root />"; 967 968 private static Pattern _emailAddressPattern = Pattern.compile( 969 "[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@" + 970 "(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?"); 971 private static Pattern _ipAddressPattern = Pattern.compile( 972 "\\b" + 973 "((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\." + 974 "((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\." + 975 "((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\." + 976 "((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])" + 977 "\\b"); 978 private static Pattern _variableNamePattern = Pattern.compile( 979 "[_a-zA-Z]+[_a-zA-Z0-9]*"); 980 981 }