正方形の周長 #17
JDK1.6よりも前であれば面倒だったけれど、
1.6で導入されたResourceBundle.Controlクラスにより簡単に書くことができるようになった。
ResourceBundle.ControlクラスのAPI仕様にあるXMLベースのリソース取り込みのサンプルとあまり変わりない。
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.IOException; import java.net.URL; import java.net.URLConnection; import java.nio.charset.Charset; import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.PropertyResourceBundle; import java.util.ResourceBundle; public class PropertiesControl extends ResourceBundle.Control { private static final Charset UTF8 = Charset.forName("UTF-8"); private Charset charset; public PropertiesControl() { this(UTF8); } public PropertiesControl(String charsetName) { this(Charset.forName(charsetName)); } public PropertiesControl(Charset charset) { this.charset = charset; } private static final String FORMAT = "properties"; private static final List<String> FORMATS = Arrays.asList(FORMAT); @Override public List<String> getFormats(String baseName) { if (baseName == null) throw new NullPointerException(); return FORMATS; } @Override public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) throws IOException { if (baseName == null || locale == null || format == null || loader == null) throw new NullPointerException(); ResourceBundle bundle = null; if (format.equals(FORMAT)) { String bundleName = toBundleName(baseName, locale); String resourceName = toResourceName(bundleName, format); InputStream stream = null; if (reload) { URL url = loader.getResource(resourceName); if (url != null) { URLConnection connection = url.openConnection(); if (connection != null) { connection.setUseCaches(false); stream = connection.getInputStream(); } } } else { stream = loader.getResourceAsStream(resourceName); } if (stream != null) { try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream, charset))) { bundle = new PropertyResourceBundle(reader); } } } return bundle; } }
オーバーライドしたgetFormatsメソッドが返すListから分かるように、
プロパティファイルベースの取り込みにのみ対応しており、クラスベースのものは無視する。
newBundleメソッド内、PropertyResourceBundleでプロパティファイルを取り込む時に、
InputStreamでなく文字エンコードを指定したReaderを指定するのがポイントである。
ここではコンストラクタで任意のCharsetを指定できるようにはしているが、
UTF-8辺りが妥当なところだろうということで引数なしのときはUTF-8指定にしている。