0001: /*
0002: * $Id: UtilValidate.java,v 1.5 2003/12/17 21:30:02 ajzeneski Exp $
0003: *
0004: * Copyright (c) 2001 The Open For Business Project - www.ofbiz.org
0005: *
0006: * Permission is hereby granted, free of charge, to any person obtaining a
0007: * copy of this software and associated documentation files (the "Software"),
0008: * to deal in the Software without restriction, including without limitation
0009: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0010: * and/or sell copies of the Software, and to permit persons to whom the
0011: * Software is furnished to do so, subject to the following conditions:
0012: *
0013: * The above copyright notice and this permission notice shall be included
0014: * in all copies or substantial portions of the Software.
0015: *
0016: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
0017: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
0018: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
0019: * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
0020: * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
0021: * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
0022: * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0023: */
0024: package org.ofbiz.base.util;
0025:
0026: import java.util.Calendar;
0027: import java.util.Collection;
0028:
0029: /**
0030: * General input/data validation methods
0031: * Utility methods for validating data, especially input.
0032: * See detailed description below.
0033: *
0034: * @author <a href="mailto:jonesde@ofbiz.org">David E. Jones</a>
0035: * @version $Revision: 1.5 $
0036: * @since 1.0
0037: *
0038: *
0039: * <br> SUMMARY
0040: * <br>
0041: * <br> This is a set of meethods for validating input. Functions are provided to validate:
0042: * <br> - U.S. and international phone/fax numbers
0043: * <br> - U.S. ZIP codes(5 or 9 digit postal codes)
0044: * <br> - U.S. Postal Codes(2 letter abbreviations for names of states)
0045: * <br> - U.S. Social Security Numbers(abbreviated as SSNs)
0046: * <br> - email addresses
0047: * <br> - dates(entry of year, month, and day and validity of combined date)
0048: * <br> - credit card numbers
0049: * <br>
0050: * <br> Supporting utility functions validate that:
0051: * <br> - characters are Letter, Digit, or LetterOrDigit
0052: * <br> - strings are a Signed, Positive, Negative, Nonpositive, or Nonnegative integer
0053: * <br> - strings are a Float or a SignedFloat
0054: * <br> - strings are Alphabetic, Alphanumeric, or Whitespace
0055: * <br> - strings contain an integer within a specified range
0056: * <br>
0057: * <br> Other utility functions are provided to:
0058: * <br> - remove from a string characters which are/are not in a "bag" of selected characters
0059: * <br> - strip whitespace/leading whitespace from a string
0060: * <br>
0061: * <br> ==============================================================================
0062: * <br> NOTE: This code was adapted from the Netscape JavaScript form validation code,
0063: * <br> usually found in "FormChek.js". Credit card verification functions Originally
0064: * <br< included as Starter Application 1.0.0 in LivePayment.
0065: * <br> ==============================================================================
0066: */
0067: public class UtilValidate {
0068:
0069: public static final String module = UtilValidate.class.getName();
0070:
0071: /** boolean specifying by default whether or not it is okay for a String to be empty */
0072: public static final boolean defaultEmptyOK = true;
0073:
0074: /** digit characters */
0075: public static final String digits = "0123456789";
0076:
0077: /** lower-case letter characters */
0078: public static final String lowercaseLetters = "abcdefghijklmnopqrstuvwxyz";
0079:
0080: /** upper-case letter characters */
0081: public static final String uppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
0082:
0083: /** letter characters */
0084: public static final String letters = lowercaseLetters
0085: + uppercaseLetters;
0086:
0087: /** whitespace characters */
0088: public static final String whitespace = " \t\n\r";
0089:
0090: /** decimal point character differs by language and culture */
0091: public static final String decimalPointDelimiter = ".";
0092:
0093: /** non-digit characters which are allowed in phone numbers */
0094: public static final String phoneNumberDelimiters = "()- ";
0095:
0096: /** characters which are allowed in US phone numbers */
0097: public static final String validUSPhoneChars = digits
0098: + phoneNumberDelimiters;
0099:
0100: /** characters which are allowed in international phone numbers(a leading + is OK) */
0101: public static final String validWorldPhoneChars = digits
0102: + phoneNumberDelimiters + "+";
0103:
0104: /** non-digit characters which are allowed in Social Security Numbers */
0105: public static final String SSNDelimiters = "- ";
0106:
0107: /** characters which are allowed in Social Security Numbers */
0108: public static final String validSSNChars = digits + SSNDelimiters;
0109:
0110: /** U.S. Social Security Numbers have 9 digits. They are formatted as 123-45-6789. */
0111: public static final int digitsInSocialSecurityNumber = 9;
0112:
0113: /** U.S. phone numbers have 10 digits. They are formatted as 123 456 7890 or(123) 456-7890. */
0114: public static final int digitsInUSPhoneNumber = 10;
0115: public static final int digitsInUSPhoneAreaCode = 3;
0116: public static final int digitsInUSPhoneMainNumber = 7;
0117:
0118: /** non-digit characters which are allowed in ZIP Codes */
0119: public static final String ZipCodeDelimiters = "-";
0120:
0121: /** our preferred delimiter for reformatting ZIP Codes */
0122: public static final String ZipCodeDelimeter = "-";
0123:
0124: /** characters which are allowed in Social Security Numbers */
0125: public static final String validZipCodeChars = digits
0126: + ZipCodeDelimiters;
0127:
0128: /** U.S. ZIP codes have 5 or 9 digits. They are formatted as 12345 or 12345-6789. */
0129: public static final int digitsInZipCode1 = 5;
0130:
0131: /** U.S. ZIP codes have 5 or 9 digits. They are formatted as 12345 or 12345-6789. */
0132: public static final int digitsInZipCode2 = 9;
0133:
0134: /** non-digit characters which are allowed in credit card numbers */
0135: public static final String creditCardDelimiters = " -";
0136:
0137: public static final String isNotEmptyMsg = "This field cannot be empty, please enter a value.";
0138: public static final String isStateCodeMsg = "The State Code must be a valid two character U.S. state abbreviation(like CA for California).";
0139: public static final String isContiguousStateCodeMsg = "The State Code must be a valid two character U.S. state abbreviation for one of the 48 contiguous United States (like CA for California).";
0140: public static final String isZipCodeMsg = "The ZIP Code must be a 5 or 9 digit U.S. ZIP Code(like 94043).";
0141: public static final String isUSPhoneMsg = "The US Phone must be a 10 digit U.S. phone number(like 415-555-1212).";
0142: public static final String isUSPhoneAreaCodeMsg = "The Phone Number Area Code must be 3 digits.";
0143: public static final String isUSPhoneMainNumberMsg = "The Phone Number must be 7 digits.";
0144: public static final String isContiguousZipCodeMsg = "Zip Code is not a valid Zip Code for one of the 48 contiguous United States .";
0145: public static final String isInternationalPhoneNumberMsg = "The World Phone must be a valid international phone number.";
0146: public static final String isSSNMsg = "The SSN must be a 9 digit U.S. social security number(like 123-45-6789).";
0147: public static final String isEmailMsg = "The Email must be a valid email address(like john@email.com). Please re-enter it now.";
0148: public static final String isAnyCardMsg = "The credit card number is not a valid card number.";
0149: public static final String isCreditCardPrefixMsg = " is not a valid ";
0150: public static final String isCreditCardSuffixMsg = " credit card number.";
0151: public static final String isDayMsg = "The Day must be a day number between 1 and 31. ";
0152: public static final String isMonthMsg = "The Month must be a month number between 1 and 12. ";
0153: public static final String isYearMsg = "The Year must be a 2 or 4 digit year number. ";
0154: public static final String isDatePrefixMsg = "The Day, Month, and Year for ";
0155: public static final String isDateSuffixMsg = " do not form a valid date. Please reenter them now.";
0156: public static final String isHourMsg = "The Hour must be a number between 0 and 23.";
0157: public static final String isMinuteMsg = "The Hour must be a number between 0 and 59.";
0158: public static final String isSecondMsg = "The Hour must be a number between 0 and 59.";
0159: public static final String isTimeMsg = "The Time must be a valid time formed like: HH:MM or HH:MM:SS.";
0160: public static final String isDateMsg = "The Date must be a valid date formed like: MM/YY, MM/YYYY, MM/DD/YY, or MM/DD/YYYY.";
0161: public static final String isDateAfterToday = "The Date must be a valid date after today, and formed like: MM/YY, MM/YYYY, MM/DD/YY, or MM/DD/YYYY.";
0162: public static final String isIntegerMsg = "The Number must be a valid unsigned whole decimal number.";
0163: public static final String isSignedIntegerMsg = "The Number must be a valid signed whole decimal number.";
0164: public static final String isLongMsg = "The Number must be a valid unsigned whole decimal number.";
0165: public static final String isSignedLongMsg = "The Number must be a valid signed whole decimal number.";
0166: public static final String isFloatMsg = "The Number must be a valid unsigned decimal number.";
0167: public static final String isSignedFloatMsg = "The Number must be a valid signed decimal number.";
0168: public static final String isSignedDoubleMsg = "The Number must be a valid signed decimal number.";
0169:
0170: /** An array of ints representing the number of days in each month of the year.
0171: * Note: February varies depending on the year */
0172: public static final int[] daysInMonth = { 31, 29, 31, 30, 31, 30,
0173: 31, 31, 30, 31, 30, 31 };
0174:
0175: /** Delimiter for USStateCodes String */
0176: public static final String USStateCodeDelimiter = "|";
0177:
0178: /** Valid U.S. Postal Codes for states, territories, armed forces, etc.
0179: * See http://www.usps.gov/ncsc/lookups/abbr_state.txt. */
0180: public static final String USStateCodes = "AL|AK|AS|AZ|AR|CA|CO|CT|DE|DC|FM|FL|GA|GU|HI|ID|IL|IN|IA|KS|KY|LA|ME|MH|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|MP|OH|OK|OR|PW|PA|PR|RI|SC|SD|TN|TX|UT|VT|VI|VA|WA|WV|WI|WY|AE|AA|AE|AE|AP";
0181:
0182: /** Valid contiguous U.S. postal codes */
0183: public static final String ContiguousUSStateCodes = "AL|AZ|AR|CA|CO|CT|DE|DC|FL|GA|ID|IL|IN|IA|KS|KY|LA|ME|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|OH|OK|OR|PA|RI|SC|SD|TN|TX|UT|VT|VA|WA|WV|WI|WY";
0184:
0185: public static boolean areEqual(Object obj, Object obj2) {
0186: if (obj == null) {
0187: return obj2 == null;
0188: } else {
0189: return obj.equals(obj2);
0190: }
0191: }
0192:
0193: /** Check whether string s is empty. */
0194: public static boolean isEmpty(String s) {
0195: return ((s == null) || (s.length() == 0));
0196: }
0197:
0198: /** Check whether collection c is empty. */
0199: public static boolean isEmpty(Collection c) {
0200: return ((c == null) || (c.size() == 0));
0201: }
0202:
0203: /** Check whether string s is NOT empty. */
0204: public static boolean isNotEmpty(String s) {
0205: return ((s != null) && (s.length() > 0));
0206: }
0207:
0208: /** Check whether collection c is NOT empty. */
0209: public static boolean isNotEmpty(Collection c) {
0210: return ((c != null) && (c.size() > 0));
0211: }
0212:
0213: /** Returns true if string s is empty or whitespace characters only. */
0214: public static boolean isWhitespace(String s) {
0215: // Is s empty?
0216: if (isEmpty(s))
0217: return true;
0218:
0219: // Search through string's characters one by one
0220: // until we find a non-whitespace character.
0221: // When we do, return false; if we don't, return true.
0222: for (int i = 0; i < s.length(); i++) {
0223: // Check that current character isn't whitespace.
0224: char c = s.charAt(i);
0225:
0226: if (whitespace.indexOf(c) == -1)
0227: return false;
0228: }
0229: // All characters are whitespace.
0230: return true;
0231: }
0232:
0233: /** Removes all characters which appear in string bag from string s. */
0234: public static String stripCharsInBag(String s, String bag) {
0235: int i;
0236: String returnString = "";
0237:
0238: // Search through string's characters one by one.
0239: // If character is not in bag, append to returnString.
0240: for (i = 0; i < s.length(); i++) {
0241: char c = s.charAt(i);
0242:
0243: if (bag.indexOf(c) == -1)
0244: returnString += c;
0245: }
0246: return returnString;
0247: }
0248:
0249: /** Removes all characters which do NOT appear in string bag from string s. */
0250: public static String stripCharsNotInBag(String s, String bag) {
0251: int i;
0252: String returnString = "";
0253:
0254: // Search through string's characters one by one.
0255: // If character is in bag, append to returnString.
0256: for (i = 0; i < s.length(); i++) {
0257: char c = s.charAt(i);
0258:
0259: if (bag.indexOf(c) != -1)
0260: returnString += c;
0261: }
0262: return returnString;
0263: }
0264:
0265: /** Removes all whitespace characters from s.
0266: * Member whitespace(see above) defines which characters are considered whitespace. */
0267: public static String stripWhitespace(String s) {
0268: return stripCharsInBag(s, whitespace);
0269: }
0270:
0271: /** Returns true if single character c(actually a string) is contained within string s. */
0272: public static boolean charInString(char c, String s) {
0273: return (s.indexOf(c) != -1);
0274: // for(int i = 0; i < s.length; i++) {
0275: // if(s.charAt(i) == c) return true;
0276: // }
0277: // return false;
0278: }
0279:
0280: /** Removes initial(leading) whitespace characters from s.
0281: * Member whitespace(see above) defines which characters are considered whitespace. */
0282: public static String stripInitialWhitespace(String s) {
0283: int i = 0;
0284:
0285: while ((i < s.length())
0286: && charInString(s.charAt(i), whitespace))
0287: i++;
0288: return s.substring(i);
0289: // return s.substring(i, s.length);
0290: }
0291:
0292: /** Returns true if character c is an English letter (A .. Z, a..z).
0293: *
0294: * NOTE: Need i18n version to support European characters.
0295: * This could be tricky due to different character
0296: * sets and orderings for various languages and platforms. */
0297: public static boolean isLetter(char c) {
0298: return Character.isLetter(c);
0299: }
0300:
0301: /** Returns true if character c is a digit (0 .. 9). */
0302: public static boolean isDigit(char c) {
0303: return Character.isDigit(c);
0304: }
0305:
0306: /** Returns true if character c is a letter or digit. */
0307: public static boolean isLetterOrDigit(char c) {
0308: return Character.isLetterOrDigit(c);
0309: }
0310:
0311: /** Returns true if all characters in string s are numbers.
0312: *
0313: * Accepts non-signed integers only. Does not accept floating
0314: * point, exponential notation, etc.
0315: */
0316: public static boolean isInteger(String s) {
0317: if (isEmpty(s))
0318: return defaultEmptyOK;
0319:
0320: // Search through string's characters one by one
0321: // until we find a non-numeric character.
0322: // When we do, return false; if we don't, return true.
0323: for (int i = 0; i < s.length(); i++) {
0324: // Check that current character is number.
0325: char c = s.charAt(i);
0326:
0327: if (!isDigit(c))
0328: return false;
0329: }
0330:
0331: // All characters are numbers.
0332: return true;
0333: }
0334:
0335: /** Returns true if all characters are numbers;
0336: * first character is allowed to be + or - as well.
0337: *
0338: * Does not accept floating point, exponential notation, etc.
0339: */
0340: public static boolean isSignedInteger(String s) {
0341: if (isEmpty(s))
0342: return defaultEmptyOK;
0343:
0344: try {
0345: int temp = Integer.parseInt(s);
0346:
0347: return true;
0348: } catch (Exception e) {
0349: return false;
0350: }
0351:
0352: // int startPos = 0;
0353: // boolean secondArg = defaultEmptyOK;
0354:
0355: // if(isSignedInteger.arguments.length > 1) secondArg = isSignedInteger.arguments[1];
0356:
0357: // skip leading + or -
0358: // if((s.charAt(0) == "-") ||(s.charAt(0) == "+") ) startPos = 1;
0359: // return(isInteger(s.substring(startPos, s.length), secondArg))
0360: }
0361:
0362: /** Returns true if all characters are numbers;
0363: * first character is allowed to be + or - as well.
0364: *
0365: * Does not accept floating point, exponential notation, etc.
0366: */
0367: public static boolean isSignedLong(String s) {
0368: if (isEmpty(s))
0369: return defaultEmptyOK;
0370:
0371: try {
0372: long temp = Long.parseLong(s);
0373:
0374: return true;
0375: } catch (Exception e) {
0376: return false;
0377: }
0378: }
0379:
0380: /** Returns true if string s is an integer > 0. NOTE: using the Java Long object for greatest precision */
0381: public static boolean isPositiveInteger(String s) {
0382: if (isEmpty(s))
0383: return defaultEmptyOK;
0384:
0385: try {
0386: long temp = Long.parseLong(s);
0387:
0388: if (temp > 0)
0389: return true;
0390: return false;
0391: } catch (Exception e) {
0392: return false;
0393: }
0394:
0395: // return(isSignedInteger(s, secondArg)
0396: // &&((isEmpty(s) && secondArg) ||(parseInt(s) > 0) ) );
0397: }
0398:
0399: /** Returns true if string s is an integer >= 0. */
0400: public static boolean isNonnegativeInteger(String s) {
0401: if (isEmpty(s))
0402: return defaultEmptyOK;
0403:
0404: try {
0405: int temp = Integer.parseInt(s);
0406:
0407: if (temp >= 0)
0408: return true;
0409: return false;
0410: } catch (Exception e) {
0411: return false;
0412: }
0413:
0414: // return(isSignedInteger(s, secondArg)
0415: // &&((isEmpty(s) && secondArg) ||(parseInt(s) >= 0) ) );
0416: }
0417:
0418: /** Returns true if string s is an integer < 0. */
0419: public static boolean isNegativeInteger(String s) {
0420: if (isEmpty(s))
0421: return defaultEmptyOK;
0422:
0423: try {
0424: int temp = Integer.parseInt(s);
0425:
0426: if (temp < 0)
0427: return true;
0428: return false;
0429: } catch (Exception e) {
0430: return false;
0431: }
0432:
0433: // return(isSignedInteger(s, secondArg)
0434: // &&((isEmpty(s) && secondArg) ||(parseInt(s) < 0) ) );
0435: }
0436:
0437: /** Returns true if string s is an integer <= 0. */
0438: public static boolean isNonpositiveInteger(String s) {
0439: if (isEmpty(s))
0440: return defaultEmptyOK;
0441:
0442: try {
0443: int temp = Integer.parseInt(s);
0444:
0445: if (temp <= 0)
0446: return true;
0447: return false;
0448: } catch (Exception e) {
0449: return false;
0450: }
0451:
0452: // return(isSignedInteger(s, secondArg)
0453: // &&((isEmpty(s) && secondArg) ||(parseInt(s) <= 0) ) );
0454: }
0455:
0456: /** True if string s is an unsigned floating point(real) number.
0457: *
0458: * Also returns true for unsigned integers. If you wish
0459: * to distinguish between integers and floating point numbers,
0460: * first call isInteger, then call isFloat.
0461: *
0462: * Does not accept exponential notation.
0463: */
0464: public static boolean isFloat(String s) {
0465: if (isEmpty(s))
0466: return defaultEmptyOK;
0467:
0468: boolean seenDecimalPoint = false;
0469:
0470: if (s.startsWith(decimalPointDelimiter))
0471: return false;
0472:
0473: // Search through string's characters one by one
0474: // until we find a non-numeric character.
0475: // When we do, return false; if we don't, return true.
0476: for (int i = 0; i < s.length(); i++) {
0477: // Check that current character is number.
0478: char c = s.charAt(i);
0479:
0480: if (c == decimalPointDelimiter.charAt(0)) {
0481: if (!seenDecimalPoint)
0482: seenDecimalPoint = true;
0483: else
0484: return false;
0485: } else {
0486: if (!isDigit(c))
0487: return false;
0488: }
0489: }
0490: // All characters are numbers.
0491: return true;
0492: }
0493:
0494: /** True if string s is a signed or unsigned floating point
0495: * (real) number. First character is allowed to be + or -.
0496: *
0497: * Also returns true for unsigned integers. If you wish
0498: * to distinguish between integers and floating point numbers,
0499: * first call isSignedInteger, then call isSignedFloat.
0500: */
0501: public static boolean isSignedFloat(String s) {
0502: if (isEmpty(s))
0503: return defaultEmptyOK;
0504:
0505: try {
0506: float temp = Float.parseFloat(s);
0507:
0508: if (temp <= 0)
0509: return true;
0510: return false;
0511: } catch (Exception e) {
0512: return false;
0513: }
0514:
0515: // int startPos = 0;
0516: // if(isSignedFloat.arguments.length > 1) secondArg = isSignedFloat.arguments[1];
0517: // skip leading + or -
0518: // if((s.charAt(0) == "-") ||(s.charAt(0) == "+") ) startPos = 1;
0519: // return(isFloat(s.substring(startPos, s.length), secondArg))
0520: }
0521:
0522: /** True if string s is a signed or unsigned floating point
0523: * (real) number. First character is allowed to be + or -.
0524: *
0525: * Also returns true for unsigned integers. If you wish
0526: * to distinguish between integers and floating point numbers,
0527: * first call isSignedInteger, then call isSignedFloat.
0528: */
0529: public static boolean isSignedDouble(String s) {
0530: if (isEmpty(s))
0531: return defaultEmptyOK;
0532:
0533: try {
0534: double temp = Double.parseDouble(s);
0535:
0536: return true;
0537: } catch (Exception e) {
0538: return false;
0539: }
0540: }
0541:
0542: /** Returns true if string s is letters only.
0543: *
0544: * NOTE: This should handle i18n version to support European characters, etc.
0545: * since it now uses Character.isLetter()
0546: */
0547: public static boolean isAlphabetic(String s) {
0548: if (isEmpty(s))
0549: return defaultEmptyOK;
0550:
0551: // Search through string's characters one by one
0552: // until we find a non-alphabetic character.
0553: // When we do, return false; if we don't, return true.
0554: for (int i = 0; i < s.length(); i++) {
0555: // Check that current character is letter.
0556: char c = s.charAt(i);
0557:
0558: if (!isLetter(c))
0559: return false;
0560: }
0561:
0562: // All characters are letters.
0563: return true;
0564: }
0565:
0566: /** Returns true if string s is English letters (A .. Z, a..z) and numbers only.
0567: *
0568: * NOTE: Need i18n version to support European characters.
0569: * This could be tricky due to different character
0570: * sets and orderings for various languages and platforms.
0571: */
0572: public static boolean isAlphanumeric(String s) {
0573: if (isEmpty(s))
0574: return defaultEmptyOK;
0575:
0576: // Search through string's characters one by one
0577: // until we find a non-alphanumeric character.
0578: // When we do, return false; if we don't, return true.
0579: for (int i = 0; i < s.length(); i++) {
0580: // Check that current character is number or letter.
0581: char c = s.charAt(i);
0582:
0583: if (!isLetterOrDigit(c))
0584: return false;
0585: }
0586:
0587: // All characters are numbers or letters.
0588: return true;
0589: }
0590:
0591: /* ================== METHODS TO CHECK VARIOUS FIELDS. ==================== */
0592:
0593: /** isSSN returns true if string s is a valid U.S. Social Security Number. Must be 9 digits. */
0594: public static boolean isSSN(String s) {
0595: if (isEmpty(s))
0596: return defaultEmptyOK;
0597:
0598: String normalizedSSN = stripCharsInBag(s, SSNDelimiters);
0599:
0600: return (isInteger(normalizedSSN) && normalizedSSN.length() == digitsInSocialSecurityNumber);
0601: }
0602:
0603: /** isUSPhoneNumber returns true if string s is a valid U.S. Phone Number. Must be 10 digits. */
0604: public static boolean isUSPhoneNumber(String s) {
0605: if (isEmpty(s))
0606: return defaultEmptyOK;
0607: String normalizedPhone = stripCharsInBag(s,
0608: phoneNumberDelimiters);
0609:
0610: return (isInteger(normalizedPhone) && normalizedPhone.length() == digitsInUSPhoneNumber);
0611: }
0612:
0613: /** isUSPhoneAreaCode returns true if string s is a valid U.S. Phone Area Code. Must be 3 digits. */
0614: public static boolean isUSPhoneAreaCode(String s) {
0615: if (isEmpty(s))
0616: return defaultEmptyOK;
0617: String normalizedPhone = stripCharsInBag(s,
0618: phoneNumberDelimiters);
0619:
0620: return (isInteger(normalizedPhone) && normalizedPhone.length() == digitsInUSPhoneAreaCode);
0621: }
0622:
0623: /** isUSPhoneMainNumber returns true if string s is a valid U.S. Phone Main Number. Must be 7 digits. */
0624: public static boolean isUSPhoneMainNumber(String s) {
0625: if (isEmpty(s))
0626: return defaultEmptyOK;
0627: String normalizedPhone = stripCharsInBag(s,
0628: phoneNumberDelimiters);
0629:
0630: return (isInteger(normalizedPhone) && normalizedPhone.length() == digitsInUSPhoneMainNumber);
0631: }
0632:
0633: /** isInternationalPhoneNumber returns true if string s is a valid
0634: * international phone number. Must be digits only; any length OK.
0635: * May be prefixed by + character.
0636: */
0637: public static boolean isInternationalPhoneNumber(String s) {
0638: if (isEmpty(s))
0639: return defaultEmptyOK;
0640:
0641: String normalizedPhone = stripCharsInBag(s,
0642: phoneNumberDelimiters);
0643:
0644: return isPositiveInteger(normalizedPhone);
0645: }
0646:
0647: /** isZIPCode returns true if string s is a valid U.S. ZIP code. Must be 5 or 9 digits only. */
0648: public static boolean isZipCode(String s) {
0649: if (isEmpty(s))
0650: return defaultEmptyOK;
0651:
0652: String normalizedZip = stripCharsInBag(s, ZipCodeDelimiters);
0653:
0654: return (isInteger(normalizedZip) && ((normalizedZip.length() == digitsInZipCode1) || (normalizedZip
0655: .length() == digitsInZipCode2)));
0656: }
0657:
0658: /** Returns true if string s is a valid contiguous U.S. Zip code. Must be 5 or 9 digits only. */
0659: public static boolean isContiguousZipCode(String s) {
0660: boolean retval = false;
0661: if (isZipCode(s)) {
0662: if (isEmpty(s))
0663: retval = defaultEmptyOK;
0664: else {
0665: String normalizedZip = s.substring(0, 5);
0666: int iZip = Integer.parseInt(normalizedZip);
0667: if ((iZip >= 96701 && iZip <= 96898)
0668: || (iZip >= 99501 && iZip <= 99950))
0669: retval = false;
0670: else
0671: retval = true;
0672: }
0673: }
0674: return retval;
0675: }
0676:
0677: /** Return true if s is a valid U.S. Postal Code (abbreviation for state). */
0678: public static boolean isStateCode(String s) {
0679: if (isEmpty(s))
0680: return defaultEmptyOK;
0681: return ((USStateCodes.indexOf(s) != -1) && (s
0682: .indexOf(USStateCodeDelimiter) == -1));
0683: }
0684:
0685: /** Return true if s is a valid contiguous U.S. Postal Code (abbreviation for state). */
0686: public static boolean isContiguousStateCode(String s) {
0687: if (isEmpty(s))
0688: return defaultEmptyOK;
0689: return ((ContiguousUSStateCodes.indexOf(s) != -1) && (s
0690: .indexOf(USStateCodeDelimiter) == -1));
0691: }
0692:
0693: /** Email address must be of form a@b.c -- in other words:
0694: * - there must be at least one character before the @
0695: * - there must be at least one character before and after the .
0696: * - the characters @ and . are both required
0697: */
0698: public static boolean isEmail(String s) {
0699: if (isEmpty(s))
0700: return defaultEmptyOK;
0701:
0702: // is s whitespace?
0703: if (isWhitespace(s))
0704: return false;
0705:
0706: // there must be >= 1 character before @, so we
0707: // start looking at character position 1
0708: // (i.e. second character)
0709: int i = 1;
0710: int sLength = s.length();
0711:
0712: // look for @
0713: while ((i < sLength) && (s.charAt(i) != '@'))
0714: i++;
0715:
0716: // there must be at least one character after the .
0717: if ((i >= sLength - 1) || (s.charAt(i) != '@'))
0718: return false;
0719: else
0720: return true;
0721:
0722: // DEJ 2001-10-13 Don't look for '.', some valid emails do not have a dot in the domain name
0723: // else i += 2;
0724:
0725: // look for .
0726: // while((i < sLength) && (s.charAt(i) != '.')) i++;
0727: // there must be at least one character after the .
0728: // if((i >= sLength - 1) || (s.charAt(i) != '.')) return false;
0729: // else return true;
0730: }
0731:
0732: /** isUrl returns true if the string contains ://
0733: * @param s String to validate
0734: * @return true if s contains ://
0735: */
0736: public static boolean isUrl(String s) {
0737: if (isEmpty(s))
0738: return defaultEmptyOK;
0739: if (s.indexOf("://") != -1)
0740: return true;
0741: return false;
0742: }
0743:
0744: /** isYear returns true if string s is a valid
0745: * Year number. Must be 2 or 4 digits only.
0746: *
0747: * For Year 2000 compliance, you are advised
0748: * to use 4-digit year numbers everywhere.
0749: */
0750: public static boolean isYear(String s) {
0751: if (isEmpty(s))
0752: return defaultEmptyOK;
0753:
0754: if (!isNonnegativeInteger(s))
0755: return false;
0756: return ((s.length() == 2) || (s.length() == 4));
0757: }
0758:
0759: /** isIntegerInRange returns true if string s is an integer
0760: * within the range of integer arguments a and b, inclusive.
0761: */
0762: public static boolean isIntegerInRange(String s, int a, int b) {
0763: if (isEmpty(s))
0764: return defaultEmptyOK;
0765: // Catch non-integer strings to avoid creating a NaN below,
0766: // which isn't available on JavaScript 1.0 for Windows.
0767: if (!isSignedInteger(s))
0768: return false;
0769: // Now, explicitly change the type to integer via parseInt
0770: // so that the comparison code below will work both on
0771: // JavaScript 1.2(which typechecks in equality comparisons)
0772: // and JavaScript 1.1 and before(which doesn't).
0773: int num = Integer.parseInt(s);
0774:
0775: return ((num >= a) && (num <= b));
0776: }
0777:
0778: /** isMonth returns true if string s is a valid month number between 1 and 12. */
0779: public static boolean isMonth(String s) {
0780: if (isEmpty(s))
0781: return defaultEmptyOK;
0782: return isIntegerInRange(s, 1, 12);
0783: }
0784:
0785: /** isDay returns true if string s is a valid day number between 1 and 31. */
0786: public static boolean isDay(String s) {
0787: if (isEmpty(s))
0788: return defaultEmptyOK;
0789: return isIntegerInRange(s, 1, 31);
0790: }
0791:
0792: /** Given integer argument year, returns number of days in February of that year. */
0793: public static int daysInFebruary(int year) {
0794: // February has 29 days in any year evenly divisible by four,
0795: // EXCEPT for centurial years which are not also divisible by 400.
0796: return (((year % 4 == 0) && ((!(year % 100 == 0)) || (year % 400 == 0))) ? 29
0797: : 28);
0798: }
0799:
0800: /** isHour returns true if string s is a valid number between 0 and 23. */
0801: public static boolean isHour(String s) {
0802: if (isEmpty(s))
0803: return defaultEmptyOK;
0804: return isIntegerInRange(s, 0, 23);
0805: }
0806:
0807: /** isMinute returns true if string s is a valid number between 0 and 59. */
0808: public static boolean isMinute(String s) {
0809: if (isEmpty(s))
0810: return defaultEmptyOK;
0811: return isIntegerInRange(s, 0, 59);
0812: }
0813:
0814: /** isSecond returns true if string s is a valid number between 0 and 59. */
0815: public static boolean isSecond(String s) {
0816: if (isEmpty(s))
0817: return defaultEmptyOK;
0818: return isIntegerInRange(s, 0, 59);
0819: }
0820:
0821: /** isDate returns true if string arguments year, month, and day form a valid date. */
0822: public static boolean isDate(String year, String month, String day) {
0823: // catch invalid years(not 2- or 4-digit) and invalid months and days.
0824: if (!(isYear(year) && isMonth(month) && isDay(day)))
0825: return false;
0826:
0827: int intYear = Integer.parseInt(year);
0828: int intMonth = Integer.parseInt(month);
0829: int intDay = Integer.parseInt(day);
0830:
0831: // catch invalid days, except for February
0832: if (intDay > daysInMonth[intMonth - 1])
0833: return false;
0834: if ((intMonth == 2) && (intDay > daysInFebruary(intYear)))
0835: return false;
0836: return true;
0837: }
0838:
0839: /** isDate returns true if string argument date forms a valid date. */
0840: public static boolean isDate(String date) {
0841: if (isEmpty(date))
0842: return defaultEmptyOK;
0843: String month;
0844: String day;
0845: String year;
0846:
0847: int dateSlash1 = date.indexOf("/");
0848: int dateSlash2 = date.lastIndexOf("/");
0849:
0850: if (dateSlash1 <= 0 || dateSlash1 == dateSlash2)
0851: return false;
0852: month = date.substring(0, dateSlash1);
0853: day = date.substring(dateSlash1 + 1, dateSlash2);
0854: year = date.substring(dateSlash2 + 1);
0855:
0856: return isDate(year, month, day);
0857: }
0858:
0859: /** isDate returns true if string argument date forms a valid date and is after today. */
0860: public static boolean isDateAfterToday(String date) {
0861: if (isEmpty(date))
0862: return defaultEmptyOK;
0863: int dateSlash1 = date.indexOf("/");
0864: int dateSlash2 = date.lastIndexOf("/");
0865:
0866: if (dateSlash1 <= 0)
0867: return false;
0868:
0869: java.util.Date passed = null;
0870: if (dateSlash1 == dateSlash2) {
0871: // consider the day to be optional; use the first day of the following month for comparison since this is an is after test
0872: String month = date.substring(0, dateSlash1);
0873: String day = "28";
0874: String year = date.substring(dateSlash1 + 1);
0875: if (!isDate(year, month, day))
0876: return false;
0877:
0878: try {
0879: int monthInt = Integer.parseInt(month);
0880: int yearInt = Integer.parseInt(year);
0881: Calendar calendar = Calendar.getInstance();
0882: calendar.set(yearInt, monthInt - 1, 0, 0, 0, 0);
0883: calendar.add(Calendar.MONTH, 1);
0884: passed = new java.util.Date(calendar.getTime()
0885: .getTime());
0886: } catch (Exception e) {
0887: passed = null;
0888: }
0889: } else {
0890: String month = date.substring(0, dateSlash1);
0891: String day = date.substring(dateSlash1 + 1, dateSlash2);
0892: String year = date.substring(dateSlash2 + 1);
0893: if (!isDate(year, month, day))
0894: return false;
0895: passed = UtilDateTime.toDate(month, day, year, "0", "0",
0896: "0");
0897: }
0898:
0899: java.util.Date now = UtilDateTime.nowDate();
0900: if (passed != null) {
0901: return passed.after(now);
0902: } else {
0903: return false;
0904: }
0905: }
0906:
0907: /** isTime returns true if string arguments hour, minute, and second form a valid time. */
0908: public static boolean isTime(String hour, String minute,
0909: String second) {
0910: // catch invalid years(not 2- or 4-digit) and invalid months and days.
0911: if (isHour(hour) && isMinute(minute) && isSecond(second))
0912: return true;
0913: else
0914: return false;
0915: }
0916:
0917: /** isTime returns true if string argument time forms a valid time. */
0918: public static boolean isTime(String time) {
0919: if (isEmpty(time))
0920: return defaultEmptyOK;
0921:
0922: String hour;
0923: String minute;
0924: String second;
0925:
0926: int timeColon1 = time.indexOf(":");
0927: int timeColon2 = time.lastIndexOf(":");
0928:
0929: if (timeColon1 <= 0)
0930: return false;
0931: hour = time.substring(0, timeColon1);
0932: if (timeColon1 == timeColon2) {
0933: minute = time.substring(timeColon1 + 1);
0934: second = "0";
0935: } else {
0936: minute = time.substring(timeColon1 + 1, timeColon2);
0937: second = time.substring(timeColon2 + 1);
0938: }
0939: return isTime(hour, minute, second);
0940: }
0941:
0942: /** Check to see if a card number is a valid ValueLink Gift Card
0943: *
0944: * @param stPassed a string representing a valuelink gift card
0945: * @return true, if the number passed simple checks
0946: */
0947: public static boolean isValueLinkCard(String stPassed) {
0948: if (isEmpty(stPassed))
0949: return defaultEmptyOK;
0950: String st = stripCharsInBag(stPassed, creditCardDelimiters);
0951: if (st.length() == 16
0952: && (st.startsWith("7") || st.startsWith("6"))) {
0953: return true;
0954: }
0955: return false;
0956: }
0957:
0958: /** Check to see if a card number is a supported Gift Card
0959: *
0960: * @param stPassed a string representing a gift card
0961: * @return true, if the number passed simple checks
0962: */
0963: public static boolean isGiftCard(String stPassed) {
0964: return isValueLinkCard(stPassed);
0965: }
0966:
0967: public static int getLuhnSum(String stPassed) {
0968: stPassed = stPassed.replaceAll("\\D", ""); // nuke any non-digit characters
0969:
0970: int len = stPassed.length();
0971: int sum = 0;
0972: int mul = 1;
0973: for (int i = len - 1; i >= 0; i--) {
0974: int digit = Character.digit(stPassed.charAt(i), 10);
0975: digit *= (mul == 1) ? mul++ : mul--;
0976: sum += (digit >= 10) ? (digit % 10) + 1 : digit;
0977: }
0978:
0979: return sum;
0980: }
0981:
0982: public static int getLuhnCheckDigit(String stPassed) {
0983: int sum = getLuhnSum(stPassed);
0984: int mod = ((sum / 10 + 1) * 10 - sum) % 10;
0985: return (10 - mod);
0986: }
0987:
0988: public static boolean sumIsMod10(int sum) {
0989: return ((sum % 10) == 0);
0990: }
0991:
0992: public static String appendCheckDigit(String stPassed) {
0993: String checkDigit = new Integer(getLuhnCheckDigit(stPassed))
0994: .toString();
0995: return stPassed + checkDigit;
0996: }
0997:
0998: /** Checks credit card number with Luhn Mod-10 test
0999: *
1000: * @param stPassed a string representing a credit card number
1001: * @return true, if the credit card number passes the Luhn Mod-10 test, false otherwise
1002: */
1003: public static boolean isCreditCard(String stPassed) {
1004: if (isEmpty(stPassed))
1005: return defaultEmptyOK;
1006: String st = stripCharsInBag(stPassed, creditCardDelimiters);
1007:
1008: // encoding only works on cars with less the 19 digits
1009: if (st.length() > 19)
1010: return false;
1011: return sumIsMod10(getLuhnSum(st));
1012: }
1013:
1014: /** Checks to see if the cc number is a valid Visa number
1015: *
1016: * @param cc a string representing a credit card number; Sample number: 4111 1111 1111 1111(16 digits)
1017: * @return true, if the credit card number is a valid VISA number, false otherwise
1018: */
1019: public static boolean isVisa(String cc) {
1020: if (((cc.length() == 16) || (cc.length() == 13))
1021: && (cc.substring(0, 1).equals("4")))
1022: return isCreditCard(cc);
1023: return false;
1024: }
1025:
1026: /** Checks to see if the cc number is a valid Master Card number
1027: *
1028: * @param cc a string representing a credit card number; Sample number: 5500 0000 0000 0004(16 digits)
1029: * @return true, if the credit card number is a valid MasterCard number, false otherwise
1030: */
1031: public static boolean isMasterCard(String cc) {
1032: int firstdig = Integer.parseInt(cc.substring(0, 1));
1033: int seconddig = Integer.parseInt(cc.substring(1, 2));
1034:
1035: if ((cc.length() == 16) && (firstdig == 5)
1036: && ((seconddig >= 1) && (seconddig <= 5)))
1037: return isCreditCard(cc);
1038: return false;
1039:
1040: }
1041:
1042: /** Checks to see if the cc number is a valid American Express number
1043: * @param cc - a string representing a credit card number; Sample number: 340000000000009(15 digits)
1044: * @return true, if the credit card number is a valid American Express number, false otherwise
1045: */
1046: public static boolean isAmericanExpress(String cc) {
1047: int firstdig = Integer.parseInt(cc.substring(0, 1));
1048: int seconddig = Integer.parseInt(cc.substring(1, 2));
1049:
1050: if ((cc.length() == 15) && (firstdig == 3)
1051: && ((seconddig == 4) || (seconddig == 7)))
1052: return isCreditCard(cc);
1053: return false;
1054:
1055: }
1056:
1057: /** Checks to see if the cc number is a valid Diners Club number
1058: * @param cc - a string representing a credit card number; Sample number: 30000000000004(14 digits)
1059: * @return true, if the credit card number is a valid Diner's Club number, false otherwise
1060: */
1061: public static boolean isDinersClub(String cc) {
1062: int firstdig = Integer.parseInt(cc.substring(0, 1));
1063: int seconddig = Integer.parseInt(cc.substring(1, 2));
1064:
1065: if ((cc.length() == 14)
1066: && (firstdig == 3)
1067: && ((seconddig == 0) || (seconddig == 6) || (seconddig == 8)))
1068: return isCreditCard(cc);
1069: return false;
1070: }
1071:
1072: /** Checks to see if the cc number is a valid Carte Blanche number
1073: * @param cc - a string representing a credit card number; Sample number: 30000000000004(14 digits)
1074: * @return true, if the credit card number is a valid Carte Blanche number, false otherwise
1075: */
1076: public static boolean isCarteBlanche(String cc) {
1077: return isDinersClub(cc);
1078: }
1079:
1080: /** Checks to see if the cc number is a valid Discover number
1081: * @param cc - a string representing a credit card number; Sample number: 6011000000000004(16 digits)
1082: * @return true, if the credit card number is a valid Discover card number, false otherwise
1083: */
1084: public static boolean isDiscover(String cc) {
1085: String first4digs = cc.substring(0, 4);
1086:
1087: if ((cc.length() == 16) && (first4digs.equals("6011")))
1088: return isCreditCard(cc);
1089: return false;
1090: }
1091:
1092: /** Checks to see if the cc number is a valid EnRoute number
1093: * @param cc - a string representing a credit card number; Sample number: 201400000000009(15 digits)
1094: * @return true, if the credit card number is a valid enRoute card number, false, otherwise
1095: */
1096: public static boolean isEnRoute(String cc) {
1097: String first4digs = cc.substring(0, 4);
1098:
1099: if ((cc.length() == 15)
1100: && (first4digs.equals("2014") || first4digs
1101: .equals("2149")))
1102: return isCreditCard(cc);
1103: return false;
1104: }
1105:
1106: /** Checks to see if the cc number is a valid JCB number
1107: * @param cc - a string representing a credit card number; Sample number: 3088000000000009(16 digits)
1108: * @return true, if the credit card number is a valid JCB card number, false otherwise
1109: */
1110: public static boolean isJCB(String cc) {
1111: String first4digs = cc.substring(0, 4);
1112:
1113: if ((cc.length() == 16)
1114: && (first4digs.equals("3088")
1115: || first4digs.equals("3096")
1116: || first4digs.equals("3112")
1117: || first4digs.equals("3158")
1118: || first4digs.equals("3337") || first4digs
1119: .equals("3528")))
1120: return isCreditCard(cc);
1121: return false;
1122: }
1123:
1124: /** Checks to see if the cc number is a valid number for any accepted credit card
1125: * @param ccPassed - a string representing a credit card number
1126: * @return true, if the credit card number is any valid credit card number for any of the accepted card types, false otherwise
1127: */
1128: public static boolean isAnyCard(String ccPassed) {
1129: if (isEmpty(ccPassed))
1130: return defaultEmptyOK;
1131:
1132: String cc = stripCharsInBag(ccPassed, creditCardDelimiters);
1133:
1134: if (!isCreditCard(cc))
1135: return false;
1136: if (isMasterCard(cc) || isVisa(cc) || isAmericanExpress(cc)
1137: || isDinersClub(cc) || isDiscover(cc) || isEnRoute(cc)
1138: || isJCB(cc))
1139: return true;
1140: return false;
1141: }
1142:
1143: /** Checks to see if the cc number is a valid number for any accepted credit card, and return the name of that type
1144: * @param ccPassed - a string representing a credit card number
1145: * @return true, if the credit card number is any valid credit card number for any of the accepted card types, false otherwise
1146: */
1147: public static String getCardType(String ccPassed) {
1148: if (isEmpty(ccPassed))
1149: return "Unknown";
1150: String cc = stripCharsInBag(ccPassed, creditCardDelimiters);
1151:
1152: if (!isCreditCard(cc))
1153: return "Unknown";
1154:
1155: if (isMasterCard(cc))
1156: return "MasterCard";
1157: if (isVisa(cc))
1158: return "Visa";
1159: if (isAmericanExpress(cc))
1160: return "AmericanExpress";
1161: if (isDinersClub(cc))
1162: return "DinersClub";
1163: if (isDiscover(cc))
1164: return "Discover";
1165: if (isEnRoute(cc))
1166: return "EnRoute";
1167: if (isJCB(cc))
1168: return "JCB";
1169: return "Unknown";
1170: }
1171:
1172: /** Checks to see if the cc number is a valid number for the specified type
1173: * @param cardType - a string representing the credit card type
1174: * @param cardNumberPassed - a string representing a credit card number
1175: * @return true, if the credit card number is valid for the particular credit card type given in "cardType", false otherwise
1176: */
1177: public static boolean isCardMatch(String cardType,
1178: String cardNumberPassed) {
1179: if (isEmpty(cardType))
1180: return defaultEmptyOK;
1181: if (isEmpty(cardNumberPassed))
1182: return defaultEmptyOK;
1183: String cardNumber = stripCharsInBag(cardNumberPassed,
1184: creditCardDelimiters);
1185:
1186: if ((cardType.equalsIgnoreCase("VISA")) && (isVisa(cardNumber)))
1187: return true;
1188: if ((cardType.equalsIgnoreCase("MASTERCARD"))
1189: && (isMasterCard(cardNumber)))
1190: return true;
1191: if (((cardType.equalsIgnoreCase("AMERICANEXPRESS")) || (cardType
1192: .equalsIgnoreCase("AMEX")))
1193: && (isAmericanExpress(cardNumber)))
1194: return true;
1195: if ((cardType.equalsIgnoreCase("DISCOVER"))
1196: && (isDiscover(cardNumber)))
1197: return true;
1198: if ((cardType.equalsIgnoreCase("JCB")) && (isJCB(cardNumber)))
1199: return true;
1200: if (((cardType.equalsIgnoreCase("DINERSCLUB")) || (cardType
1201: .equalsIgnoreCase("DINERS")))
1202: && (isDinersClub(cardNumber)))
1203: return true;
1204: if ((cardType.equalsIgnoreCase("CARTEBLANCHE"))
1205: && (isCarteBlanche(cardNumber)))
1206: return true;
1207: if ((cardType.equalsIgnoreCase("ENROUTE"))
1208: && (isEnRoute(cardNumber)))
1209: return true;
1210: return false;
1211: }
1212:
1213: /** isNotPoBox returns true if address argument does not contain anything that looks like a a PO Box. */
1214: public static boolean isNotPoBox(String s) {
1215: if (isEmpty(s))
1216: return defaultEmptyOK;
1217:
1218: // strings to check from Greg's program
1219: // "P.O. B"
1220: // "P.o.B"
1221: // "P.O B"
1222: // "PO. B"
1223: // "P O B"
1224: // "PO B"
1225: // "P.0. B"
1226: // "P0 B"
1227:
1228: String sl = s.toLowerCase();
1229: if (sl.indexOf("p.o. b") != -1)
1230: return false;
1231: if (sl.indexOf("p.o.b") != -1)
1232: return false;
1233: if (sl.indexOf("p.o b") != -1)
1234: return false;
1235: if (sl.indexOf("p o b") != -1)
1236: return false;
1237: if (sl.indexOf("po b") != -1)
1238: return false;
1239: if (sl.indexOf("pobox") != -1)
1240: return false;
1241: if (sl.indexOf("po#") != -1)
1242: return false;
1243: if (sl.indexOf("po #") != -1)
1244: return false;
1245:
1246: // now with 0's for them sneaky folks
1247: if (sl.indexOf("p.0. b") != -1)
1248: return false;
1249: if (sl.indexOf("p.0.b") != -1)
1250: return false;
1251: if (sl.indexOf("p.0 b") != -1)
1252: return false;
1253: if (sl.indexOf("p 0 b") != -1)
1254: return false;
1255: if (sl.indexOf("p0 b") != -1)
1256: return false;
1257: if (sl.indexOf("p0box") != -1)
1258: return false;
1259: if (sl.indexOf("p0#") != -1)
1260: return false;
1261: if (sl.indexOf("p0 #") != -1)
1262: return false;
1263: return true;
1264: }
1265: }
|