|
23 | 23 | import static org.apache.commons.lang3.Validate.notNull; |
24 | 24 |
|
25 | 25 | import java.io.IOException; |
| 26 | +import java.io.InputStream; |
| 27 | +import java.io.InputStreamReader; |
| 28 | +import java.nio.charset.Charset; |
| 29 | +import java.nio.charset.StandardCharsets; |
26 | 30 | import java.text.MessageFormat; |
27 | 31 | import java.util.ArrayList; |
28 | 32 | import java.util.Enumeration; |
29 | 33 | import java.util.List; |
30 | 34 | import java.util.Locale; |
| 35 | +import java.util.PropertyResourceBundle; |
31 | 36 | import java.util.ResourceBundle; |
32 | 37 | import java.util.regex.Matcher; |
33 | 38 | import java.util.regex.Pattern; |
@@ -158,7 +163,7 @@ public Object apply(final String key, final Options options) throws IOException |
158 | 163 | String baseName = options.hash("bundle", defaultBundle); |
159 | 164 | ClassLoader classLoader = options.hash("classLoader", getClass().getClassLoader()); |
160 | 165 | I18nSource localSource = source == null |
161 | | - ? new DefI18nSource(baseName, locale, classLoader) : source; |
| 166 | + ? new DefI18nSource(charset, baseName, locale, classLoader) : source; |
162 | 167 |
|
163 | 168 | return localSource.message(key, locale, options.params); |
164 | 169 | } |
@@ -232,7 +237,7 @@ public Object apply(final String localeName, final Options options) throws IOExc |
232 | 237 | String baseName = options.hash("bundle", defaultBundle); |
233 | 238 | ClassLoader classLoader = options.hash("classLoader", getClass().getClassLoader()); |
234 | 239 | I18nSource localSource = source == null |
235 | | - ? new DefI18nSource(baseName, locale, classLoader) : source; |
| 240 | + ? new DefI18nSource(charset, baseName, locale, classLoader) : source; |
236 | 241 | StringBuilder buffer = new StringBuilder(); |
237 | 242 | Boolean wrap = options.hash("wrap", true); |
238 | 243 | if (wrap) { |
@@ -292,6 +297,20 @@ private String message(final String message) { |
292 | 297 | /** The message source to use. */ |
293 | 298 | protected I18nSource source; |
294 | 299 |
|
| 300 | + /** Charset. **/ |
| 301 | + protected Charset charset = StandardCharsets.UTF_8; |
| 302 | + |
| 303 | + /** |
| 304 | + * Set the charset to use. |
| 305 | + * |
| 306 | + * NotThreadSafe Make sure to call this method ONCE at start time. |
| 307 | + * |
| 308 | + * @param charset Charset. Required. |
| 309 | + */ |
| 310 | + public void setCharset(final Charset charset) { |
| 311 | + this.charset = notNull(charset, "Charset required."); |
| 312 | + } |
| 313 | + |
295 | 314 | /** |
296 | 315 | * Set the message source. |
297 | 316 | * |
@@ -332,18 +351,60 @@ public void setDefaultLocale(final Locale locale) { |
332 | 351 | /** Default implementation of I18nSource. */ |
333 | 352 | class DefI18nSource implements I18nSource { |
334 | 353 |
|
| 354 | + /** |
| 355 | + * UTF8 resource bundle control. |
| 356 | + * |
| 357 | + * Source: Source: ckoverflow.com/questions/4659929 |
| 358 | + * |
| 359 | + * @author edgar |
| 360 | + * |
| 361 | + */ |
| 362 | + public static class UTF8Control extends ResourceBundle.Control { |
| 363 | + /** Charset. */ |
| 364 | + private final Charset charset; |
| 365 | + |
| 366 | + /** |
| 367 | + * Creates a new utf8 control. |
| 368 | + * |
| 369 | + * @param charset Charset. |
| 370 | + */ |
| 371 | + public UTF8Control(final Charset charset) { |
| 372 | + this.charset = charset; |
| 373 | + } |
| 374 | + @Override |
| 375 | + public ResourceBundle newBundle(final String baseName, final Locale locale, final String format, |
| 376 | + final ClassLoader loader, final boolean reload) throws IOException { |
| 377 | + // The below is a copy of the default implementation. |
| 378 | + String bundleName = toBundleName(baseName, locale); |
| 379 | + String resourceName = toResourceName(bundleName, "properties"); |
| 380 | + InputStream stream = null; |
| 381 | + try { |
| 382 | + stream = loader.getResourceAsStream(resourceName); |
| 383 | + PropertyResourceBundle bundle = new PropertyResourceBundle( |
| 384 | + new InputStreamReader(stream, charset)); |
| 385 | + return bundle; |
| 386 | + } finally { |
| 387 | + if (stream != null) { |
| 388 | + stream.close(); |
| 389 | + } |
| 390 | + } |
| 391 | + } |
| 392 | + } |
| 393 | + |
335 | 394 | /** The resource bundle. */ |
336 | 395 | private ResourceBundle bundle; |
337 | 396 |
|
338 | 397 | /** |
339 | 398 | * Creates a new {@link DefI18nSource}. |
340 | 399 | * |
| 400 | + * @param charset Charset to use. |
341 | 401 | * @param baseName The base name. |
342 | 402 | * @param locale The locale. |
343 | 403 | * @param classLoader The classloader. |
344 | 404 | */ |
345 | | - public DefI18nSource(final String baseName, final Locale locale, final ClassLoader classLoader) { |
346 | | - bundle = ResourceBundle.getBundle(baseName, locale, classLoader); |
| 405 | + public DefI18nSource(final Charset charset, final String baseName, final Locale locale, |
| 406 | + final ClassLoader classLoader) { |
| 407 | + bundle = ResourceBundle.getBundle(baseName, locale, classLoader, new UTF8Control(charset)); |
347 | 408 | } |
348 | 409 |
|
349 | 410 | @Override |
|
0 commit comments