tags:

views:

100

answers:

4

I read a file in an application that specifies a language code:

public void setResources(String locale) {

    // validate locale
    // ULocale lo = new ULocale(locale);
    // System.out.println(lo.getDisplayCountry());

}

that must be in the format: <ISO 639 language code>_<ISO 3166 region code> eg. en_UK, en_US etc. Is it possible to validate that the locale string is valid before continuing?

+4  A: 

You can get the available locales like so and enumerate them to see if the locale is valid

boolean isValidLocale(String value) {
  Locale []locales = Locale.getAvailableLocales();
  for (Locale l : locales) {
    if (value.equals(l.toString()) {
      return true;
    }
  }
  return false;
}
locka
This is very inperformant because of the large number of available locales!
Arne Burmeister
You only need to do it once and put it into a set
Rich
You could introduce a sorted list with the most used locales, which is checked first and adds new locals if confirmed, this should reduce the checks of the whole available locales!
codedevour
+1. If the resources are part of the actual application itself (and not integrated into the system from an external source or interface), I'd integrate the above code snippet into a unit test of sorts that checks all the resources filenames with the list found in `Locale.getAvailableLocales()`.
Cthulhu
A: 

You could check if the String is contained in the Arrays returned by the getISOCountries() or getISOLanguages() methods of Locale. Its kinda crude but may actually work. You could also extract all available Locales with getAvailableLocales() and search them for display names.

kostja
+1  A: 

I do not know ULocale, but if you mean java.util.Locale, the following code may do:

public void setResources(String locale) {
  // validate locale
  Locale lo = parseLocale(locale);
  if (isValid(lo) {
    System.out.println(lo.getDisplayCountry());
  } else {
    System.out.println("invalid: " + locale);
  }
}

private Locale parseLocale(String locale) {
  String[] parts = locale.split("_");
  switch (parts.length) {
    case 3: return new Locale(parts[0], parts[1], parts[2]);
    case 2: return new Locale(parts[0], parts[1]);
    case 1: return new Locale(parts[0]);
    default: throw new IllegalArgumentException("Invalid locale: " + locale);
  }
}

private boolean isValid(Locale locale) {
  try {
    return locale.getISO3Language() != null && locale.getISO3Country() != null;
  } catch (MissingResourceException e) {
    return false;
  }
}

EDIT: added validation

Arne Burmeister
I think ULocale is referring to [this](http://icu-project.org/apiref/icu4j/com/ibm/icu/util/ULocale.Type.html).
Matt Ball
A: 

Now I just do:

ULocale uLocale = new ULocale(locale);
if (uLocale.getCountry() != null && !uLocale.getCountry().isEmpty()) {
  ...
}

which works fine.

tul