Search code examples
jsfjsf-2myfaces

JSF 2.2: Configure available Locales outside faces-config.xml


Currently i have a section in my faces-config.xml such as follows:

    <locale-config>
        <default-locale>en</default-locale>
        <supported-locale>en_US</supported-locale>
        <supported-locale>en_GB</supported-locale>
        <supported-locale>de</supported-locale>
        <supported-locale>de_DE</supported-locale>
    </locale-config>

This is working as intended.

The problem is, i have to be able to define these Locales whithout touching the faces-config.xml in my war. The idea is having e.g. a config File on the resource Path defining all the available Locales.

I already tried an programatic approach as well as using a second faces-config.xml in the META-INF of another module i have access to and defining an specific file on the ressource path which should be merged according to this article. The second file in each case contained the above section in a valid faces-config.xml format. Both without any effect (neither errors nor any change in the behaviour)

Is there any nice way to do this without touching the original faces-config?

I am able to change the ear module and to access ressources programatically in any location. Unfortunately adjusting the faces-config.xml in the .war is no option.


Solution

  • There is a misconception here as far as I can see. There is no need to configure anything in the locale-config if you use custom resolvers/resource bundles/whatever and have otherwise full control over things.

    If you look at the answer in Add Resource Bundles Programmatically, you see the OmniFaces Faces.getLocale() is used to pass a locale to the resourceBundle

    Locale userLocale = Faces.getLocale();
    ResourceBundle b = ResourceBundle.getBundle("msgs", userLocale);
    

    So what is effectively done is pass a programmatically chosen locale to it, not automagically using something that is configured in the locale-config.

    The fact the IN Faces.getLocale() some code is present to use the locale-config is to make sure it can be used when people have something configured in locale-config, so it behaves as expected in plain normal JSF. In line 16 it retreives the locale send in the request by the user. In line 18 it checks this against the supported-locale (can be left out in a custom implementation!!!) and if no match, use the default-locale (can be left out to, as can line 7-12)

    1   /**
    2     * {@inheritDoc}
    3     * @see Faces#getLocale()
    4     */
    5   public static Locale getLocale(FacesContext context) {
    6       Locale locale = null;
    7       UIViewRoot viewRoot = context.getViewRoot();
    8
    9       // Prefer the locale set in the view.
    10      if (viewRoot != null) {
    11          locale = viewRoot.getLocale();
    12      }
    13
    14      // Then the client preferred locale.
    15      if (locale == null) {
    16          Locale clientLocale = context.getExternalContext().getRequestLocale();
    17
    18          if (getSupportedLocales(context).contains(clientLocale)) {
    19              locale = clientLocale;
    20          }
    21      }
    22
    23      // Then the JSF default locale.
    24      if (locale == null) {
    25          locale = context.getApplication().getDefaultLocale();
    26      }
    27
    28      // Finally the system default locale.
    29      if (locale == null) {
    30          locale = Locale.getDefault();
    31      }
    32
    33      return locale;
    34  }
    

    So this code can be totally tweaked to your liking, including first checking if the user has configured a locale of preference in your application and otherwise using the locale send by the browser IF supported.