0001: /*******************************************************************************
0002: * Licensed to the Apache Software Foundation (ASF) under one
0003: * or more contributor license agreements. See the NOTICE file
0004: * distributed with this work for additional information
0005: * regarding copyright ownership. The ASF licenses this file
0006: * to you under the Apache License, Version 2.0 (the
0007: * "License"); you may not use this file except in compliance
0008: * with the License. You may obtain a copy of the License at
0009: *
0010: * http://www.apache.org/licenses/LICENSE-2.0
0011: *
0012: * Unless required by applicable law or agreed to in writing,
0013: * software distributed under the License is distributed on an
0014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0015: * KIND, either express or implied. See the License for the
0016: * specific language governing permissions and limitations
0017: * under the License.
0018: *******************************************************************************/package org.ofbiz.base.util;
0019:
0020: import java.util.Calendar;
0021: import java.util.Collection;
0022:
0023: /**
0024: * General input/data validation methods
0025: * Utility methods for validating data, especially input.
0026: * See detailed description below.
0027: *
0028: * <br/> SUMMARY
0029: * <br/>
0030: * <br/> This is a set of meethods for validating input. Functions are provided to validate:
0031: * <br/> - U.S. and international phone/fax numbers
0032: * <br/> - U.S. ZIP codes(5 or 9 digit postal codes)
0033: * <br/> - U.S. Postal Codes(2 letter abbreviations for names of states)
0034: * <br/> - U.S. Social Security Numbers(abbreviated as SSNs)
0035: * <br/> - email addresses
0036: * <br/> - dates(entry of year, month, and day and validity of combined date)
0037: * <br/> - credit card numbers
0038: * <br/>
0039: * <br/> Supporting utility functions validate that:
0040: * <br/> - characters are Letter, Digit, or LetterOrDigit
0041: * <br/> - strings are a Signed, Positive, Negative, Nonpositive, or Nonnegative integer
0042: * <br/> - strings are a Float or a SignedFloat
0043: * <br/> - strings are Alphabetic, Alphanumeric, or Whitespace
0044: * <br/> - strings contain an integer within a specified range
0045: * <br/>
0046: * <br/> Other utility functions are provided to:
0047: * <br/> - remove from a string characters which are/are not in a "bag" of selected characters
0048: * <br/> - strip whitespace/leading whitespace from a string
0049: * <br/>
0050: * <br/> ==============================================================================
0051: * <br/> NOTE: This code was adapted from the Netscape JavaScript form validation code,
0052: * <br/> usually found in "FormChek.js". Credit card verification functions Originally
0053: * <br< included as Starter Application 1.0.0 in LivePayment.
0054: * <br/> ==============================================================================
0055: */
0056: public class UtilValidate {
0057:
0058: public static final String module = UtilValidate.class.getName();
0059:
0060: /** boolean specifying by default whether or not it is okay for a String to be empty */
0061: public static final boolean defaultEmptyOK = true;
0062:
0063: /** digit characters */
0064: public static final String digits = "0123456789";
0065:
0066: /** lower-case letter characters */
0067: public static final String lowercaseLetters = "abcdefghijklmnopqrstuvwxyz";
0068:
0069: /** upper-case letter characters */
0070: public static final String uppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
0071:
0072: /** letter characters */
0073: public static final String letters = lowercaseLetters
0074: + uppercaseLetters;
0075:
0076: /** whitespace characters */
0077: public static final String whitespace = " \t\n\r";
0078:
0079: /** decimal point character differs by language and culture */
0080: public static final String decimalPointDelimiter = ".";
0081:
0082: /** non-digit characters which are allowed in phone numbers */
0083: public static final String phoneNumberDelimiters = "()- ";
0084:
0085: /** characters which are allowed in US phone numbers */
0086: public static final String validUSPhoneChars = digits
0087: + phoneNumberDelimiters;
0088:
0089: /** characters which are allowed in international phone numbers(a leading + is OK) */
0090: public static final String validWorldPhoneChars = digits
0091: + phoneNumberDelimiters + "+";
0092:
0093: /** non-digit characters which are allowed in Social Security Numbers */
0094: public static final String SSNDelimiters = "- ";
0095:
0096: /** characters which are allowed in Social Security Numbers */
0097: public static final String validSSNChars = digits + SSNDelimiters;
0098:
0099: /** U.S. Social Security Numbers have 9 digits. They are formatted as 123-45-6789. */
0100: public static final int digitsInSocialSecurityNumber = 9;
0101:
0102: /** U.S. phone numbers have 10 digits. They are formatted as 123 456 7890 or(123) 456-7890. */
0103: public static final int digitsInUSPhoneNumber = 10;
0104: public static final int digitsInUSPhoneAreaCode = 3;
0105: public static final int digitsInUSPhoneMainNumber = 7;
0106:
0107: /** non-digit characters which are allowed in ZIP Codes */
0108: public static final String ZipCodeDelimiters = "-";
0109:
0110: /** our preferred delimiter for reformatting ZIP Codes */
0111: public static final String ZipCodeDelimeter = "-";
0112:
0113: /** characters which are allowed in Social Security Numbers */
0114: public static final String validZipCodeChars = digits
0115: + ZipCodeDelimiters;
0116:
0117: /** U.S. ZIP codes have 5 or 9 digits. They are formatted as 12345 or 12345-6789. */
0118: public static final int digitsInZipCode1 = 5;
0119:
0120: /** U.S. ZIP codes have 5 or 9 digits. They are formatted as 12345 or 12345-6789. */
0121: public static final int digitsInZipCode2 = 9;
0122:
0123: /** non-digit characters which are allowed in credit card numbers */
0124: public static final String creditCardDelimiters = " -";
0125:
0126: public static final String isNotEmptyMsg = "This field cannot be empty, please enter a value.";
0127: public static final String isStateCodeMsg = "The State Code must be a valid two character U.S. state abbreviation(like CA for California).";
0128: 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).";
0129: public static final String isZipCodeMsg = "The ZIP Code must be a 5 or 9 digit U.S. ZIP Code(like 94043).";
0130: public static final String isUSPhoneMsg = "The US Phone must be a 10 digit U.S. phone number(like 415-555-1212).";
0131: public static final String isUSPhoneAreaCodeMsg = "The Phone Number Area Code must be 3 digits.";
0132: public static final String isUSPhoneMainNumberMsg = "The Phone Number must be 7 digits.";
0133: public static final String isContiguousZipCodeMsg = "Zip Code is not a valid Zip Code for one of the 48 contiguous United States .";
0134: public static final String isInternationalPhoneNumberMsg = "The World Phone must be a valid international phone number.";
0135: public static final String isSSNMsg = "The SSN must be a 9 digit U.S. social security number(like 123-45-6789).";
0136: public static final String isEmailMsg = "The Email must be a valid email address(like john@email.com). Please re-enter it now.";
0137: public static final String isAnyCardMsg = "The credit card number is not a valid card number.";
0138: public static final String isCreditCardPrefixMsg = " is not a valid ";
0139: public static final String isCreditCardSuffixMsg = " credit card number.";
0140: public static final String isDayMsg = "The Day must be a day number between 1 and 31. ";
0141: public static final String isMonthMsg = "The Month must be a month number between 1 and 12. ";
0142: public static final String isYearMsg = "The Year must be a 2 or 4 digit year number. ";
0143: public static final String isDatePrefixMsg = "The Day, Month, and Year for ";
0144: public static final String isDateSuffixMsg = " do not form a valid date. Please reenter them now.";
0145: public static final String isHourMsg = "The Hour must be a number between 0 and 23.";
0146: public static final String isMinuteMsg = "The Hour must be a number between 0 and 59.";
0147: public static final String isSecondMsg = "The Hour must be a number between 0 and 59.";
0148: public static final String isTimeMsg = "The Time must be a valid time formed like: HH:MM or HH:MM:SS.";
0149: 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.";
0150: 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.";
0151: public static final String isIntegerMsg = "The Number must be a valid unsigned whole decimal number.";
0152: public static final String isSignedIntegerMsg = "The Number must be a valid signed whole decimal number.";
0153: public static final String isLongMsg = "The Number must be a valid unsigned whole decimal number.";
0154: public static final String isSignedLongMsg = "The Number must be a valid signed whole decimal number.";
0155: public static final String isFloatMsg = "The Number must be a valid unsigned decimal number.";
0156: public static final String isSignedFloatMsg = "The Number must be a valid signed decimal number.";
0157: public static final String isSignedDoubleMsg = "The Number must be a valid signed decimal number.";
0158:
0159: /** An array of ints representing the number of days in each month of the year.
0160: * Note: February varies depending on the year */
0161: public static final int[] daysInMonth = { 31, 29, 31, 30, 31, 30,
0162: 31, 31, 30, 31, 30, 31 };
0163:
0164: /** Delimiter for USStateCodes String */
0165: public static final String USStateCodeDelimiter = "|";
0166:
0167: /** Valid U.S. Postal Codes for states, territories, armed forces, etc.
0168: * See http://www.usps.gov/ncsc/lookups/abbr_state.txt. */
0169: 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";
0170:
0171: /** Valid contiguous U.S. postal codes */
0172: 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";
0173:
0174: public static boolean areEqual(Object obj, Object obj2) {
0175: if (obj == null) {
0176: return obj2 == null;
0177: } else {
0178: return obj.equals(obj2);
0179: }
0180: }
0181:
0182: /** Check whether an object is empty, will see if it is a String, Map, Collection, etc. */
0183: public static boolean isEmpty(Object o) {
0184: return ObjectType.isEmpty(o);
0185: }
0186:
0187: /** Check whether an object is NOT empty, will see if it is a String, Map, Collection, etc. */
0188: public static boolean isNotEmpty(Object o) {
0189: return !ObjectType.isEmpty(o);
0190: }
0191:
0192: /** Check whether string s is empty. */
0193: public static boolean isEmpty(String s) {
0194: return ((s == null) || (s.length() == 0));
0195: }
0196:
0197: /** Check whether collection c is empty. */
0198: public static boolean isEmpty(Collection c) {
0199: return ((c == null) || (c.size() == 0));
0200: }
0201:
0202: /** Check whether string s is NOT empty. */
0203: public static boolean isNotEmpty(String s) {
0204: return ((s != null) && (s.length() > 0));
0205: }
0206:
0207: /** Check whether collection c is NOT empty. */
0208: public static boolean isNotEmpty(Collection c) {
0209: return ((c != null) && (c.size() > 0));
0210: }
0211:
0212: public static boolean isString(Object obj) {
0213: return ((obj != null) && (obj instanceof java.lang.String));
0214: }
0215:
0216: /** Returns true if string s is empty or whitespace characters only. */
0217: public static boolean isWhitespace(String s) {
0218: // Is s empty?
0219: if (isEmpty(s))
0220: return true;
0221:
0222: // Search through string's characters one by one
0223: // until we find a non-whitespace character.
0224: // When we do, return false; if we don't, return true.
0225: for (int i = 0; i < s.length(); i++) {
0226: // Check that current character isn't whitespace.
0227: char c = s.charAt(i);
0228:
0229: if (whitespace.indexOf(c) == -1)
0230: return false;
0231: }
0232: // All characters are whitespace.
0233: return true;
0234: }
0235:
0236: /** Removes all characters which appear in string bag from string s. */
0237: public static String stripCharsInBag(String s, String bag) {
0238: int i;
0239: String returnString = "";
0240:
0241: // Search through string's characters one by one.
0242: // If character is not in bag, append to returnString.
0243: for (i = 0; i < s.length(); i++) {
0244: char c = s.charAt(i);
0245:
0246: if (bag.indexOf(c) == -1)
0247: returnString += c;
0248: }
0249: return returnString;
0250: }
0251:
0252: /** Removes all characters which do NOT appear in string bag from string s. */
0253: public static String stripCharsNotInBag(String s, String bag) {
0254: int i;
0255: String returnString = "";
0256:
0257: // Search through string's characters one by one.
0258: // If character is in bag, append to returnString.
0259: for (i = 0; i < s.length(); i++) {
0260: char c = s.charAt(i);
0261:
0262: if (bag.indexOf(c) != -1)
0263: returnString += c;
0264: }
0265: return returnString;
0266: }
0267:
0268: /** Removes all whitespace characters from s.
0269: * Member whitespace(see above) defines which characters are considered whitespace. */
0270: public static String stripWhitespace(String s) {
0271: return stripCharsInBag(s, whitespace);
0272: }
0273:
0274: /** Returns true if single character c(actually a string) is contained within string s. */
0275: public static boolean charInString(char c, String s) {
0276: return (s.indexOf(c) != -1);
0277: // for(int i = 0; i < s.length; i++) {
0278: // if(s.charAt(i) == c) return true;
0279: // }
0280: // return false;
0281: }
0282:
0283: /** Removes initial(leading) whitespace characters from s.
0284: * Member whitespace(see above) defines which characters are considered whitespace. */
0285: public static String stripInitialWhitespace(String s) {
0286: int i = 0;
0287:
0288: while ((i < s.length())
0289: && charInString(s.charAt(i), whitespace))
0290: i++;
0291: return s.substring(i);
0292: // return s.substring(i, s.length);
0293: }
0294:
0295: /** Returns true if character c is an English letter (A .. Z, a..z).
0296: *
0297: * NOTE: Need i18n version to support European characters.
0298: * This could be tricky due to different character
0299: * sets and orderings for various languages and platforms. */
0300: public static boolean isLetter(char c) {
0301: return Character.isLetter(c);
0302: }
0303:
0304: /** Returns true if character c is a digit (0 .. 9). */
0305: public static boolean isDigit(char c) {
0306: return Character.isDigit(c);
0307: }
0308:
0309: /** Returns true if character c is a letter or digit. */
0310: public static boolean isLetterOrDigit(char c) {
0311: return Character.isLetterOrDigit(c);
0312: }
0313:
0314: /** Returns true if all characters in string s are numbers.
0315: *
0316: * Accepts non-signed integers only. Does not accept floating
0317: * point, exponential notation, etc.
0318: */
0319: public static boolean isInteger(String s) {
0320: if (isEmpty(s))
0321: return defaultEmptyOK;
0322:
0323: // Search through string's characters one by one
0324: // until we find a non-numeric character.
0325: // When we do, return false; if we don't, return true.
0326: for (int i = 0; i < s.length(); i++) {
0327: // Check that current character is number.
0328: char c = s.charAt(i);
0329:
0330: if (!isDigit(c))
0331: return false;
0332: }
0333:
0334: // All characters are numbers.
0335: return true;
0336: }
0337:
0338: /** Returns true if all characters are numbers;
0339: * first character is allowed to be + or - as well.
0340: *
0341: * Does not accept floating point, exponential notation, etc.
0342: */
0343: public static boolean isSignedInteger(String s) {
0344: if (isEmpty(s))
0345: return defaultEmptyOK;
0346: try {
0347: Integer.parseInt(s);
0348: return true;
0349: } catch (Exception e) {
0350: return false;
0351: }
0352:
0353: // int startPos = 0;
0354: // boolean secondArg = defaultEmptyOK;
0355:
0356: // if(isSignedInteger.arguments.length > 1) secondArg = isSignedInteger.arguments[1];
0357:
0358: // skip leading + or -
0359: // if((s.charAt(0) == "-") ||(s.charAt(0) == "+") ) startPos = 1;
0360: // return(isInteger(s.substring(startPos, s.length), secondArg))
0361: }
0362:
0363: /** Returns true if all characters are numbers;
0364: * first character is allowed to be + or - as well.
0365: *
0366: * Does not accept floating point, exponential notation, etc.
0367: */
0368: public static boolean isSignedLong(String s) {
0369: if (isEmpty(s))
0370: return defaultEmptyOK;
0371: try {
0372: Long.parseLong(s);
0373: return true;
0374: } catch (Exception e) {
0375: return false;
0376: }
0377: }
0378:
0379: /** Returns true if string s is an integer > 0. NOTE: using the Java Long object for greatest precision */
0380: public static boolean isPositiveInteger(String s) {
0381: if (isEmpty(s))
0382: return defaultEmptyOK;
0383:
0384: try {
0385: long temp = Long.parseLong(s);
0386:
0387: if (temp > 0)
0388: return true;
0389: return false;
0390: } catch (Exception e) {
0391: return false;
0392: }
0393:
0394: // return(isSignedInteger(s, secondArg)
0395: // &&((isEmpty(s) && secondArg) ||(parseInt(s) > 0) ) );
0396: }
0397:
0398: /** Returns true if string s is an integer >= 0. */
0399: public static boolean isNonnegativeInteger(String s) {
0400: if (isEmpty(s))
0401: return defaultEmptyOK;
0402:
0403: try {
0404: int temp = Integer.parseInt(s);
0405:
0406: if (temp >= 0)
0407: return true;
0408: return false;
0409: } catch (Exception e) {
0410: return false;
0411: }
0412:
0413: // return(isSignedInteger(s, secondArg)
0414: // &&((isEmpty(s) && secondArg) ||(parseInt(s) >= 0) ) );
0415: }
0416:
0417: /** Returns true if string s is an integer < 0. */
0418: public static boolean isNegativeInteger(String s) {
0419: if (isEmpty(s))
0420: return defaultEmptyOK;
0421:
0422: try {
0423: int temp = Integer.parseInt(s);
0424:
0425: if (temp < 0)
0426: return true;
0427: return false;
0428: } catch (Exception e) {
0429: return false;
0430: }
0431:
0432: // return(isSignedInteger(s, secondArg)
0433: // &&((isEmpty(s) && secondArg) ||(parseInt(s) < 0) ) );
0434: }
0435:
0436: /** Returns true if string s is an integer <= 0. */
0437: public static boolean isNonpositiveInteger(String s) {
0438: if (isEmpty(s))
0439: return defaultEmptyOK;
0440:
0441: try {
0442: int temp = Integer.parseInt(s);
0443:
0444: if (temp <= 0)
0445: return true;
0446: return false;
0447: } catch (Exception e) {
0448: return false;
0449: }
0450:
0451: // return(isSignedInteger(s, secondArg)
0452: // &&((isEmpty(s) && secondArg) ||(parseInt(s) <= 0) ) );
0453: }
0454:
0455: /** True if string s is an unsigned floating point(real) number.
0456: *
0457: * Also returns true for unsigned integers. If you wish
0458: * to distinguish between integers and floating point numbers,
0459: * first call isInteger, then call isFloat.
0460: *
0461: * Does not accept exponential notation.
0462: */
0463: public static boolean isFloat(String s) {
0464: if (isEmpty(s))
0465: return defaultEmptyOK;
0466:
0467: boolean seenDecimalPoint = false;
0468:
0469: if (s.startsWith(decimalPointDelimiter))
0470: return false;
0471:
0472: // Search through string's characters one by one
0473: // until we find a non-numeric character.
0474: // When we do, return false; if we don't, return true.
0475: for (int i = 0; i < s.length(); i++) {
0476: // Check that current character is number.
0477: char c = s.charAt(i);
0478:
0479: if (c == decimalPointDelimiter.charAt(0)) {
0480: if (!seenDecimalPoint) {
0481: seenDecimalPoint = true;
0482: } else {
0483: return false;
0484: }
0485: } else {
0486: if (!isDigit(c))
0487: return false;
0488: }
0489: }
0490: // All characters are numbers.
0491: return true;
0492: }
0493:
0494: /** General routine for testing whether a string is a float.
0495: */
0496: public static boolean isFloat(String s, boolean allowNegative,
0497: boolean allowPositive, int minDecimal, int maxDecimal) {
0498: if (isEmpty(s))
0499: return defaultEmptyOK;
0500:
0501: try {
0502: float temp = Float.parseFloat(s);
0503: if (!allowNegative && temp < 0)
0504: return false;
0505: if (!allowPositive && temp > 0)
0506: return false;
0507: String floatString = Float.toString(temp);
0508: int decimalPoint = floatString.indexOf(".");
0509: if (decimalPoint == -1) {
0510: if (minDecimal > 0)
0511: return false;
0512: return true;
0513: }
0514: // 1.2345; length=6; point=1; num=4
0515: int numDecimals = floatString.length() - decimalPoint;
0516: if (minDecimal >= 0 && numDecimals < minDecimal)
0517: return false;
0518: if (maxDecimal >= 0 && numDecimals > maxDecimal)
0519: return false;
0520: return true;
0521: } catch (Exception e) {
0522: return false;
0523: }
0524: }
0525:
0526: /** General routine for testing whether a string is a double.
0527: */
0528: public static boolean isDouble(String s, boolean allowNegative,
0529: boolean allowPositive, int minDecimal, int maxDecimal) {
0530: if (isEmpty(s))
0531: return defaultEmptyOK;
0532:
0533: try {
0534: double temp = Double.parseDouble(s);
0535: if (!allowNegative && temp < 0)
0536: return false;
0537: if (!allowPositive && temp > 0)
0538: return false;
0539: String doubleString = Double.toString(temp);
0540: int decimalPoint = doubleString.indexOf(".");
0541: if (decimalPoint == -1) {
0542: if (minDecimal > 0)
0543: return false;
0544: return true;
0545: }
0546: // 1.2345; length=6; point=1; num=4
0547: int numDecimals = doubleString.length() - decimalPoint;
0548: if (minDecimal >= 0 && numDecimals < minDecimal)
0549: return false;
0550: if (maxDecimal >= 0 && numDecimals > maxDecimal)
0551: return false;
0552: return true;
0553: } catch (Exception e) {
0554: return false;
0555: }
0556: }
0557:
0558: /** True if string s is a signed or unsigned floating point
0559: * (real) number. First character is allowed to be + or -.
0560: *
0561: * Also returns true for unsigned integers. If you wish
0562: * to distinguish between integers and floating point numbers,
0563: * first call isSignedInteger, then call isSignedFloat.
0564: */
0565: public static boolean isSignedFloat(String s) {
0566: if (isEmpty(s))
0567: return defaultEmptyOK;
0568: try {
0569: Float.parseFloat(s);
0570: return true;
0571: } catch (Exception e) {
0572: return false;
0573: }
0574:
0575: //The old way:
0576: // int startPos = 0;
0577: // if(isSignedFloat.arguments.length > 1) secondArg = isSignedFloat.arguments[1];
0578: // skip leading + or -
0579: // if((s.charAt(0) == "-") ||(s.charAt(0) == "+") ) startPos = 1;
0580: // return(isFloat(s.substring(startPos, s.length), secondArg))
0581: }
0582:
0583: /** True if string s is a signed or unsigned floating point
0584: * (real) number. First character is allowed to be + or -.
0585: *
0586: * Also returns true for unsigned integers. If you wish
0587: * to distinguish between integers and floating point numbers,
0588: * first call isSignedInteger, then call isSignedFloat.
0589: */
0590: public static boolean isSignedDouble(String s) {
0591: if (isEmpty(s))
0592: return defaultEmptyOK;
0593: try {
0594: Double.parseDouble(s);
0595: return true;
0596: } catch (Exception e) {
0597: return false;
0598: }
0599: }
0600:
0601: /** Returns true if string s is letters only.
0602: *
0603: * NOTE: This should handle i18n version to support European characters, etc.
0604: * since it now uses Character.isLetter()
0605: */
0606: public static boolean isAlphabetic(String s) {
0607: if (isEmpty(s))
0608: return defaultEmptyOK;
0609:
0610: // Search through string's characters one by one
0611: // until we find a non-alphabetic character.
0612: // When we do, return false; if we don't, return true.
0613: for (int i = 0; i < s.length(); i++) {
0614: // Check that current character is letter.
0615: char c = s.charAt(i);
0616:
0617: if (!isLetter(c))
0618: return false;
0619: }
0620:
0621: // All characters are letters.
0622: return true;
0623: }
0624:
0625: /** Returns true if string s is English letters (A .. Z, a..z) and numbers only.
0626: *
0627: * NOTE: Need i18n version to support European characters.
0628: * This could be tricky due to different character
0629: * sets and orderings for various languages and platforms.
0630: */
0631: public static boolean isAlphanumeric(String s) {
0632: if (isEmpty(s))
0633: return defaultEmptyOK;
0634:
0635: // Search through string's characters one by one
0636: // until we find a non-alphanumeric character.
0637: // When we do, return false; if we don't, return true.
0638: for (int i = 0; i < s.length(); i++) {
0639: // Check that current character is number or letter.
0640: char c = s.charAt(i);
0641:
0642: if (!isLetterOrDigit(c))
0643: return false;
0644: }
0645:
0646: // All characters are numbers or letters.
0647: return true;
0648: }
0649:
0650: /* ================== METHODS TO CHECK VARIOUS FIELDS. ==================== */
0651:
0652: /** isSSN returns true if string s is a valid U.S. Social Security Number. Must be 9 digits. */
0653: public static boolean isSSN(String s) {
0654: if (isEmpty(s))
0655: return defaultEmptyOK;
0656:
0657: String normalizedSSN = stripCharsInBag(s, SSNDelimiters);
0658:
0659: return (isInteger(normalizedSSN) && normalizedSSN.length() == digitsInSocialSecurityNumber);
0660: }
0661:
0662: /** isUSPhoneNumber returns true if string s is a valid U.S. Phone Number. Must be 10 digits. */
0663: public static boolean isUSPhoneNumber(String s) {
0664: if (isEmpty(s))
0665: return defaultEmptyOK;
0666: String normalizedPhone = stripCharsInBag(s,
0667: phoneNumberDelimiters);
0668:
0669: return (isInteger(normalizedPhone) && normalizedPhone.length() == digitsInUSPhoneNumber);
0670: }
0671:
0672: /** isUSPhoneAreaCode returns true if string s is a valid U.S. Phone Area Code. Must be 3 digits. */
0673: public static boolean isUSPhoneAreaCode(String s) {
0674: if (isEmpty(s))
0675: return defaultEmptyOK;
0676: String normalizedPhone = stripCharsInBag(s,
0677: phoneNumberDelimiters);
0678:
0679: return (isInteger(normalizedPhone) && normalizedPhone.length() == digitsInUSPhoneAreaCode);
0680: }
0681:
0682: /** isUSPhoneMainNumber returns true if string s is a valid U.S. Phone Main Number. Must be 7 digits. */
0683: public static boolean isUSPhoneMainNumber(String s) {
0684: if (isEmpty(s))
0685: return defaultEmptyOK;
0686: String normalizedPhone = stripCharsInBag(s,
0687: phoneNumberDelimiters);
0688:
0689: return (isInteger(normalizedPhone) && normalizedPhone.length() == digitsInUSPhoneMainNumber);
0690: }
0691:
0692: /** isInternationalPhoneNumber returns true if string s is a valid
0693: * international phone number. Must be digits only; any length OK.
0694: * May be prefixed by + character.
0695: */
0696: public static boolean isInternationalPhoneNumber(String s) {
0697: if (isEmpty(s))
0698: return defaultEmptyOK;
0699:
0700: String normalizedPhone = stripCharsInBag(s,
0701: phoneNumberDelimiters);
0702:
0703: return isPositiveInteger(normalizedPhone);
0704: }
0705:
0706: /** isZIPCode returns true if string s is a valid U.S. ZIP code. Must be 5 or 9 digits only. */
0707: public static boolean isZipCode(String s) {
0708: if (isEmpty(s))
0709: return defaultEmptyOK;
0710:
0711: String normalizedZip = stripCharsInBag(s, ZipCodeDelimiters);
0712:
0713: return (isInteger(normalizedZip) && ((normalizedZip.length() == digitsInZipCode1) || (normalizedZip
0714: .length() == digitsInZipCode2)));
0715: }
0716:
0717: /** Returns true if string s is a valid contiguous U.S. Zip code. Must be 5 or 9 digits only. */
0718: public static boolean isContiguousZipCode(String s) {
0719: boolean retval = false;
0720: if (isZipCode(s)) {
0721: if (isEmpty(s))
0722: retval = defaultEmptyOK;
0723: else {
0724: String normalizedZip = s.substring(0, 5);
0725: int iZip = Integer.parseInt(normalizedZip);
0726: if ((iZip >= 96701 && iZip <= 96898)
0727: || (iZip >= 99501 && iZip <= 99950))
0728: retval = false;
0729: else
0730: retval = true;
0731: }
0732: }
0733: return retval;
0734: }
0735:
0736: /** Return true if s is a valid U.S. Postal Code (abbreviation for state). */
0737: public static boolean isStateCode(String s) {
0738: if (isEmpty(s))
0739: return defaultEmptyOK;
0740: return ((USStateCodes.indexOf(s) != -1) && (s
0741: .indexOf(USStateCodeDelimiter) == -1));
0742: }
0743:
0744: /** Return true if s is a valid contiguous U.S. Postal Code (abbreviation for state). */
0745: public static boolean isContiguousStateCode(String s) {
0746: if (isEmpty(s))
0747: return defaultEmptyOK;
0748: return ((ContiguousUSStateCodes.indexOf(s) != -1) && (s
0749: .indexOf(USStateCodeDelimiter) == -1));
0750: }
0751:
0752: public static boolean isEmail(String s) {
0753: return isEmail(s, false);
0754: }
0755:
0756: /** Email address must be of form a@b.c -- in other words:
0757: * - there must be at least one character before the @
0758: * - there must be at least one character before and after the .
0759: * - the character @ is required, and . requirement is controlled
0760: * - by requireDot
0761: */
0762: public static boolean isEmail(String s, boolean requireDot) {
0763:
0764: // todo: use regular expression validation
0765:
0766: if (isEmpty(s))
0767: return defaultEmptyOK;
0768:
0769: // is s whitespace?
0770: if (isWhitespace(s))
0771: return false;
0772:
0773: int atSymbolIndex = s.indexOf('@');
0774:
0775: // there must be >= 1 character before @
0776: // indexOf returns -1 if char not found, so 0 or -1 are bad
0777: if (atSymbolIndex <= 0)
0778: return false;
0779:
0780: if (requireDot) {
0781: int dotIndex = s.lastIndexOf('.');
0782: if (dotIndex == -1)
0783: return false; // no dot
0784: if (dotIndex < atSymbolIndex + 2)
0785: return false; // nothing between @ and .
0786: if (dotIndex == s.length() - 1)
0787: return false; // . is last character
0788: }
0789:
0790: return true;
0791: }
0792:
0793: /** isUrl returns true if the string contains ://
0794: * @param s String to validate
0795: * @return true if s contains ://
0796: */
0797: public static boolean isUrl(String s) {
0798: if (isEmpty(s))
0799: return defaultEmptyOK;
0800: if (s.indexOf("://") != -1)
0801: return true;
0802: return false;
0803: }
0804:
0805: /** isYear returns true if string s is a valid
0806: * Year number. Must be 2 or 4 digits only.
0807: *
0808: * For Year 2000 compliance, you are advised
0809: * to use 4-digit year numbers everywhere.
0810: */
0811: public static boolean isYear(String s) {
0812: if (isEmpty(s))
0813: return defaultEmptyOK;
0814:
0815: if (!isNonnegativeInteger(s))
0816: return false;
0817: return ((s.length() == 2) || (s.length() == 4));
0818: }
0819:
0820: /** isIntegerInRange returns true if string s is an integer
0821: * within the range of integer arguments a and b, inclusive.
0822: */
0823: public static boolean isIntegerInRange(String s, int a, int b) {
0824: if (isEmpty(s))
0825: return defaultEmptyOK;
0826: // Catch non-integer strings to avoid creating a NaN below,
0827: // which isn't available on JavaScript 1.0 for Windows.
0828: if (!isSignedInteger(s))
0829: return false;
0830: // Now, explicitly change the type to integer via parseInt
0831: // so that the comparison code below will work both on
0832: // JavaScript 1.2(which typechecks in equality comparisons)
0833: // and JavaScript 1.1 and before(which doesn't).
0834: int num = Integer.parseInt(s);
0835:
0836: return ((num >= a) && (num <= b));
0837: }
0838:
0839: /** isMonth returns true if string s is a valid month number between 1 and 12. */
0840: public static boolean isMonth(String s) {
0841: if (isEmpty(s))
0842: return defaultEmptyOK;
0843: return isIntegerInRange(s, 1, 12);
0844: }
0845:
0846: /** isDay returns true if string s is a valid day number between 1 and 31. */
0847: public static boolean isDay(String s) {
0848: if (isEmpty(s))
0849: return defaultEmptyOK;
0850: return isIntegerInRange(s, 1, 31);
0851: }
0852:
0853: /** Given integer argument year, returns number of days in February of that year. */
0854: public static int daysInFebruary(int year) {
0855: // February has 29 days in any year evenly divisible by four,
0856: // EXCEPT for centurial years which are not also divisible by 400.
0857: return (((year % 4 == 0) && ((!(year % 100 == 0)) || (year % 400 == 0))) ? 29
0858: : 28);
0859: }
0860:
0861: /** isHour returns true if string s is a valid number between 0 and 23. */
0862: public static boolean isHour(String s) {
0863: if (isEmpty(s))
0864: return defaultEmptyOK;
0865: return isIntegerInRange(s, 0, 23);
0866: }
0867:
0868: /** isMinute returns true if string s is a valid number between 0 and 59. */
0869: public static boolean isMinute(String s) {
0870: if (isEmpty(s))
0871: return defaultEmptyOK;
0872: return isIntegerInRange(s, 0, 59);
0873: }
0874:
0875: /** isSecond returns true if string s is a valid number between 0 and 59. */
0876: public static boolean isSecond(String s) {
0877: if (isEmpty(s))
0878: return defaultEmptyOK;
0879: return isIntegerInRange(s, 0, 59);
0880: }
0881:
0882: /** isDate returns true if string arguments year, month, and day form a valid date. */
0883: public static boolean isDate(String year, String month, String day) {
0884: // catch invalid years(not 2- or 4-digit) and invalid months and days.
0885: if (!(isYear(year) && isMonth(month) && isDay(day)))
0886: return false;
0887:
0888: int intYear = Integer.parseInt(year);
0889: int intMonth = Integer.parseInt(month);
0890: int intDay = Integer.parseInt(day);
0891:
0892: // catch invalid days, except for February
0893: if (intDay > daysInMonth[intMonth - 1])
0894: return false;
0895: if ((intMonth == 2) && (intDay > daysInFebruary(intYear)))
0896: return false;
0897: return true;
0898: }
0899:
0900: /** isDate returns true if string argument date forms a valid date. */
0901: public static boolean isDate(String date) {
0902: if (isEmpty(date))
0903: return defaultEmptyOK;
0904: String month;
0905: String day;
0906: String year;
0907:
0908: int dateSlash1 = date.indexOf("/");
0909: int dateSlash2 = date.lastIndexOf("/");
0910:
0911: if (dateSlash1 <= 0 || dateSlash1 == dateSlash2)
0912: return false;
0913: month = date.substring(0, dateSlash1);
0914: day = date.substring(dateSlash1 + 1, dateSlash2);
0915: year = date.substring(dateSlash2 + 1);
0916:
0917: return isDate(year, month, day);
0918: }
0919:
0920: /** isDate returns true if string argument date forms a valid date and is after today. */
0921: public static boolean isDateAfterToday(String date) {
0922: if (isEmpty(date))
0923: return defaultEmptyOK;
0924: int dateSlash1 = date.indexOf("/");
0925: int dateSlash2 = date.lastIndexOf("/");
0926:
0927: if (dateSlash1 <= 0)
0928: return false;
0929:
0930: java.util.Date passed = null;
0931: if (dateSlash1 == dateSlash2) {
0932: // consider the day to be optional; use the first day of the following month for comparison since this is an is after test
0933: String month = date.substring(0, dateSlash1);
0934: String day = "28";
0935: String year = date.substring(dateSlash1 + 1);
0936: if (!isDate(year, month, day))
0937: return false;
0938:
0939: try {
0940: int monthInt = Integer.parseInt(month);
0941: int yearInt = Integer.parseInt(year);
0942: Calendar calendar = Calendar.getInstance();
0943: calendar.set(yearInt, monthInt - 1, 0, 0, 0, 0);
0944: calendar.add(Calendar.MONTH, 1);
0945: passed = new java.util.Date(calendar.getTime()
0946: .getTime());
0947: } catch (Exception e) {
0948: passed = null;
0949: }
0950: } else {
0951: String month = date.substring(0, dateSlash1);
0952: String day = date.substring(dateSlash1 + 1, dateSlash2);
0953: String year = date.substring(dateSlash2 + 1);
0954: if (!isDate(year, month, day))
0955: return false;
0956: passed = UtilDateTime.toDate(month, day, year, "0", "0",
0957: "0");
0958: }
0959:
0960: java.util.Date now = UtilDateTime.nowDate();
0961: if (passed != null) {
0962: return passed.after(now);
0963: } else {
0964: return false;
0965: }
0966: }
0967:
0968: /** isDate returns true if string argument date forms a valid date and is before today. */
0969: public static boolean isDateBeforeToday(String date) {
0970: if (isEmpty(date))
0971: return defaultEmptyOK;
0972: int dateSlash1 = date.indexOf("/");
0973: int dateSlash2 = date.lastIndexOf("/");
0974:
0975: if (dateSlash1 <= 0)
0976: return defaultEmptyOK; // In this case an issue number has been provided (requires a javascript check in template!)
0977:
0978: java.util.Date passed = null;
0979: if (dateSlash1 == dateSlash2) {
0980: // consider the day to be optional; use the first day of the following month for comparison since this is an is after test
0981: String month = date.substring(0, dateSlash1);
0982: String day = "28";
0983: String year = date.substring(dateSlash1 + 1);
0984: if (!isDate(year, month, day))
0985: return false;
0986:
0987: try {
0988: int monthInt = Integer.parseInt(month);
0989: int yearInt = Integer.parseInt(year);
0990: Calendar calendar = Calendar.getInstance();
0991: calendar.set(yearInt, monthInt - 1, 0, 0, 0, 0);
0992: calendar.add(Calendar.MONTH, 1);
0993: passed = new java.util.Date(calendar.getTime()
0994: .getTime());
0995: } catch (Exception e) {
0996: passed = null;
0997: }
0998: } else {
0999: String month = date.substring(0, dateSlash1);
1000: String day = date.substring(dateSlash1 + 1, dateSlash2);
1001: String year = date.substring(dateSlash2 + 1);
1002: if (!isDate(year, month, day))
1003: return false;
1004: passed = UtilDateTime.toDate(month, day, year, "0", "0",
1005: "0");
1006: }
1007:
1008: java.util.Date now = UtilDateTime.nowDate();
1009: if (passed != null) {
1010: return passed.before(now);
1011: } else {
1012: return false;
1013: }
1014: }
1015:
1016: /** isTime returns true if string arguments hour, minute, and second form a valid time. */
1017: public static boolean isTime(String hour, String minute,
1018: String second) {
1019: // catch invalid years(not 2- or 4-digit) and invalid months and days.
1020: if (isHour(hour) && isMinute(minute) && isSecond(second))
1021: return true;
1022: else
1023: return false;
1024: }
1025:
1026: /** isTime returns true if string argument time forms a valid time. */
1027: public static boolean isTime(String time) {
1028: if (isEmpty(time))
1029: return defaultEmptyOK;
1030:
1031: String hour;
1032: String minute;
1033: String second;
1034:
1035: int timeColon1 = time.indexOf(":");
1036: int timeColon2 = time.lastIndexOf(":");
1037:
1038: if (timeColon1 <= 0)
1039: return false;
1040: hour = time.substring(0, timeColon1);
1041: if (timeColon1 == timeColon2) {
1042: minute = time.substring(timeColon1 + 1);
1043: second = "0";
1044: } else {
1045: minute = time.substring(timeColon1 + 1, timeColon2);
1046: second = time.substring(timeColon2 + 1);
1047: }
1048: return isTime(hour, minute, second);
1049: }
1050:
1051: /** Check to see if a card number is a valid ValueLink Gift Card
1052: *
1053: * @param stPassed a string representing a valuelink gift card
1054: * @return true, if the number passed simple checks
1055: */
1056: public static boolean isValueLinkCard(String stPassed) {
1057: if (isEmpty(stPassed))
1058: return defaultEmptyOK;
1059: String st = stripCharsInBag(stPassed, creditCardDelimiters);
1060: if (st.length() == 16
1061: && (st.startsWith("7") || st.startsWith("6"))) {
1062: return true;
1063: }
1064: return false;
1065: }
1066:
1067: /** Check to see if a card number is a valid OFB Gift Card (Certifiicate)
1068: *
1069: * @param stPassed a string representing a gift card
1070: * @return tru, if the number passed simple checks
1071: */
1072: public static boolean isOFBGiftCard(String stPassed) {
1073: if (isEmpty(stPassed))
1074: return defaultEmptyOK;
1075: String st = stripCharsInBag(stPassed, creditCardDelimiters);
1076: if (st.length() == 15 && sumIsMod10(getLuhnSum(st))) {
1077: return true;
1078: }
1079: return false;
1080: }
1081:
1082: /** Check to see if a card number is a supported Gift Card
1083: *
1084: * @param stPassed a string representing a gift card
1085: * @return true, if the number passed simple checks
1086: */
1087: public static boolean isGiftCard(String stPassed) {
1088: if (isOFBGiftCard(stPassed)) {
1089: return true;
1090: } else if (isValueLinkCard(stPassed)) {
1091: return true;
1092: }
1093: return false;
1094: }
1095:
1096: public static int getLuhnSum(String stPassed) {
1097: stPassed = stPassed.replaceAll("\\D", ""); // nuke any non-digit characters
1098:
1099: int len = stPassed.length();
1100: int sum = 0;
1101: int mul = 1;
1102: for (int i = len - 1; i >= 0; i--) {
1103: int digit = Character.digit(stPassed.charAt(i), 10);
1104: digit *= (mul == 1) ? mul++ : mul--;
1105: sum += (digit >= 10) ? (digit % 10) + 1 : digit;
1106: }
1107:
1108: return sum;
1109: }
1110:
1111: public static int getLuhnCheckDigit(String stPassed) {
1112: int sum = getLuhnSum(stPassed);
1113: int mod = ((sum / 10 + 1) * 10 - sum) % 10;
1114: return (10 - mod);
1115: }
1116:
1117: public static boolean sumIsMod10(int sum) {
1118: return ((sum % 10) == 0);
1119: }
1120:
1121: public static String appendCheckDigit(String stPassed) {
1122: String checkDigit = Integer
1123: .toString(getLuhnCheckDigit(stPassed));
1124: return stPassed + checkDigit;
1125: }
1126:
1127: /** Checks credit card number with Luhn Mod-10 test
1128: *
1129: * @param stPassed a string representing a credit card number
1130: * @return true, if the credit card number passes the Luhn Mod-10 test, false otherwise
1131: */
1132: public static boolean isCreditCard(String stPassed) {
1133: if (isEmpty(stPassed))
1134: return defaultEmptyOK;
1135: String st = stripCharsInBag(stPassed, creditCardDelimiters);
1136:
1137: // encoding only works on cars with less the 19 digits
1138: if (st.length() > 19)
1139: return false;
1140: return sumIsMod10(getLuhnSum(st));
1141: }
1142:
1143: /** Checks to see if the cc number is a valid Visa number
1144: *
1145: * @param cc a string representing a credit card number; Sample number: 4111 1111 1111 1111(16 digits)
1146: * @return true, if the credit card number is a valid VISA number, false otherwise
1147: */
1148: public static boolean isVisa(String cc) {
1149: if (((cc.length() == 16) || (cc.length() == 13))
1150: && (cc.substring(0, 1).equals("4")))
1151: return isCreditCard(cc);
1152: return false;
1153: }
1154:
1155: /** Checks to see if the cc number is a valid Master Card number
1156: *
1157: * @param cc a string representing a credit card number; Sample number: 5500 0000 0000 0004(16 digits)
1158: * @return true, if the credit card number is a valid MasterCard number, false otherwise
1159: */
1160: public static boolean isMasterCard(String cc) {
1161: int firstdig = Integer.parseInt(cc.substring(0, 1));
1162: int seconddig = Integer.parseInt(cc.substring(1, 2));
1163:
1164: if ((cc.length() == 16) && (firstdig == 5)
1165: && ((seconddig >= 1) && (seconddig <= 5)))
1166: return isCreditCard(cc);
1167: return false;
1168:
1169: }
1170:
1171: /** Checks to see if the cc number is a valid American Express number
1172: * @param cc - a string representing a credit card number; Sample number: 340000000000009(15 digits)
1173: * @return true, if the credit card number is a valid American Express number, false otherwise
1174: */
1175: public static boolean isAmericanExpress(String cc) {
1176: int firstdig = Integer.parseInt(cc.substring(0, 1));
1177: int seconddig = Integer.parseInt(cc.substring(1, 2));
1178:
1179: if ((cc.length() == 15) && (firstdig == 3)
1180: && ((seconddig == 4) || (seconddig == 7)))
1181: return isCreditCard(cc);
1182: return false;
1183:
1184: }
1185:
1186: /** Checks to see if the cc number is a valid Diners Club number
1187: * @param cc - a string representing a credit card number; Sample number: 30000000000004(14 digits)
1188: * @return true, if the credit card number is a valid Diner's Club number, false otherwise
1189: */
1190: public static boolean isDinersClub(String cc) {
1191: int firstdig = Integer.parseInt(cc.substring(0, 1));
1192: int seconddig = Integer.parseInt(cc.substring(1, 2));
1193:
1194: if ((cc.length() == 14)
1195: && (firstdig == 3)
1196: && ((seconddig == 0) || (seconddig == 6) || (seconddig == 8)))
1197: return isCreditCard(cc);
1198: return false;
1199: }
1200:
1201: /** Checks to see if the cc number is a valid Carte Blanche number
1202: * @param cc - a string representing a credit card number; Sample number: 30000000000004(14 digits)
1203: * @return true, if the credit card number is a valid Carte Blanche number, false otherwise
1204: */
1205: public static boolean isCarteBlanche(String cc) {
1206: return isDinersClub(cc);
1207: }
1208:
1209: /** Checks to see if the cc number is a valid Discover number
1210: * @param cc - a string representing a credit card number; Sample number: 6011000000000004(16 digits)
1211: * @return true, if the credit card number is a valid Discover card number, false otherwise
1212: */
1213: public static boolean isDiscover(String cc) {
1214: String first4digs = cc.substring(0, 4);
1215:
1216: if ((cc.length() == 16) && (first4digs.equals("6011")))
1217: return isCreditCard(cc);
1218: return false;
1219: }
1220:
1221: /** Checks to see if the cc number is a valid EnRoute number
1222: * @param cc - a string representing a credit card number; Sample number: 201400000000009(15 digits)
1223: * @return true, if the credit card number is a valid enRoute card number, false, otherwise
1224: */
1225: public static boolean isEnRoute(String cc) {
1226: String first4digs = cc.substring(0, 4);
1227:
1228: if ((cc.length() == 15)
1229: && (first4digs.equals("2014") || first4digs
1230: .equals("2149")))
1231: return isCreditCard(cc);
1232: return false;
1233: }
1234:
1235: /** Checks to see if the cc number is a valid JCB number
1236: * @param cc - a string representing a credit card number; Sample number: 3088000000000009(16 digits)
1237: * @return true, if the credit card number is a valid JCB card number, false otherwise
1238: */
1239: public static boolean isJCB(String cc) {
1240: String first4digs = cc.substring(0, 4);
1241:
1242: if ((cc.length() == 16)
1243: && (first4digs.equals("3088")
1244: || first4digs.equals("3096")
1245: || first4digs.equals("3112")
1246: || first4digs.equals("3158")
1247: || first4digs.equals("3337") || first4digs
1248: .equals("3528")))
1249: return isCreditCard(cc);
1250: return false;
1251: }
1252:
1253: /** Checks to see if the cc number is a valid Switch number
1254: * @param cc - a string representing a credit card number; Sample number: 6331100000000096(16 digits)
1255: * @return true, if the credit card number is a valid Switch card number, false otherwise
1256: */
1257: public static boolean isSwitch(String cc) {
1258: String first4digs = cc.substring(0, 4);
1259: String first6digs = cc.substring(0, 6);
1260:
1261: if (((cc.length() == 16) || (cc.length() == 18) || (cc.length() == 19))
1262: && (first4digs.equals("4903")
1263: || first4digs.equals("4905")
1264: || first4digs.equals("4911")
1265: || first4digs.equals("4936")
1266: || first6digs.equals("564182")
1267: || first6digs.equals("633110")
1268: || first4digs.equals("6333") || first4digs
1269: .equals("6759")))
1270: return isCreditCard(cc);
1271: return false;
1272: }
1273:
1274: /** Checks to see if the cc number is a valid Solo number
1275: * @param cc - a string representing a credit card number; Sample number: 6331100000000096 (16 digits)
1276: * @return true, if the credit card number is a valid Solo card number, false otherwise
1277: */
1278: public static boolean isSolo(String cc) {
1279: String first4digs = cc.substring(0, 4);
1280: String first2digs = cc.substring(0, 2);
1281: if (((cc.length() == 16) || (cc.length() == 18) || (cc.length() == 19))
1282: && (first2digs.equals("63") || first4digs
1283: .equals("6767")))
1284: return isCreditCard(cc);
1285: return false;
1286: }
1287:
1288: /** Checks to see if the cc number is a valid Visa Electron number
1289: * @param cc - a string representing a credit card number; Sample number: 4175000000000001(16 digits)
1290: * @return true, if the credit card number is a valid Visa Electron card number, false otherwise
1291: */
1292: public static boolean isVisaElectron(String cc) {
1293: String first6digs = cc.substring(0, 6);
1294:
1295: if ((cc.length() == 16) && (first6digs.equals("417500")))
1296: return isCreditCard(cc);
1297: return false;
1298: }
1299:
1300: /** Checks to see if the cc number is a valid number for any accepted credit card
1301: * @param ccPassed - a string representing a credit card number
1302: * @return true, if the credit card number is any valid credit card number for any of the accepted card types, false otherwise
1303: */
1304: public static boolean isAnyCard(String ccPassed) {
1305: if (isEmpty(ccPassed))
1306: return defaultEmptyOK;
1307:
1308: String cc = stripCharsInBag(ccPassed, creditCardDelimiters);
1309:
1310: if (!isCreditCard(cc))
1311: return false;
1312: if (isMasterCard(cc) || isVisa(cc) || isAmericanExpress(cc)
1313: || isDinersClub(cc) || isDiscover(cc) || isEnRoute(cc)
1314: || isJCB(cc) || isSolo(cc) || isSwitch(cc)
1315: || isVisaElectron(cc))
1316: return true;
1317: return false;
1318: }
1319:
1320: /** Checks to see if the cc number is a valid number for any accepted credit card, and return the name of that type
1321: * @param ccPassed - a string representing a credit card number
1322: * @return true, if the credit card number is any valid credit card number for any of the accepted card types, false otherwise
1323: */
1324: public static String getCardType(String ccPassed) {
1325: if (isEmpty(ccPassed))
1326: return "Unknown";
1327: String cc = stripCharsInBag(ccPassed, creditCardDelimiters);
1328:
1329: if (!isCreditCard(cc))
1330: return "Unknown";
1331:
1332: if (isMasterCard(cc))
1333: return "MasterCard";
1334: if (isVisa(cc))
1335: return "Visa";
1336: if (isAmericanExpress(cc))
1337: return "AmericanExpress";
1338: if (isDinersClub(cc))
1339: return "DinersClub";
1340: if (isDiscover(cc))
1341: return "Discover";
1342: if (isEnRoute(cc))
1343: return "EnRoute";
1344: if (isJCB(cc))
1345: return "JCB";
1346: if (isSolo(cc))
1347: return "Solo";
1348: if (isSwitch(cc))
1349: return "Switch";
1350: if (isVisaElectron(cc))
1351: return "VisaElectron";
1352: return "Unknown";
1353: }
1354:
1355: /** Checks to see if the cc number is a valid number for the specified type
1356: * @param cardType - a string representing the credit card type
1357: * @param cardNumberPassed - a string representing a credit card number
1358: * @return true, if the credit card number is valid for the particular credit card type given in "cardType", false otherwise
1359: */
1360: public static boolean isCardMatch(String cardType,
1361: String cardNumberPassed) {
1362: if (isEmpty(cardType))
1363: return defaultEmptyOK;
1364: if (isEmpty(cardNumberPassed))
1365: return defaultEmptyOK;
1366: String cardNumber = stripCharsInBag(cardNumberPassed,
1367: creditCardDelimiters);
1368:
1369: if ((cardType.equalsIgnoreCase("VISA")) && (isVisa(cardNumber)))
1370: return true;
1371: if ((cardType.equalsIgnoreCase("MASTERCARD"))
1372: && (isMasterCard(cardNumber)))
1373: return true;
1374: if (((cardType.equalsIgnoreCase("AMERICANEXPRESS")) || (cardType
1375: .equalsIgnoreCase("AMEX")))
1376: && (isAmericanExpress(cardNumber)))
1377: return true;
1378: if ((cardType.equalsIgnoreCase("DISCOVER"))
1379: && (isDiscover(cardNumber)))
1380: return true;
1381: if ((cardType.equalsIgnoreCase("JCB")) && (isJCB(cardNumber)))
1382: return true;
1383: if (((cardType.equalsIgnoreCase("DINERSCLUB")) || (cardType
1384: .equalsIgnoreCase("DINERS")))
1385: && (isDinersClub(cardNumber)))
1386: return true;
1387: if ((cardType.equalsIgnoreCase("CARTEBLANCHE"))
1388: && (isCarteBlanche(cardNumber)))
1389: return true;
1390: if ((cardType.equalsIgnoreCase("ENROUTE"))
1391: && (isEnRoute(cardNumber)))
1392: return true;
1393: if ((cardType.equalsIgnoreCase("SOLO")) && (isSolo(cardNumber)))
1394: return true;
1395: if ((cardType.equalsIgnoreCase("SWITCH"))
1396: && (isSwitch(cardNumber)))
1397: return true;
1398: if ((cardType.equalsIgnoreCase("VISAELECTRON"))
1399: && (isVisaElectron(cardNumber)))
1400: return true;
1401: return false;
1402: }
1403:
1404: /** isNotPoBox returns true if address argument does not contain anything that looks like a a PO Box. */
1405: public static boolean isNotPoBox(String s) {
1406: if (isEmpty(s))
1407: return defaultEmptyOK;
1408:
1409: // strings to check from Greg's program
1410: // "P.O. B"
1411: // "P.o.B"
1412: // "P.O B"
1413: // "PO. B"
1414: // "P O B"
1415: // "PO B"
1416: // "P.0. B"
1417: // "P0 B"
1418:
1419: String sl = s.toLowerCase();
1420: if (sl.indexOf("p.o. b") != -1)
1421: return false;
1422: if (sl.indexOf("p.o.b") != -1)
1423: return false;
1424: if (sl.indexOf("p.o b") != -1)
1425: return false;
1426: if (sl.indexOf("p o b") != -1)
1427: return false;
1428: if (sl.indexOf("po b") != -1)
1429: return false;
1430: if (sl.indexOf("pobox") != -1)
1431: return false;
1432: if (sl.indexOf("po#") != -1)
1433: return false;
1434: if (sl.indexOf("po #") != -1)
1435: return false;
1436:
1437: // now with 0's for them sneaky folks
1438: if (sl.indexOf("p.0. b") != -1)
1439: return false;
1440: if (sl.indexOf("p.0.b") != -1)
1441: return false;
1442: if (sl.indexOf("p.0 b") != -1)
1443: return false;
1444: if (sl.indexOf("p 0 b") != -1)
1445: return false;
1446: if (sl.indexOf("p0 b") != -1)
1447: return false;
1448: if (sl.indexOf("p0box") != -1)
1449: return false;
1450: if (sl.indexOf("p0#") != -1)
1451: return false;
1452: if (sl.indexOf("p0 #") != -1)
1453: return false;
1454: return true;
1455: }
1456:
1457: public static boolean isValidUpc(String upc) {
1458: if (upc == null || upc.length() != 12) {
1459: throw new IllegalArgumentException(
1460: "Invalid UPC length; must be 12 characters");
1461: }
1462:
1463: char csum = upc.charAt(11);
1464: char calcSum = calcUpcChecksum(upc);
1465: return csum == calcSum;
1466: }
1467:
1468: public static char calcUpcChecksum(String upc) {
1469: if (upc != null && upc.length() == 12) {
1470: upc = upc.substring(0, 11);
1471: }
1472: if (upc == null || upc.length() != 11) {
1473: throw new IllegalArgumentException(
1474: "Illegal size of UPC; must be 11 characters");
1475: }
1476: int oddsum = 0;
1477: int evensum = 0;
1478: for (int i = upc.length() - 1; i >= 0; i--) {
1479: if ((upc.length() - i) % 2 == 0) {
1480: evensum += Character.digit(upc.charAt(i), 10);
1481: } else {
1482: oddsum += Character.digit(upc.charAt(i), 10);
1483: }
1484: }
1485: int check = 10 - ((evensum + 3 * oddsum) % 10);
1486: if (check >= 10)
1487: check = 0;
1488: return Character.forDigit(check, 10);
1489: }
1490: }
|