3 import java
.security
.AccessController
;
4 import java
.util
.ArrayList
;
6 import java
.util
.Locale
;
7 import java
.util
.ResourceBundle
;
9 import javax
.security
.auth
.Subject
;
11 import org
.apache
.commons
.logging
.Log
;
12 import org
.apache
.commons
.logging
.LogFactory
;
13 import org
.argeo
.cms
.auth
.CurrentUser
;
15 /** Utilities simplifying the development of localization enums. */
16 public class LocaleUtils
{
17 final static String DEFAULT_OSGI_l10N_BUNDLE
= "/OSGI-INF/l10n/bundle";
19 private final static Log log
= LogFactory
.getLog(LocaleUtils
.class);
21 private final static ThreadLocal
<Locale
> threadLocale
= new ThreadLocal
<>();
23 public static void setThreadLocale(Locale locale
) {
24 threadLocale
.set(locale
);
27 public static String
local(Localized localized
) {
28 return local(localized
.name(), localized
.getClass().getClassLoader());
31 public static String
local(Localized localized
, Locale locale
) {
32 if (localized
.name() == null) // untranslated
33 return localized
.local(locale
);
34 return local(localized
.name(), locale
, localized
.getClass().getClassLoader());
38 public static String
local(Enum
<?
> en
) {
39 return local(en
, getCurrentLocale(), DEFAULT_OSGI_l10N_BUNDLE
);
43 public static String
local(Enum
<?
> en
, Locale locale
) {
44 return local(en
, locale
, DEFAULT_OSGI_l10N_BUNDLE
);
48 public static String
local(Enum
<?
> en
, Locale locale
, String resource
) {
49 return local(en
, locale
, resource
, en
.getClass().getClassLoader());
53 public static String
local(Enum
<?
> en
, Locale locale
, String resource
, ClassLoader classLoader
) {
54 return local(en
.name(), locale
, resource
, classLoader
);
57 public static String
local(String key
, ClassLoader classLoader
) {
58 return local(key
, getCurrentLocale(), DEFAULT_OSGI_l10N_BUNDLE
, classLoader
);
61 public static String
local(String key
, Locale locale
, ClassLoader classLoader
) {
62 return local(key
, locale
, DEFAULT_OSGI_l10N_BUNDLE
, classLoader
);
65 /** Where the search for a message is actually performed. */
66 public static String
local(String key
, Locale locale
, String resource
, ClassLoader classLoader
) {
67 ResourceBundle rb
= ResourceBundle
.getBundle(resource
, locale
, classLoader
);
68 assert key
.length() > 2;
70 key
= key
.substring(1);
71 if (rb
.containsKey(key
))
72 return rb
.getString(key
);
73 else // for simple cases, the key will actually be the English word
77 public static boolean isLocaleKey(String str
) {
78 if (str
.length() > 2 && ('%' == str
.charAt(0)))
84 /** Lead transformation on the translated string. */
85 public static String
toLead(String raw
, Locale locale
) {
86 return raw
.substring(0, 1).toUpperCase(locale
) + raw
.substring(1);
89 public static String
lead(Localized localized
, ClassLoader classLoader
) {
90 Locale locale
= getCurrentLocale();
91 if (localized
.name() == null)// untranslated
92 return toLead(localized
.local(locale
), locale
);
93 return toLead(local(localized
.name(), getCurrentLocale(), DEFAULT_OSGI_l10N_BUNDLE
, classLoader
), locale
);
96 public static String
lead(Localized localized
) {
97 return lead(localized
, localized
.getL10nClassLoader());
100 public static String
lead(Localized localized
, Locale locale
) {
101 return toLead(local(localized
, locale
), locale
);
104 static Locale
getCurrentLocale() {
105 Locale currentLocale
= null;
106 if (Subject
.getSubject(AccessController
.getContext()) != null)
107 currentLocale
= CurrentUser
.locale();
108 else if (threadLocale
.get() != null) {
109 currentLocale
= threadLocale
.get();
111 if (log
.isTraceEnabled())
112 log
.trace("Thread #" + Thread
.currentThread().getId() + " " + Thread
.currentThread().getName() + " locale: "
114 if (currentLocale
== null)
115 throw new IllegalStateException("No locale found");
116 return currentLocale
;
117 // return UiContext.getLocale();
118 // FIXME look into Subject or settings
119 // return Locale.getDefault();
122 /** Returns null if argument is null. */
123 public static List
<Locale
> asLocaleList(Object locales
) {
126 ArrayList
<Locale
> availableLocales
= new ArrayList
<Locale
>();
127 String
[] codes
= locales
.toString().split(",");
128 for (int i
= 0; i
< codes
.length
; i
++) {
129 String code
= codes
[i
];
130 // variant not supported
131 int indexUnd
= code
.indexOf("_");
134 String language
= code
.substring(0, indexUnd
);
135 String country
= code
.substring(indexUnd
+ 1);
136 locale
= new Locale(language
, country
);
138 locale
= new Locale(code
);
140 availableLocales
.add(locale
);
142 return availableLocales
;