/* ====================================================================
* The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
*
* Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by Jcorporate Ltd.
* (http://www.jcorporate.com/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. "Jcorporate" and product names such as "Expresso" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written permission,
* please contact info@jcorporate.com.
*
* 5. Products derived from this software may not be called "Expresso",
* or other Jcorporate product names; nor may "Expresso" or other
* Jcorporate product names appear in their name, without prior
* written permission of Jcorporate Ltd.
*
* 6. No product derived from this software may compete in the same
* market space, i.e. framework, without prior written permission
* of Jcorporate Ltd. For written permission, please contact
* partners@jcorporate.com.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Jcorporate Ltd. Contributions back
* to the project(s) are encouraged when you make modifications.
* Please send them to support@jcorporate.com. For more information
* on Jcorporate Ltd. and its products, please see
* <http://www.jcorporate.com/>.
*
* Portions of this software are based upon other open source
* products and are subject to their respective licenses.
*/
package com.jcorporate.expresso.ext.dbobj;
import com.jcorporate.expresso.core.db.DBConnection;
import com.jcorporate.expresso.core.db.DBException;
import com.jcorporate.expresso.core.dbobj.DBField;
import com.jcorporate.expresso.core.dbobj.RequestContext;
import com.jcorporate.expresso.core.dbobj.SecuredDBObject;
import com.jcorporate.expresso.core.misc.StringUtil;
import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.PatternCompiler;
import org.apache.oro.text.regex.PatternMatcher;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;
import org.apache.oro.util.Cache;
import org.apache.oro.util.CacheLRU;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.Vector;
/**
* This database table contains a list of all known ISO 3166-1 country codes.
* See www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/index.html
* for the source of this data.
* <p/>
* This is highly useful for registration data. Allow a person to choose from a
* dropdown box. Also can check postal code against known regular expressions
* depending on the iso country code associated with the registration.
*
* @author Michael Rimov
* @since Expresso 5.0
*/
public class ISOCountryCodes extends SecuredDBObject {
public static final String FLD_ISOCODE = "ISOCode";
public static final String FLD_COUNTRY = "Country";
public static final String FLD_POSTALREGEXP = "PostalRegExp";
public static final String TABLE = "ISOCOUNTRYCODES";
/**
* Used to hold compiled regular expressions in an attempt to speed
* up pattern matching.
*/
protected static Cache regExpCache = new CacheLRU();
/**
* Used for regular expression compilation
*/
protected static PatternCompiler compiler = new Perl5Compiler();
/**
* Used to match compiled patterns against strings
*/
protected static PatternMatcher matcher = new Perl5Matcher();
/**
* Constructor
*/
public ISOCountryCodes()
throws DBException {
super();
} /* User() */
/**
* Constructor
*
* @param myConnection The DBConnection to use Locally
*/
public ISOCountryCodes(DBConnection myConnection)
throws DBException {
super(myConnection);
} /* User(String) */
/**
* Use over (String) constructor. Initializes the object in the context
* of the user who's uid belongs to the parameter.
*
* @param uid the Uid of the user context
* @throws DBException if there's an initialization problem
*/
public ISOCountryCodes(int uid)
throws DBException {
super(uid);
}
/**
* For using DBObjects within Controllers. Initializes based upon the current
* user and the requested db. [Of course this can be modified later]
*
* @param request - The controller request handed to you by the framework.
* @throws DBException if there's an initialization problem
*/
public ISOCountryCodes(RequestContext request)
throws DBException {
super(request);
}
/**
* This function populates the table with the current listing of ISO country codes
*
* @throws DBException if an error occurs while populating the table.
* @see com.jcorporate.expresso.core.dbobj.DBObject#populateDefaultValues
*/
public synchronized void populateDefaultValues()
throws DBException {
int i;
String[][] localCodes = getCountryCodes();
int len = localCodes.length;
for (i = 0; i < len; i++) {
this.clear();
this.setField(FLD_ISOCODE, localCodes[i][1]);
if (!this.find()) {
setField(FLD_COUNTRY, localCodes[i][0]);
this.add();
}
}
} /* populateDefaultValues() */
/**
* Useful method for unit testing to make sure that everything got added during
* setup as expected.
*
* @return the length of what's expected to be in the table
*/
public int getExpectedDefaultPopulation() {
String[][] countryCodes = getCountryCodes();
return countryCodes.length;
}
/**
* @return Vector of ValidValue Value/Description pairs for ISO Country Codes
* @throws DBException If the values cannot be retrieved
*/
public Vector getValues()
throws DBException {
return getValuesDefault(FLD_ISOCODE, FLD_COUNTRY);
} /* getValues() */
/**
* Checks a postal code for proper formatting The iso country definition
* should already have been retrieved.
*
* @param testPostalCode the postalCode to check
* @return true if the postal code existed for this country
* @throws DBException if the test code didn't match the regular expression
* stored in the database OR if the regular expression in the database
* is syntactically invalid
*/
public boolean checkPostalCode(String testPostalCode)
throws DBException {
String regExp = StringUtil.notNull(this.getField(FLD_POSTALREGEXP));
if (regExp.length() == 0) {
return false;
}
Pattern compiledRegExp = getPattern(regExp);
synchronized (matcher) {
if (!matcher.matches(testPostalCode, compiledRegExp)) {
throw new DBException("You've entered an invalid postal code");
}
}
return true;
}
/**
* Get's the regular expression patter to match against.
*
* @param postalCodePattern the postalCode pattern to check
* @return ORO Compiled Regular Expression Pattern
* @throws DBException if the mattern match is bad.
*/
private synchronized Pattern getPattern(String postalCodePattern)
throws DBException {
Pattern p = (Pattern) regExpCache.getElement(postalCodePattern);
if (p == null) {
try {
p = compiler.compile(postalCodePattern, Perl5Compiler.READ_ONLY_MASK);
regExpCache.addElement(postalCodePattern, p);
} catch (MalformedPatternException mpe) {
throw new DBException(this.getClass().getName() +
"getPattern(String)", mpe);
}
}
return p;
}
/**
* @throws DBException
*/
protected void setupFields()
throws DBException {
setTargetTable(TABLE);
setDescription("ISO Country Codes");
setCharset("ISO-8859-1");
addField(FLD_ISOCODE, DBField.VARCHAR_TYPE, 10, false, "ISO Country Code");
addField(FLD_COUNTRY, DBField.VARCHAR_TYPE, 128, false, "Country Name");
addField(FLD_POSTALREGEXP, DBField.VARCHAR_TYPE, 128, true,
"Postal Code Valid Regular Expression");
setStringFilter(FLD_ISOCODE, "stripFilter");
setStringFilter(FLD_COUNTRY, "rawFilter");
addKey(FLD_ISOCODE);
setReadOnly(FLD_ISOCODE);
addIndex("CountryNames", FLD_COUNTRY, true);
} /* setupFields() */
protected synchronized static String[][] getCountryCodes() {
synchronized (countryCodeLock) {
if (countryCodes == null || countryCodes.get() == null) {
countryCodes = new WeakReference(new String[][]{
{"United States", "US", ""}, {"Afghanistan", "AF", ""}, {"Aland Islands", "AX", ""},
{"Albania", "AL", ""}, {"Algeria", "DZ", ""},
{"American Samoa", "AS", ""}, {"Andorra", "AD", ""},
{"Angola", "AO", ""}, {"Anguilla", "AI", ""}, {"Antarctica", "AQ", ""},
{"Antigua And Barbuda", "AG", ""}, {"Argentina", "AR", ""},
{"Armenia", "AM", ""}, {"Aruba", "AW", ""}, {"Australia", "AU", ""},
{"Austria", "AT", ""}, {"Azerbaijan", "AZ", ""}, {"Bahamas", "BS", ""},
{"Bahrain", "BH", ""}, {"Bangladesh", "BD", ""},
{"Barbados", "BB", ""}, {"Belarus", "BY", ""}, {"Belgium", "BE", ""},
{"Belize", "BZ", ""}, {"Benin", "BJ", ""}, {"Bermuda", "BM", ""},
{"Bhutan", "BT", ""}, {"Bolivia", "BO", ""},
{"Bosnia And Herzegovina", "BA", ""}, {"Botswana", "BW", ""},
{"Bouvet Island", "BV", ""}, {"Brazil", "BR", ""},
{"British Indian Ocean Territory", "IO", ""},
{"Brunei Darussalam", "BN", ""}, {"Bulgaria", "BG", ""},
{"Burkina Faso", "BF", ""}, {"Burundi", "BI", ""},
{"Cambodia", "KH", ""}, {"Cameroon", "CM", ""}, {"Canada", "CA", ""},
{"Cape Verde", "CV", ""}, {"Cayman Islands", "KY", ""},
{"Central African Republic", "CF", ""}, {"Chad", "TD", ""},
{"Chile", "CL", ""}, {"China", "CN", ""},
{"Christmas Island", "CX", ""}, {"Cocos (Keeling) Islands", "CC", ""},
{"Colombia", "CO", ""}, {"Comoros", "KM", ""}, {"Congo", "CG", ""},
{"Congo, The Democratic Republic Of The", "CD", ""},
{"Cook Islands", "CK", ""}, {"Costa Rica", "CR", ""},
{"Cote D'Ivoire", "CI", ""}, {"Croatia", "HR", ""}, {"Cuba", "CU", ""},
{"Cyprus", "CY", ""}, {"Czech Republic", "CZ", ""},
{"Denmark", "DK", ""}, {"Djibouti", "DJ", ""}, {"Dominica", "DM", ""},
{"Dominican Republic", "DO", ""},
{"Ecuador", "EC", ""}, {"Egypt", "EG", ""}, {"El Salvador", "SV", ""},
{"Equatorial Guinea", "GQ", ""}, {"Eritrea", "ER", ""},
{"Estonia", "EE", ""}, {"Ethiopia", "ET", ""},
{"Falkland Islands", "FK", ""}, {"Faroe Islands", "FO", ""},
{"Fiji", "FJ", ""}, {"Finland", "FI", ""}, {"France", "FR", ""},
{"French Guiana", "GF", ""}, {"French Polynesia", "PF", ""},
{"French Southern Territories", "TF", ""}, {"Gabon", "GA", ""},
{"Gambia", "GM", ""}, {"Georgia", "GE", ""}, {"Germany", "DE", ""},
{"Ghana", "GH", ""}, {"Gibraltar", "GI", ""}, {"Greece", "GR", ""},
{"Greenland", "GL", ""}, {"Grenada", "GD", ""},
{"Guadeloupe", "GP", ""}, {"Guam", "GU", ""}, {"Guatemala", "GT", ""},
{"Guinea", "GN", ""}, {"Guinea-bissau", "GW", ""},
{"Guyana", "GY", ""}, {"Haiti", "HT", ""},
{"Heard Island And Mcdonald Islands", "HM", ""},
{"Holy See (Vatican City State)", "VA", ""}, {"Honduras", "HN", ""},
{"Hong Kong", "HK", ""}, {"Hungary", "HU", ""}, {"Iceland", "IS", ""},
{"India", "IN", ""}, {"Indonesia", "ID", ""}, {"Iran", "IR", ""},
{"Iraq", "IQ", ""}, {"Ireland", "IE", ""}, {"Israel", "IL", ""},
{"Italy", "IT", ""}, {"Jamaica", "JM", ""}, {"Japan", "JP", ""},
{"Jordan", "JO", ""}, {"Kazakhstan", "KZ", ""}, {"Kenya", "KE", ""},
{"Kiribati", "KI", ""}, {"North Korea", "KP", ""},
{"South Korea", "KR", ""}, {"Kuwait", "KW", ""},
{"Kyrgyzstan", "KG", ""},
{"Lao People's Democratic Republic", "LA", ""}, {"Latvia", "LV", ""},
{"Lebanon", "LB", ""}, {"Lesotho", "LS", ""}, {"Liberia", "LR", ""},
{"Libyan Arab Jamahiriya", "LY", ""}, {"Liechtenstein", "LI", ""},
{"Lithuania", "LT", ""}, {"Luxembourg", "LU", ""}, {"Macao", "MO", ""},
{"Macedonia", "MK", ""}, {"Madagascar", "MG", ""},
{"Malawi", "MW", ""}, {"Malaysia", "MY", ""}, {"Maldives", "MV", ""},
{"Mali", "ML", ""}, {"Malta", "MT", ""},
{"Marshall Islands", "MH", ""}, {"Martinique", "MQ", ""},
{"Mauritania", "MR", ""}, {"Mauritius", "MU", ""},
{"Mayotte", "YT", ""}, {"Mexico", "MX", ""}, {"Micronesia", "FM", ""},
{"Moldova", "MD", ""}, {"Monaco", "MC", ""}, {"Mongolia", "MN", ""},
{"Montserrat", "MS", ""}, {"Morocco", "MA", ""},
{"Mozambique", "MZ", ""}, {"Myanmar", "MM", ""}, {"Namibia", "NA", ""},
{"Nauru", "NR", ""}, {"Nepal", "NP", ""}, {"Netherlands", "NL", ""},
{"Netherlands Antilles", "AN", ""}, {"New Caledonia", "NC", ""},
{"New Zealand", "NZ", ""}, {"Nicaragua", "NI", ""},
{"Niger", "NE", ""}, {"Nigeria", "NG", ""}, {"Niue", "NU", ""},
{"Norfolk Island", "NF", ""}, {"Northern Mariana Islands", "MP", ""},
{"Norway", "NO", ""}, {"Oman", "OM", ""}, {"Pakistan", "PK", ""},
{"Palau", "PW", ""}, {"Palestinian Territory", "PS", ""},
{"Panama", "PA", ""}, {"Papua New Guinea", "PG", ""},
{"Paraguay", "PY", ""}, {"Peru", "PE", ""}, {"Philippines", "PH", ""},
{"Pitcairn", "PN", ""}, {"Poland", "PL", ""}, {"Portugal", "PT", ""},
{"Puerto Rico", "PR", ""}, {"Qatar", "QA", ""}, {"Reunion", "RE", ""},
{"Romania", "RO", ""}, {"Russian Federation", "RU", ""},
{"Rwanda", "RW", ""}, {"Saint Helena", "SH", ""},
{"Saint Kitts And Nevis", "KN", ""}, {"Saint Lucia", "LC", ""},
{"Saint Pierre And Miquelon", "PM", ""},
{"Saint Vincent And The Grenadines", "VC", ""}, {"Samoa", "WS", ""},
{"San Marino", "SM", ""}, {"Sao Tome And Principe", "ST", ""},
{"Saudi Arabia", "SA", ""}, {"Senegal", "SN", ""}, {"Serbia And Montenegro", "CS", ""},
{"Seychelles", "SC", ""}, {"Sierra Leone", "SL", ""},
{"Singapore", "SG", ""}, {"Slovakia", "SK", ""},
{"Slovenia", "SI", ""}, {"Solomon Islands", "SB", ""},
{"Somalia", "SO", ""}, {"South Africa", "ZA", ""},
{"South Georgia And The South Sandwich Islands", "GS", ""},
{"Spain", "ES", ""}, {"Sri Lanka", "LK", ""}, {"Sudan", "SD", ""},
{"Suriname", "SR", ""}, {"Svalbard And Jan Mayen", "SJ", ""},
{"Swaziland", "SZ", ""}, {"Sweden", "SE", ""},
{"Switzerland", "CH", ""}, {"Syrian Arab Republic", "SY", ""},
{"Taiwan", "TW", ""}, {"Tajikistan", "TJ", ""},
{"Tanzania", "TZ", ""}, {"Thailand", "TH", ""}, {"Timor-Leste", "TL", ""},
{"Togo", "TG", ""}, {"Tokelau", "TK", ""}, {"Tonga", "TO", ""},
{"Trinidad And Tobago", "TT", ""}, {"Tunisia", "TN", ""},
{"Turkey", "TR", ""}, {"Turkmenistan", "TM", ""},
{"Turks And Caicos Islands", "TC", ""}, {"Tuvalu", "TV", ""},
{"Uganda", "UG", ""}, {"Ukraine", "UA", ""},
{"United Arab Emirates", "AE", ""}, {"United Kingdom", "GB", ""},
{"United States Minor Outlying Islands", "UM", ""},
{"Uruguay", "UY", ""}, {"Uzbekistan", "UZ", ""}, {"Vanuatu", "VU", ""},
{"Venezuela", "VE", ""}, {"Viet Nam", "VN", ""},
{"Virgin Islands, British", "VG", ""},
{"Virgin Islands, U.S.", "VI", ""}, {"Wallis And Futuna", "WF", ""},
{"Western Sahara", "EH", ""}, {"Yemen", "YE", ""},
{"Zambia", "ZM", ""}, {"Zimbabwe", "ZW", ""}
});
}
return (String[][]) countryCodes.get();
}
}
protected static Reference countryCodes = null;
protected static Object countryCodeLock = new Object();
}
|