PageRenderTime 47ms CodeModel.GetById 18ms app.highlight 24ms RepoModel.GetById 0ms app.codeStats 0ms

/portal-service/src/com/liferay/portal/kernel/util/Validator.java

https://github.com/spreddy/liferay-portal
Java | 988 lines | 477 code | 132 blank | 379 comment | 192 complexity | 6688748929d626e1cbad37ccef7ecf0e MD5 | raw file
  1/**
  2 * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
  3 *
  4 * This library is free software; you can redistribute it and/or modify it under
  5 * the terms of the GNU Lesser General Public License as published by the Free
  6 * Software Foundation; either version 2.1 of the License, or (at your option)
  7 * any later version.
  8 *
  9 * This library is distributed in the hope that it will be useful, but WITHOUT
 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 11 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 12 * details.
 13 */
 14
 15package com.liferay.portal.kernel.util;
 16
 17import java.net.MalformedURLException;
 18import java.net.URL;
 19
 20import java.util.regex.Matcher;
 21import java.util.regex.Pattern;
 22
 23/**
 24 * Provides utility methods related to data validation and format checking.
 25 *
 26 * @author Brian Wing Shun Chan
 27 * @author Alysa Carver
 28 */
 29public class Validator {
 30
 31	/**
 32	 * Returns <code>true</code> if the booleans are equal.
 33	 *
 34	 * @param  boolean1 the first boolean
 35	 * @param  boolean2 the second boolean
 36	 * @return <code>true</code> if the booleans are equal; <code>false</code>
 37	 *         otherwise
 38	 */
 39	public static boolean equals(boolean boolean1, boolean boolean2) {
 40		if (boolean1 == boolean2) {
 41			return true;
 42		}
 43		else {
 44			return false;
 45		}
 46	}
 47
 48	/**
 49	 * Returns <code>true</code> if the bytes are equal.
 50	 *
 51	 * @param  byte1 the first byte
 52	 * @param  byte2 the second byte
 53	 * @return <code>true</code> if the bytes are equal; <code>false</code>
 54	 *         otherwise
 55	 */
 56	public static boolean equals(byte byte1, byte byte2) {
 57		if (byte1 == byte2) {
 58			return true;
 59		}
 60		else {
 61			return false;
 62		}
 63	}
 64
 65	/**
 66	 * Returns <code>true</code> if the characters are equal.
 67	 *
 68	 * @param  char1 the first character
 69	 * @param  char2 the second character
 70	 * @return <code>true</code> if the characters are equal; <code>false</code>
 71	 *         otherwise
 72	 */
 73	public static boolean equals(char char1, char char2) {
 74		if (char1 == char2) {
 75			return true;
 76		}
 77		else {
 78			return false;
 79		}
 80	}
 81
 82	/**
 83	 * Returns <code>true</code> if the doubles are equal.
 84	 *
 85	 * @param  double1 the first double
 86	 * @param  double2 the second double
 87	 * @return <code>true</code> if the doubles are equal; <code>false</code>
 88	 *         otherwise
 89	 */
 90	public static boolean equals(double double1, double double2) {
 91		if (Double.compare(double1, double2) == 0) {
 92			return true;
 93		}
 94		else {
 95			return false;
 96		}
 97	}
 98
 99	/**
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}