View Javadoc

1   /**
2    * This file Copyright (c) 2013 Magnolia International
3    * Ltd.  (http://www.magnolia-cms.com). All rights reserved.
4    *
5    *
6    * This file is dual-licensed under both the Magnolia
7    * Network Agreement and the GNU General Public License.
8    * You may elect to use one or the other of these licenses.
9    *
10   * This file is distributed in the hope that it will be
11   * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
12   * implied warranty of MERCHANTABILITY or FITNESS FOR A
13   * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
14   * Redistribution, except as permitted by whichever of the GPL
15   * or MNA you select, is prohibited.
16   *
17   * 1. For the GPL license (GPL), you can redistribute and/or
18   * modify this file under the terms of the GNU General
19   * Public License, Version 3, as published by the Free Software
20   * Foundation.  You should have received a copy of the GNU
21   * General Public License, Version 3 along with this program;
22   * if not, write to the Free Software Foundation, Inc., 51
23   * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24   *
25   * 2. For the Magnolia Network Agreement (MNA), this file
26   * and the accompanying materials are made available under the
27   * terms of the MNA which accompanies this distribution, and
28   * is available at http://www.magnolia-cms.com/mna.html
29   *
30   * Any modifications to this file must keep this entire header
31   * intact.
32   *
33   */
34  package info.magnolia.i18nsystem.util;
35  
36  import java.util.Locale;
37  
38  import org.apache.commons.lang.StringUtils;
39  
40  /**
41   * Utility methods to work with {@link java.util.Locale} objects.
42   */
43  public class LocaleUtils {
44      /**
45       * @return a Locale object matching the properties file name passed as input. The method is quite lenient and accepts file names with underscores (_) even if they're not used
46       * to separate the <code>language_country_variant</code> triad commonly found at the end of i18n messages file names.
47       * <p>
48       * I.e. given a filename like the following <code>messages_foo_bar_de_CH</code> it will correctly resolve into a Locale whose language is <code>de</code> and whose country code is <code>CH</code>. If the filename contains no Locale information at the expected position, the method will return {@literal fallback}.
49       * <p>
50       * The method is also forgiving when it comes to a lowercase country code and won't throw any exception.
51       */
52      public static Locale parseFromFilename(String filename, Locale fallback) {
53          filename = StringUtils.substringBeforeLast(filename, ".");
54          final String[] parts = filename.split("_");
55  
56          Locale locale = null;
57  
58          // can't use LocaleUtils.toLocale() here as it will throw a runtime exception if the country code is lowercase.
59          switch (parts.length) {
60          case 1:
61              locale = fallback;
62              break;
63          case 2:
64              locale = new Locale(parts[1]);
65              if (!isValidLocale(locale)) {
66                  locale = fallback;
67              }
68              break;
69          case 3:
70              locale = new Locale(parts[1], parts[2]);
71              if (!isValidLocale(locale)) {
72                  locale = new Locale(parts[2]);
73              }
74              if (!isValidLocale(locale)) {
75                  locale = fallback;
76              }
77              break;
78          default: // 4 or more
79              locale = new Locale(parts[parts.length - 2], parts[parts.length - 1]);
80              if (!isValidLocale(locale)) {
81                  locale = new Locale(parts[parts.length - 1]);
82              }
83              if (!isValidLocale(locale)) {
84                  // the last item is probably a variant. To test if this is a valid Locale we must skip the variant part
85                  locale = new Locale(parts[parts.length - 3], parts[parts.length - 2]);
86              } else {
87                  break;
88              }
89              if (isValidLocale(locale)) {
90                  // re-add the variant
91                  locale = new Locale(parts[parts.length - 3], parts[parts.length - 2], parts[parts.length - 1]);
92              } else {
93                  locale = fallback;
94              }
95          }
96          return locale;
97      }
98  
99      public static boolean isValidLocale(Locale locale) {
100         return org.apache.commons.lang.LocaleUtils.availableLocaleSet().contains(locale);
101     }
102 }