java、AntのXmlProperty形式のxmlファイルを読む

Properties.loadFromXMLで読もうとしたら失敗した。フォーマット違うのね。
方法としては、antを使う方法とCommons configurationを使う方法がある。

AntのXmlPropertyを使う方法

以下のコードはant 1.6.5で確認。
ファイルシステム上にプロパティのxmlがあることが前提。InputStreamから読もうとするとけっこうめんどくさそう。

final String propertyFilePath="/path/to/property/settings.properties.xml";

final File propertyFile=new File(propertyFilePath);
if(!propertyFile.exists()) {
	// XmlPropertyは指定されたファイルが存在しないときでも正常終了する……
	throw "ファイルがないよ";
}

final XmlProperty prop = new XmlProperty();
try {
	prop.setProject(new Project());
	prop.init();
	prop.setFile(configFile);
	prop.setKeeproot(false); // その他設定はお好みで
	prop.execute();
} catch (BuildException e) {
	throw "なんかエラー";
}

final Project project=prop.getProject();

// これが目的の値。replacePropertiesは${property}みたいな文字列を展開するメソッド
final String value = project.replaceProperties(project.getProperty("property.of.something"));

Commons configurationを使う方法

こっちのほうが柔軟性があって便利。
Commons configuration 1.6で確認

final XMLConfiguration config;
try {
	config=new XMLConfiguration(textCoreConfigPath);
} catch(ConfigurationException e) {
	throw "失敗したよ";
}

// getString(String name)はキーが見つからない際の挙動が決まってないらしいのでデフォルト値を指定したほうが安全っぽい
// http://commons.apache.org/configuration/apidocs/org/apache/commons/configuration/Configuration.html
// "The behavior of the methods that do not take a default value in case of a missing property is not defined
//  by this interface and depends on a concrete implementation."
String value=config.getString("property.of.something",null);

${property.reference}みたいなのも展開してくれるようです。

注意:上記のやり方だと"hoge,hage"というプロパティ値をgetStringで取得しようとしても"hoge"しかかえってきません。
デフォルトではカンマを使用して複数の値を記述できる設定になってるため。
この挙動を変更するには初期化処理を以下のようにする。

final XMLConfiguration config;
try {
	config=new XMLConfiguration();
	config.setDelimiterParsingDisabled(true); //デリミタ無効。このメソッドは設定ファイルのロード前に呼ぶこと
	config.load(textCoreConfigPath);
} catch(ConfigurationException e) {
	throw "失敗したよ";
}