/******************************************************************************* * Gisgraphy Project * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA * * Copyright 2008 Gisgraphy project * David Masclet <davidmasclet@gisgraphy.com> * * *******************************************************************************/ package com.gisgraphy.domain.geoloc.entity; import java.io.Serializable; import java.util.ArrayList; import java.util.Currency; import java.util.List; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.ManyToMany; import javax.persistence.Transient; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; import org.hibernate.annotations.Index; /** * A Country (as defined by ISO 3166). A country always has an ISO 3166 alpha-2, * alpha-3 and numeric code, but may, or may not have other names (FIPS, etc). * The list of countries has been imported from Geonames Country List. Codes are * written in upper case ! * * @see <a * href="http://www.iso.org/iso/en/prods-services/popstds/countrynamecodes.html">Country * Name Codes</a> * @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a> */ @Entity @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) public class Country extends GisFeature implements Serializable, Comparable<Country> { /** * Constructor that populate the {@link Country} with the gisFeature fields<br> * * @param gisFeature * The gisFeature from which we want to populate the * {@linkplain Country} */ public Country(GisFeature gisFeature) { super(gisFeature); } /** * Default constructor (Needed by CGLib) */ public Country() { super(); } /** * Construct a country with the iso 3166 alpha-2 code, iso 3166 alpha-3 code, and * iso 3166 numeric code * * @param iso3166Alpha2Code * The iso 3166 alpha 2 code for this Country * @param iso3166Alpha3Code * The iso 3166 alpha3 code for this Country * @param iso3166NumericCode * The iso 3166 numeric code for this Country <u>NOTE</u> : The * iso3166AlphaX codes will be automatically uppercased */ public Country(String iso3166Alpha2Code, String iso3166Alpha3Code, int iso3166NumericCode) { super(); this.setIso3166Alpha2Code(iso3166Alpha2Code); this.setIso3166Alpha3Code(iso3166Alpha3Code); this.setIso3166NumericCode(iso3166NumericCode); } private static final long serialVersionUID = 1L; private Double area; private String tld; private String capitalName; private String continent; private String postalCodeRegex; /** * @see #getCurrencyCode() * @see #getCurrency() */ private String currencyCode; private String currencyName; /** * @see #getEquivalentFipsCode() */ private String equivalentFipsCode; /** * @see #getFipsCode() */ private String fipsCode; /** * @see #getIso3166Alpha2Code() */ private String iso3166Alpha2Code; /** * @see #getIso3166Alpha3Code() */ private String iso3166Alpha3Code; /** * @see #getIso3166NumericCode() */ private int iso3166NumericCode; // TODO v3 // private List<Country> neighbourCountries = new ArrayList<Country>(); /** * @see #getPhonePrefix() */ private String phonePrefix; /** * @see #getPostalCodeMask() */ private String postalCodeMask; /** * The spoken languages */ private List<Language> spokenLanguages = new ArrayList<Language>(); /* * public void addNeighbourCountry(Country c) { * this.neighbourCountries.add(c); } */ /** * Add a spoken language to the country. The language is described by its * Alpha2 Code. * * @param lang */ public void addSpokenLanguage(Language lang) { this.spokenLanguages.add(lang); } /* * (non-Javadoc) * * @see com.gisgraphy.domain.geoloc.entity.GisFeature#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (!super.equals(obj)) { return false; } if (getClass() != obj.getClass()) { return false; } final Country other = (Country) obj; if (iso3166Alpha2Code == null) { if (other.iso3166Alpha2Code != null) { return false; } } else if (!iso3166Alpha2Code.equals(other.iso3166Alpha2Code)) { return false; } return true; } /** * Country area in square Km * * @return The country area in square Km */ public Double getArea() { return this.area; } /** * Returns the ISO 4217 Currency from the currency code. The code is not * imported but processed : * {@link Currency#getInstance(java.util.Locale)} Important : some * currencies are NOT recognized by * {@link Currency#getInstance(java.util.Locale)}. * * @return The ISO 4217 Currency or null if the currencyCode is null or * incorrect */ @Transient public Currency getCurrency() { Currency currency = null; if (this.currencyCode != null) { try { currency = Currency.getInstance(this.currencyCode); } catch (RuntimeException e) { logger.warn("Got a wrong currencycode" + getCountryCode()); } } return currency; } /** * ISO 4217 currency code when possible. However, for some countries, there * is no official ISO 4217 code, like Guernsey (GGP), and the information * can be null sometimes when we're not sure of the currency (United States * Minor Outlying Islands). This field is not unique, because some countries * have the same currency. (Euro for instance..) * * @see <a * href="http://www.iso.org/iso/en/prods-services/popstds/currencycodeslist.html"> * ISO 4217 Currency names </a> * @see <a href="http://en.wikipedia.org/wiki/Guernsey_pound">Guernsey Pound</a> * @see <a * href="http://en.wikipedia.org/wiki/United_States_Minor_Outlying_Islands"> * United States Minor Outlying Islands</a> * @return The ISO 4217 currency code */ @Column(unique = false, nullable = true) public String getCurrencyCode() { return this.currencyCode; } /** * This field is not supported yet. The equivalent fips Code. This is * the same as the FIPS code, except that sometimes, there is no FIPS code * for some entity (Aaland Islands), even if it is the same country than * another one (finland). So in that case, Aaland island equivalent fips * code will be set to FI * * @return The equivalent fips Code */ public String getEquivalentFipsCode() { return this.equivalentFipsCode; } /** * The FIPS 10.4 country code. This field can be null in some cases * (when there is an ISO Code and no FIPS code, for instance). Note that * these code is not the same as the ISO 3166 codes used by the U.N. and * for Internet top-level country code domains. * * @see <a href="http://en.wikipedia.org/wiki/List_of_FIPS_country_codes"> * List Of FIPS Country Codes </a> * @return Returns the fipsCode. */ @Column(unique = true, nullable = true) @Index(name = "countryFipsCode") public String getFipsCode() { return this.fipsCode; } /** * The ISO 3166 alpha-2 letter code(should be in upper case). We don't use the country code of the * GisFeature because we want that fields as mandatory and the GisFeature * one is not * * @see <a href="http://en.wikipedia.org/wiki/ISO_3166"> ISO 3166 </a> * @return Returns the iso3166Alpha2Code. */ @Column(unique = true, nullable = false) @Index(name = "countryIso3166Alpha2CodeIndex") public String getIso3166Alpha2Code() { return this.iso3166Alpha2Code; } /** * The ISO 3166 alpha-3 letter code (should be in upper case) * * @see <a href="http://en.wikipedia.org/wiki/ISO_3166"> ISO 3166 </a> */ @Column(unique = true, nullable = false) @Index(name = "countryIso3166Alpha3CodeIndex") public String getIso3166Alpha3Code() { return this.iso3166Alpha3Code; } /** * @return The ISO 3166 numeric code */ @Column(unique = true, nullable = false) @Index(name = "countryIso3166NumericCodeIndex") public int getIso3166NumericCode() { return this.iso3166NumericCode; } /* * Neighbour Countries @return @ManyToMany public List<Country> * getNeighbourCountries() { return this.neighbourCountries; } */ /** * The Phone Prefix (e.g : 33..) without '+' * * @return The phone prefix */ public String getPhonePrefix() { return this.phonePrefix; } /** * @return The postal Code Mask (ex : #####) */ public String getPostalCodeMask() { return this.postalCodeMask; } /** * All language spoken in this Country. * * @see Language * @return the {@link Language} spoken in this Country */ @ManyToMany @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) public List<Language> getSpokenLanguages() { return this.spokenLanguages; } /* * (non-Javadoc) * * @see com.gisgraphy.domain.geoloc.entity.GisFeature#hashCode() */ @Override public int hashCode() { final int PRIME = 31; int result = super.hashCode(); result = PRIME * result + ((iso3166Alpha2Code == null) ? 0 : iso3166Alpha2Code .hashCode()); return result; } /** * @see #getArea() * @param area */ public void setArea(Double area) { this.area = area; } /** * Set the currency code for this country * * @see #getCurrencyCode() * @param currencyCode * The currencyCode to set */ public void setCurrencyCode(String currencyCode) { this.currencyCode = currencyCode; } /** * @see #getEquivalentFipsCode() * @param equivalentFipsCode */ public void setEquivalentFipsCode(String equivalentFipsCode) { this.equivalentFipsCode = equivalentFipsCode; } /** * @see #getFipsCode() * @param fipsCode * The fipsCode to set. */ public void setFipsCode(String fipsCode) { this.fipsCode = fipsCode; } /** * Set the iso3166 alpha-2 code. <u>NOTE</u> : The Code will be automaticaly uppercased, and * the gisfeature code will be set automatically * * @see #getIso3166Alpha2Code() * @param isoCode * The iso3166 alpha-2 code to set in upper case. */ public void setIso3166Alpha2Code(String isoCode) { if (isoCode != null) { this.iso3166Alpha2Code = isoCode.toUpperCase(); } else { this.iso3166Alpha2Code = isoCode; } setCountryCode(isoCode); } /** * <u>Note</u> : The code will be automaticaly uppercased * * @see #getIso3166Alpha3Code() * @param iso3166Alpha3Code * The iso3166Alpha3Code to set (in upper case). */ public void setIso3166Alpha3Code(String iso3166Alpha3Code) { // check if we can apply touppercase method if (iso3166Alpha3Code != null) { this.iso3166Alpha3Code = iso3166Alpha3Code.toUpperCase(); } else { this.iso3166Alpha3Code = iso3166Alpha3Code; } } /** * @see #getIso3166NumericCode() * @param iso3166NumericCode * The iso 3166 numeric code to set. */ public void setIso3166NumericCode(int iso3166NumericCode) { this.iso3166NumericCode = iso3166NumericCode; } /* * /** * * @see #getNeighbourCountries() @param neighbourCountries public void * setNeighbourCountries(List<Country> neighbourCountries) { * this.neighbourCountries = neighbourCountries; } */ /** * @see #getPhonePrefix() * @param phonePrefix */ public void setPhonePrefix(String phonePrefix) { this.phonePrefix = phonePrefix; } /** * @see #getPostalCodeMask() * @param postalCodeMask */ public void setPostalCodeMask(String postalCodeMask) { this.postalCodeMask = postalCodeMask; } /** * @see #getSpokenLanguages() * @param languages */ public void setSpokenLanguages(List<Language> languages) { this.spokenLanguages = languages; } /** * @see #getSpokenLanguages() * @param languages */ public void addSpokenLanguages(List<Language> languages) { this.spokenLanguages.addAll(languages); } /** * Get the capital for this country * * @return the Capital for this country */ public String getCapitalName() { return capitalName; } /** * @see #getCapitalName() */ public void setCapitalName(String capitalName) { this.capitalName = capitalName; } /** * Returns The name of the continent this country belongs to * * @return The name of the continent this country belongs to */ public String getContinent() { return continent; } /** * @see #getContinent() */ public void setContinent(String continent) { this.continent = continent; } /** * Returns The name of the currency for this country. The name is not * processed but imported from file. * * @return The name of the currency */ public String getCurrencyName() { return currencyName; } /** * @see #getCurrencyName() */ public void setCurrencyName(String currencyName) { this.currencyName = currencyName; } /** * Returns The regexp that every Zipcode for this country matches. it is * useful to test if a zipcode is valid. this field is imported from file * and is not tested. Please report any problems. * * @see #getPostalCodeMask() * @return The regexp that every zipcode for this country matches */ public String getPostalCodeRegex() { return postalCodeRegex; } /** * @see #getPostalCodeRegex() */ public void setPostalCodeRegex(String postalCodeRegex) { this.postalCodeRegex = postalCodeRegex; } /** * Returns the top level domain for this country with the starting point. * (ex : .fr) * * @see <a href="http://en.wikipedia.org/wiki/Top-level_domain">TLD</a> * @return the TLD for this Country */ public String getTld() { return tld; } /** * @see #getTld() */ public void setTld(String tld) { this.tld = tld; } /** * compare the name of the country */ public int compareTo(Country country) { if (getName() == null) { if (country.getName() == null) { return 0; } else { return -1; } } return getName().compareTo(country.getName()); } }