There is 246 countries in ISO 3166, you might get a relay big enum on back of this. I prefer to use XML file with list of countries, you can download one from http://www.iso.org/ and load them (e.g. when app is starting).
Than, as you need them in GWT load them in back as RPC call, but remember to cache those (some kind of lazy loading) so you wont finish with loading them each time.
I think this would be anyway better than holding them in code, as you will finish with loading full list each time module is accessed, even if user will not need to use this list.
So you need something which will hold country:
public class Country
{
private final String name;
private final String code;
public Country(String name, String code)
{
this.name = name;
this.code = code;
}
public String getName()
{
return name;
}
public String getCode()
{
return code;
}
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null || getClass() != obj.getClass())
{
return false;
}
Country country = (Country) obj;
return code.equals(country.code);
}
public int hashCode()
{
return code.hashCode();
}
}
For GWT this class would need to implement IsSerializable.
And you can load those, on server side using:
import java.util.ArrayList;
import java.util.List;
import java.io.InputStream;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class CountriesService
{
private static final String EL_COUNTRY = "ISO_3166-1_Entry";
private static final String EL_COUNTRY_NAME = "ISO_3166-1_Country_name";
private static final String EL_COUNTRY_CODE = "ISO_3166-1_Alpha-2_Code_element";
private List<Country> countries = new ArrayList<Country>();
public CountriesService(InputStream countriesList)
{
parseCountriesList(countriesList);
}
public List<Country> getCountries()
{
return countries;
}
private void parseCountriesList(InputStream countriesList)
{
countries.clear();
try
{
Document document = parse(countriesList);
Element root = document.getRootElement();
//noinspection unchecked
Iterator<Element> i = root.elementIterator(EL_COUNTRY);
while (i.hasNext())
{
Element countryElement = i.next();
Element countryName = countryElement.element(EL_COUNTRY_NAME);
Element countryCode = countryElement.element(EL_COUNTRY_CODE);
String countryname = countryName.getText();
countries.add(new Country(countryname, countryCode.getText()));
}
}
catch (DocumentException e)
{
log.error(e, "Cannot read countries list");
}
catch (IOException e)
{
log.error(e, "Cannot read countries list");
}
}
public static Document parse(InputStream inputStream) throws DocumentException
{
SAXReader reader = new SAXReader();
return reader.read(inputStream);
}
}
Of course, if you need to find country by ISO 2 letter code you might wont to change List to Map probably.
If, as you mentioned, you need separate countries by continent, you might extend XML from ISO 3166 and add your own elements. Just check their (ISO website) license.