Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ResourceBundle that defaults to English

Setup

Let's say I have 2 strings files:

Strings_en.properties
Strings_fr.properties

Let's say English is the default language, and all the strings are present, while French lags behind and some strings are missing.

Desired behavior

I want to fall back to English in both of these cases:

  • When requesting a completely different locale, such as German.
    • ResourceBundle.getBundle("path/to/Strings", Locale.GERMAN);
  • When requesting a string missing from French.
    • ResourceBundle.getBundle("path/to/Strings", Locale.FRENCH).getString("only.in.english");

The first fallback is simple enough: as per the documentation, it's enough to have English as the default locale, for example by setting Locale.setDefault(Locale.ENGLISH);.

Problem

My problem is with the second fallback. If the string is not found in Strings_fr, the lookup continues to the "parent bundle": getObject() documentation. However, Strings_en is not the parent of Strings_fr and a MissingResourceException is thrown.

Workaround

A simple fix is to rename Strings_en.properties to Strings.properties. This makes it the parent bundle for Strings_fr (and for any other Strings_, for that matter) and looking up missing strings returns the default English versions.

Problem: the system now has a default localization, but it no longer understands that there is an English localization.

Workaround 2

When fetching a string, check if it's present in the bundle - if not, fetch it from the English one instead.

ResourceBundle bundle = ResourceBundle.getBundle("path/to/Strings", Locale.FRENCH);
if (bundle.containsKey(key)) { return bundle.getString(key); }
return ResourceBundle.getBundle("path/to/Strings", DEFAULT_WHICH_IS_ENGLISH).getString(key);

Problem: this is just a hack, I believe there is an "intended" way to do it.

Question

Is there a simple way to make Strings_en the parent of Strings_fr? If not, is it reasonable to for example hardlink Strings_en to Strings, so that I can keep English as an explicit localization and at the same time as the default one?

like image 794
vektor Avatar asked Mar 15 '16 12:03

vektor


2 Answers

You can rename Strings_en.properties to Strings.properties (making English the default localization) and add a new empty Strings_en.properties.

Then

ResourceBundle.getBundle("path/to/Strings", Locale.ENGLISH).getLocale()

also returns Locale.ENGLISH.

like image 114
wero Avatar answered Sep 20 '22 23:09

wero


Old thread, another solution: You can use ResourceBundle.Control and getCandidateLocales to add custom language candidates (file suffix)

ResourceBundle.getBundle(baseName, locale, new ResourceBundle.Control() {
    @Override
    public List<Locale> getCandidateLocales(String baseName, Locale locale) {
      List<Locale> list = super.getCandidateLocales(baseName, locale);
      list.add(new Locale("en"));
      return list;
    }
  }
like image 29
Marcin Gum Avatar answered Sep 19 '22 23:09

Marcin Gum