Geography
Geography
When you need an internationalized list of countries and their corresponding sub-countries (states/provinces), you can use the com.elasticpath.domain.misc.Geography class.
Key classes and files
- GeographyImpl - For retrieving locale specific list of countries and sub-countries
- Application - The bootstrapping class in cmclient.
- ResourceRetrievalServiceImpl - Service used by the cmclient rcp application to retrieve resources from the server remotely
- PropertiesDaoImpl - Provides loading mechanism of the properties files.
- country.properties - This file lists the ISO 3166-2 country codes and their string values.
- subcountry.XX.properties - This file lists the ISO 3166-2 subregion codes and their string values.XX is the ISO 3166-2 country code for the subregions country.
How the Geography Class works
The Geography class requires that the properties files containing geography information is loaded up into its properties map before use. In the past this was done through the EpContextConfigListener, which reads in *.properties files in WEB-INF/conf/resources folder on application startup. In cmclient, we don't have a WEB-INF folder, so we will need to get the properties transferred over from the remote CM server.
- On startup of the Commerce Manager client application, Application class is loaded up by the framework, and retrieves the ResourceRetrievalService to get the properties from the CM server.
- ResourceRetrievalService uses the PropertiesDao to load all property files into a Map, which will be transfered to the cmclient.
- Application class initializes Geography class with the retrieved properties map.
- Geography class can now be used anywhere in cmclient to retrieve a map of countries with internationalized names.
i.e. geography.getCountries(Application.getInstance().getElasticPath().getDefaultLocale());
Configuration
Properties files are stored under com.elasticpath.core/WEB-INF/conf/resources and copied to CM project at build time. If the properties map is needed elsewhere, it can be retrieved from the Application class Application.getPropertiesMap()
How Country Files Work
Country names and subregions are stored in two country properties files:
- country.properties - stores ISO 3166-2 country codes and the country string values.
- subcountry.XX.properties - stores the subregions of the country defined in the country.properties file. XX is the ISO 3166-2 country code for the for the subregion's parent country.
For example, Canada would be defined as CA=Canada in the country.properties and Canada's subregions would be defined in the country.CA.properties file.
Country and Subregion Formats
country.properties follow this format: XX=COUNTRY. The first two letters XX is the ISO 3166-2 country code and COUNTRY is the value shown in the Storefront and Commerce Manager. Example:
CA=Canada BE=Belgium
subcountry.XX.properties follow this format: XX=SUBREGION. The first two letters XX is the ISO 3166-2 subregion code and SUBREGION is the value shown in the Storefront and Commerce Manager. Example:
AB=Alberta BC=British Columbia
Customizing the Display Order for Countries and Subregions
Countries and subregions are, by default, sorted and displayed alphabetically. You can customize the display order. To customize the Country order, define an index value for the country code. For example, if you wanted Canada to display first and Belgium to display second, you would write the following in country.properties:
1=CA 2=BE CA=Canada BE=Belgium
To customize the subregion order, define and index value for the subregion. For example, if you wanted Yukon to display first and then Saskatchewan to display second, you would write the following in country.CA.properties:
1=YT 2=SK SK=Saskatchewan YT=Yukon
Unexpected results may occur if the countries and subregions are not defined in the proper format.
Notes
- To retrieve sub countries for a given country, you need to pass in the country code.
- Sub Countries are keyed by country code. Here's a helper method to convert a country code from a country's name if you already have the map of countries.
private String getCountryCode(final String country) { String code = ""; if (countryMap \!= null) { Map.Entry<String, String> entry = null; for (final Iterator< ? > itr = countryMap.entrySet().iterator(); itr.hasNext();-) { entry = (Map.Entry) itr.next(); if (entry.getValue().equalsIgnoreCase(country)) { code = entry.getKey(); } } return code; }