EncodingControl.java

  1. package com.gh.mygreen.xlsmapper.localization;

  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.io.InputStreamReader;
  5. import java.nio.charset.Charset;
  6. import java.security.AccessController;
  7. import java.security.PrivilegedActionException;
  8. import java.security.PrivilegedExceptionAction;
  9. import java.util.Locale;
  10. import java.util.PropertyResourceBundle;
  11. import java.util.ResourceBundle;

  12. import org.slf4j.Logger;
  13. import org.slf4j.LoggerFactory;

  14. /**
  15.  * {@link ResourceBundle}を任意の文字コードで読み込むためのコントローラ。
  16.  *
  17.  * @since 2.0
  18.  * @author T.TSUCHIE
  19.  *
  20.  */
  21. public class EncodingControl extends ResourceBundle.Control {
  22.    
  23.     private static final Logger logger = LoggerFactory.getLogger(EncodingControl.class);
  24.    
  25.     private static final String SUPPORT_FORMAT = "java.properties";
  26.    
  27.     private final Charset encoding;
  28.    
  29.     /**
  30.      * 文字コードUTF-8で設定する
  31.      */
  32.     public EncodingControl() {
  33.         this("UTF-8");
  34.     }
  35.    
  36.     public EncodingControl(final String encoding) {
  37.         this(Charset.forName(encoding));
  38.     }
  39.    
  40.     public EncodingControl(final Charset encoding) {
  41.         this.encoding = encoding;
  42.     }
  43.    
  44.     @Override
  45.     public ResourceBundle newBundle(final String baseName, final Locale locale, final String format,
  46.             final ClassLoader loader, final boolean reload)
  47.             throws IllegalAccessException, InstantiationException, IOException {

  48.         if(format.equals(SUPPORT_FORMAT)) {
  49.             final String bundleName = toBundleName(baseName, locale);
  50.             final String resourceName = toResourceName(bundleName, "properties");
  51.            
  52.             try (InputStream stream = getResourceStream(loader, resourceName)) {
  53.                 try (InputStreamReader isr = new InputStreamReader(stream, encoding)) {
  54.                     return new PropertyResourceBundle(isr);
  55.                 }
  56.             } catch (PrivilegedActionException e) {
  57.                 throw(IOException) e.getException();
  58.             }
  59.         } else {
  60.             // 「java.class」はサポートしない。
  61.             // プロパティファイル(java.properties)のみサポートする。
  62.             logger.trace("Not support format. baseName={}, format={}, reload={}.", baseName, format, reload);
  63.             return null;
  64.         }

  65.     }
  66.    
  67.     private InputStream getResourceStream(final ClassLoader loader, final String resourceName) throws PrivilegedActionException {
  68.        
  69.         return AccessController.doPrivileged(new PrivilegedExceptionAction<InputStream>() {
  70.            
  71.             @Override
  72.             public InputStream run() throws IOException {
  73.                 // realod=trueのときもキャッシュを使用せずに新しく読み込む。
  74.                 return loader.getResourceAsStream(resourceName);
  75.             }
  76.         });
  77.     }
  78.    
  79.     /**
  80.      * 設定されている文字コードを取得します。
  81.      * @return リソースファイルの文字コード。
  82.      */
  83.     public Charset getEncoding() {
  84.         return encoding;
  85.     }

  86. }