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