001 /** 002 * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved. 003 * 004 * This library is free software; you can redistribute it and/or modify it under 005 * the terms of the GNU Lesser General Public License as published by the Free 006 * Software Foundation; either version 2.1 of the License, or (at your option) 007 * any later version. 008 * 009 * This library is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 011 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 012 * details. 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 * Returns <code>true</code> 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 * Returns <code>true</code> 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 * Returns <code>true</code> 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 * Returns <code>true</code> 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 * Returns <code>true</code> 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 * Returns <code>true</code> 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 * Returns <code>true</code> 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 * Returns <code>true</code> if the objects are either equal, the same 152 * instance, or both <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 * Returns <code>true</code> 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 * Returns <code>true</code> if the string is an email address. The only 190 * requirements are that the string consist of two parts separated by an @ 191 * symbol, and that 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 * Returns <code>true</code> if the string is an alphanumeric name, meaning 221 * it contains 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 * Returns <code>true</code> if the character is in the ASCII character set. 243 * This includes characters with integer values between 32 and 126 244 * (inclusive). 245 * 246 * @param c the character to check 247 * @return <code>true</code> if the character is in the ASCII character set; 248 * <code>false</code> otherwise 249 */ 250 public static boolean isAscii(char c) { 251 int i = c; 252 253 if ((i >= 32) && (i <= 126)) { 254 return true; 255 } 256 else { 257 return false; 258 } 259 } 260 261 /** 262 * Returns <code>true</code> if the character is an upper or lower case 263 * English letter. 264 * 265 * @param c the character to check 266 * @return <code>true</code> if the character is an upper or lower case 267 * English letter; <code>false</code> otherwise 268 */ 269 public static boolean isChar(char c) { 270 int x = c; 271 272 if ((x >= _CHAR_BEGIN) && (x <= _CHAR_END)) { 273 return true; 274 } 275 276 return false; 277 } 278 279 /** 280 * Returns <code>true</code> if string consists only of upper and lower case 281 * English letters. 282 * 283 * @param s the string to check 284 * @return <code>true</code> if the string consists only of upper and lower 285 * case English letters 286 */ 287 public static boolean isChar(String s) { 288 if (isNull(s)) { 289 return false; 290 } 291 292 for (char c : s.toCharArray()) { 293 if (!isChar(c)) { 294 return false; 295 } 296 } 297 298 return true; 299 } 300 301 /** 302 * Returns <code>true</code> if the date is valid in the Gregorian calendar. 303 * 304 * @param month the month to check 305 * @param day the day to check 306 * @return <code>true</code> if the date is valid in the Gregorian calendar; 307 * <code>false</code> otherwise 308 */ 309 public static boolean isDate(int month, int day, int year) { 310 return isGregorianDate(month, day, year); 311 } 312 313 /** 314 * Returns <code>true</code> if the character is a digit between 0 and 9 315 * (inclusive). 316 * 317 * @param c the character to check 318 * @return <code>true</code> if the character is a digit between 0 and 9 319 * (inclusive); <code>false</code> otherwise 320 */ 321 public static boolean isDigit(char c) { 322 int x = c; 323 324 if ((x >= _DIGIT_BEGIN) && (x <= _DIGIT_END)) { 325 return true; 326 } 327 328 return false; 329 } 330 331 /** 332 * Returns <code>true</code> if the string consists of only digits between 0 333 * and 9 (inclusive). 334 * 335 * @param s the string to check 336 * @return <code>true</code> if the string consists of only digits between 0 337 * and 9 (inclusive); <code>false</code> otherwise 338 */ 339 public static boolean isDigit(String s) { 340 if (isNull(s)) { 341 return false; 342 } 343 344 for (char c : s.toCharArray()) { 345 if (!isDigit(c)) { 346 return false; 347 } 348 } 349 350 return true; 351 } 352 353 /** 354 * Returns <code>true</code> if the string is a valid domain name. See 355 * RFC-1034 (section 3), RFC-1123 (section 2.1), and RFC-952 (section B. 356 * Lexical grammar). 357 * 358 * @param domainName the string to check 359 * @return <code>true</code> if the string is a valid domain name; 360 * <code>false</code> otherwise 361 */ 362 public static boolean isDomain(String domainName) { 363 364 // See RFC-1034 (section 3), RFC-1123 (section 2.1), and RFC-952 365 // (section B. Lexical grammar) 366 367 if (isNull(domainName)) { 368 return false; 369 } 370 371 if (domainName.length() > 255) { 372 return false; 373 } 374 375 String[] domainNameArray = StringUtil.split( 376 domainName, CharPool.PERIOD); 377 378 for (String domainNamePart : domainNameArray) { 379 char[] domainNamePartCharArray = domainNamePart.toCharArray(); 380 381 for (int i = 0; i < domainNamePartCharArray.length; i++) { 382 char c = domainNamePartCharArray[i]; 383 384 if ((i == 0) && (c == CharPool.DASH)) { 385 return false; 386 } 387 else if ((i == (domainNamePartCharArray.length - 1)) && 388 (c == CharPool.DASH)) { 389 390 return false; 391 } 392 else if ((!isChar(c)) && (!isDigit(c)) && 393 (c != CharPool.DASH)) { 394 395 return false; 396 } 397 } 398 } 399 400 return true; 401 } 402 403 /** 404 * Returns <code>true</code> if the string is a valid email address. 405 * 406 * @param emailAddress the string to check 407 * @return <code>true</code> if the string is a valid email address; 408 * <code>false</code> otherwise 409 */ 410 public static boolean isEmailAddress(String emailAddress) { 411 Matcher matcher = _emailAddressPattern.matcher(emailAddress); 412 413 return matcher.matches(); 414 } 415 416 /** 417 * Returns <code>true</code> if the character is a special character in an 418 * email address. 419 * 420 * @param c the character to check 421 * @return <code>true</code> if the character is a special character in an 422 * email address; <code>false</code> otherwise 423 */ 424 public static boolean isEmailAddressSpecialChar(char c) { 425 426 // LEP-1445 427 428 for (int i = 0; i < _EMAIL_ADDRESS_SPECIAL_CHAR.length; i++) { 429 if (c == _EMAIL_ADDRESS_SPECIAL_CHAR[i]) { 430 return true; 431 } 432 } 433 434 return false; 435 } 436 437 /** 438 * Returns <code>true</code> if the date is valid in the Gregorian calendar. 439 * 440 * @param month the month (0-based, meaning 0 for January) 441 * @param day the day of the month 442 * @param year the year 443 * @return <code>true</code> if the date is valid; <code>false</code> 444 * otherwise 445 */ 446 public static boolean isGregorianDate(int month, int day, int year) { 447 if ((month < 0) || (month > 11)) { 448 return false; 449 } 450 451 int[] months = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 452 453 if (month == 1) { 454 int febMax = 28; 455 456 if (((year % 4) == 0) && ((year % 100) != 0) || 457 ((year % 400) == 0)) { 458 459 febMax = 29; 460 } 461 462 if ((day < 1) || (day > febMax)) { 463 return false; 464 } 465 } 466 else if ((day < 1) || (day > months[month])) { 467 return false; 468 } 469 470 return true; 471 } 472 473 /** 474 * Returns <code>true</code> if the string is a hexidecimal number. At 475 * present the only requirement is that the string is not <code>null</code>; 476 * it does not actually check the format of the string. 477 * 478 * @param s the string to check 479 * @return <code>true</code> if the string is a hexidecimal number; 480 * <code>false</code> otherwise 481 * @see #isNull(String) 482 */ 483 public static boolean isHex(String s) { 484 if (isNull(s)) { 485 return false; 486 } 487 488 return true; 489 } 490 491 /** 492 * Returns <code>true</code> if the string is an HTML document. The only 493 * requirement is that it contain the opening and closing html tags. 494 * 495 * @param s the string to check 496 * @return <code>true</code> if the string is an HTML document; 497 * <code>false</code> otherwise 498 */ 499 public static boolean isHTML(String s) { 500 if (isNull(s)) { 501 return false; 502 } 503 504 if (((s.indexOf("<html>") != -1) || (s.indexOf("<HTML>") != -1)) && 505 ((s.indexOf("</html>") != -1) || (s.indexOf("</HTML>") != -1))) { 506 507 return true; 508 } 509 510 return false; 511 } 512 513 /** 514 * Returns <code>true</code> if the string is a valid IPv4 IP address. 515 * 516 * @param ipAddress the string to check 517 * @return <code>true</code> if the string is an IPv4 IP address; 518 * <code>false</code> otherwise 519 */ 520 public static boolean isIPAddress(String ipAddress) { 521 Matcher matcher = _ipAddressPattern.matcher(ipAddress); 522 523 return matcher.matches(); 524 } 525 526 /** 527 * Returns <code>true</code> if the date is valid in the Julian calendar. 528 * 529 * @param month the month (0-based, meaning 0 for January) 530 * @param day the day of the month 531 * @param year the year 532 * @return <code>true</code> if the date is valid; <code>false</code> 533 * otherwise 534 */ 535 public static boolean isJulianDate(int month, int day, int year) { 536 if ((month < 0) || (month > 11)) { 537 return false; 538 } 539 540 int[] months = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 541 542 if (month == 1) { 543 int febMax = 28; 544 545 if ((year % 4) == 0) { 546 febMax = 29; 547 } 548 549 if ((day < 1) || (day > febMax)) { 550 return false; 551 } 552 } 553 else if ((day < 1) || (day > months[month])) { 554 return false; 555 } 556 557 return true; 558 } 559 560 /** 561 * Returns <code>true</code> if the string contains a valid number according 562 * to the Luhn algorithm, commonly used to validate credit card numbers. 563 * 564 * @param number the string to check 565 * @return <code>true</code> if the string contains a valid number according 566 * to the Luhn algorithm; <code>false</code> otherwise 567 */ 568 public static boolean isLUHN(String number) { 569 if (number == null) { 570 return false; 571 } 572 573 number = StringUtil.reverse(number); 574 575 int total = 0; 576 577 for (int i = 0; i < number.length(); i++) { 578 int x = 0; 579 580 if (((i + 1) % 2) == 0) { 581 x = Integer.parseInt(number.substring(i, i + 1)) * 2; 582 583 if (x >= 10) { 584 String s = String.valueOf(x); 585 586 x = Integer.parseInt(s.substring(0, 1)) + 587 Integer.parseInt(s.substring(1, 2)); 588 } 589 } 590 else { 591 x = Integer.parseInt(number.substring(i, i + 1)); 592 } 593 594 total = total + x; 595 } 596 597 if ((total % 10) == 0) { 598 return true; 599 } 600 else { 601 return false; 602 } 603 } 604 605 /** 606 * Returns <code>true</code> if the string is a name, meaning it contains 607 * nothing but English letters and spaces. 608 * 609 * @param name the string to check 610 * @return <code>true</code> if the string is a name; <code>false</code> 611 * otherwise 612 */ 613 public static boolean isName(String name) { 614 if (isNull(name)) { 615 return false; 616 } 617 618 for (char c : name.trim().toCharArray()) { 619 if (!isChar(c) && !Character.isWhitespace(c)) { 620 return false; 621 } 622 } 623 624 return true; 625 } 626 627 /** 628 * Returns <code>true</code> if the long number object is not 629 * <code>null</code>, meaning it is neither a <code>null</code> reference or 630 * zero. 631 * 632 * @param l the long number object to check 633 * @return <code>true</code> if the long number object is not 634 * <code>null</code>; <code>false</code> otherwise 635 */ 636 public static boolean isNotNull(Long l) { 637 return !isNull(l); 638 } 639 640 /** 641 * Returns <code>true</code> if the object is not <code>null</code>, using 642 * the rules from {@link #isNotNull(Long)} or {@link #isNotNull(String)} if 643 * the object is one of these types. 644 * 645 * @param obj the object to check 646 * @return <code>true</code> if the object is not <code>null</code>; 647 * <code>false</code> otherwise 648 */ 649 public static boolean isNotNull(Object obj) { 650 return !isNull(obj); 651 } 652 653 /** 654 * Returns <code>true</code> if the array is not <code>null</code>, meaning 655 * it is neither a <code>null</code> reference or empty. 656 * 657 * @param array the array to check 658 * @return <code>true</code> if the array is not <code>null</code>; 659 * <code>false</code> otherwise 660 */ 661 public static boolean isNotNull(Object[] array) { 662 return !isNull(array); 663 } 664 665 /** 666 * Returns <code>true</code> if the string is not <code>null</code>, meaning 667 * it is not a <code>null</code> reference, nothing but spaces, or the 668 * string "<code>null</code>". 669 * 670 * @param s the string to check 671 * @return <code>true</code> if the string is not <code>null</code>; 672 * <code>false</code> otherwise 673 */ 674 public static boolean isNotNull(String s) { 675 return !isNull(s); 676 } 677 678 /** 679 * Returns <code>true</code> if the long number object is <code>null</code>, 680 * meaning it is either a <code>null</code> reference or zero. 681 * 682 * @param l the long number object to check 683 * @return <code>true</code> if the long number object is <code>null</code>; 684 * <code>false</code> otherwise 685 */ 686 public static boolean isNull(Long l) { 687 if ((l == null) || (l.longValue() == 0)) { 688 return true; 689 } 690 else { 691 return false; 692 } 693 } 694 695 /** 696 * Returns <code>true</code> if the object is <code>null</code>, using the 697 * rules from {@link #isNull(Long)} or {@link #isNull(String)} if the object 698 * is one of these types. 699 * 700 * @param obj the object to check 701 * @return <code>true</code> if the object is <code>null</code>; 702 * <code>false</code> otherwise 703 */ 704 public static boolean isNull(Object obj) { 705 if (obj instanceof Long) { 706 return isNull((Long)obj); 707 } 708 else if (obj instanceof String) { 709 return isNull((String)obj); 710 } 711 else if (obj == null) { 712 return true; 713 } 714 else { 715 return false; 716 } 717 } 718 719 /** 720 * Returns <code>true</code> if the array is <code>null</code>, meaning it 721 * is either a <code>null</code> reference or empty. 722 * 723 * @param array the array to check 724 * @return <code>true</code> if the array is <code>null</code>; 725 * <code>false</code> otherwise 726 */ 727 public static boolean isNull(Object[] array) { 728 if ((array == null) || (array.length == 0)) { 729 return true; 730 } 731 else { 732 return false; 733 } 734 } 735 736 /** 737 * Returns <code>true</code> if the string is <code>null</code>, meaning it 738 * is a <code>null</code> reference, nothing but spaces, or the string 739 * "<code>null</code>". 740 * 741 * @param s the string to check 742 * @return <code>true</code> if the string is <code>null</code>; 743 * <code>false</code> otherwise 744 */ 745 public static boolean isNull(String s) { 746 if (s == null) { 747 return true; 748 } 749 750 int counter = 0; 751 752 for (int i = 0; i < s.length(); i++) { 753 char c = s.charAt(i); 754 755 if (c == CharPool.SPACE) { 756 continue; 757 } 758 else if (counter > 3) { 759 return false; 760 } 761 762 if (counter == 0) { 763 if (c != CharPool.LOWER_CASE_N) { 764 return false; 765 } 766 } 767 else if (counter == 1) { 768 if (c != CharPool.LOWER_CASE_U) { 769 return false; 770 } 771 } 772 else if ((counter == 2) || (counter == 3)) { 773 if (c != CharPool.LOWER_CASE_L) { 774 return false; 775 } 776 } 777 778 counter++; 779 } 780 781 if ((counter == 0) || (counter == 4)) { 782 return true; 783 } 784 785 return false; 786 } 787 788 /** 789 * Returns <code>true</code> if the string is a decimal integer number, 790 * meaning it contains nothing but decimal digits. 791 * 792 * @param number the string to check 793 * @return <code>true</code> if the string is a decimal integer number; 794 * <code>false</code> otherwise 795 */ 796 public static boolean isNumber(String number) { 797 if (isNull(number)) { 798 return false; 799 } 800 801 for (char c : number.toCharArray()) { 802 if (!isDigit(c)) { 803 return false; 804 } 805 } 806 807 return true; 808 } 809 810 /** 811 * Returns <code>true</code> if the string is a valid password, meaning it 812 * is at least four characters long and contains only letters and decimal 813 * digits. 814 * 815 * @return <code>true</code> if the string is a valid password; 816 * <code>false</code> otherwise 817 */ 818 public static boolean isPassword(String password) { 819 if (isNull(password)) { 820 return false; 821 } 822 823 if (password.length() < 4) { 824 return false; 825 } 826 827 for (char c : password.toCharArray()) { 828 if (!isChar(c) && !isDigit(c)) { 829 return false; 830 } 831 } 832 833 return true; 834 } 835 836 /** 837 * Returns <code>true</code> if the string is a valid phone number. The only 838 * requirement is that there are decimal digits in the string; length and 839 * format are not checked. 840 * 841 * @param phoneNumber the string to check 842 * @return <code>true</code> if the string is a valid phone number; 843 * <code>false</code> otherwise 844 */ 845 public static boolean isPhoneNumber(String phoneNumber) { 846 return isNumber(StringUtil.extractDigits(phoneNumber)); 847 } 848 849 /** 850 * Returns <code>true</code> if the string is a valid URL based on the rules 851 * in {@link java.net.URL}. 852 * 853 * @param url the string to check 854 * @return <code>true</code> if the string is a valid URL; 855 * <code>false</code> otherwise 856 */ 857 public static boolean isUrl(String url) { 858 if (Validator.isNotNull(url)) { 859 if (url.indexOf(CharPool.COLON) == -1) { 860 return false; 861 } 862 863 try { 864 new URL(url); 865 866 return true; 867 } 868 catch (MalformedURLException murle) { 869 } 870 } 871 872 return false; 873 } 874 875 /** 876 * Returns <code>true</code> if the string is a valid variable name in Java. 877 * 878 * @param variableName the string to check 879 * @return <code>true</code> if the string is a valid variable name in Java; 880 * <code>false</code> otherwise 881 */ 882 public static boolean isVariableName(String variableName) { 883 if (isNull(variableName)) { 884 return false; 885 } 886 887 Matcher matcher = _variableNamePattern.matcher(variableName); 888 889 if (matcher.matches()) { 890 return true; 891 } 892 else { 893 return false; 894 } 895 } 896 897 /** 898 * Returns <code>true</code> if the string is a valid variable term, meaning 899 * it begins with "[$" and ends with "$]". 900 * 901 * @param s the string to check 902 * @return <code>true</code> if the string is a valid variable term; 903 * <code>false</code> otherwise 904 */ 905 public static boolean isVariableTerm(String s) { 906 if (s.startsWith(_VARIABLE_TERM_BEGIN) && 907 s.endsWith(_VARIABLE_TERM_END)) { 908 909 return true; 910 } 911 else { 912 return false; 913 } 914 } 915 916 /** 917 * Returns <code>true</code> if the character is whitespace, meaning it is 918 * either the <code>null</code> character '0' or whitespace according to 919 * {@link java.lang.Character#isWhitespace(char)}. 920 * 921 * @param c the character to check 922 * @return <code>true</code> if the character is whitespace; 923 * <code>false</code> otherwise 924 */ 925 public static boolean isWhitespace(char c) { 926 int i = c; 927 928 if ((i == 0) || Character.isWhitespace(c)) { 929 return true; 930 } 931 else { 932 return false; 933 } 934 } 935 936 /** 937 * Returns <code>true</code> if the string is an XML document. The only 938 * requirement is that it contain either the xml start tag "<?xml" or the 939 * empty document tag "<root />". 940 * 941 * @param s the string to check 942 * @return <code>true</code> if the string is an XML document; 943 * <code>false</code> otherwise 944 */ 945 public static boolean isXml(String s) { 946 if (s.startsWith(_XML_BEGIN) || s.startsWith(_XML_EMPTY)) { 947 return true; 948 } 949 else { 950 return false; 951 } 952 } 953 954 private static final int _CHAR_BEGIN = 65; 955 956 private static final int _CHAR_END = 122; 957 958 private static final int _DIGIT_BEGIN = 48; 959 960 private static final int _DIGIT_END = 57; 961 962 private static final char[] _EMAIL_ADDRESS_SPECIAL_CHAR = new char[] { 963 '.', '!', '#', '$', '%', '&', '\'', '*', '+', '-', '/', '=', '?', '^', 964 '_', '`', '{', '|', '}', '~' 965 }; 966 967 private static final String _VARIABLE_TERM_BEGIN = "[$"; 968 969 private static final String _VARIABLE_TERM_END = "$]"; 970 971 private static final String _XML_BEGIN = "<?xml"; 972 973 private static final String _XML_EMPTY = "<root />"; 974 975 private static Pattern _emailAddressPattern = Pattern.compile( 976 "[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@" + 977 "(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?"); 978 private static Pattern _ipAddressPattern = Pattern.compile( 979 "\\b" + 980 "((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\." + 981 "((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\." + 982 "((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\." + 983 "((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])" + 984 "\\b"); 985 private static Pattern _variableNamePattern = Pattern.compile( 986 "[_a-zA-Z]+[_a-zA-Z0-9]*"); 987 988 }