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    }