XML読込みを整理してみる。ResourceBundle使用の恩恵があるはず。
/**
* XML 解析インターフェース.
*
* AbstractXmlHandler の createParser メソッドで、XMLファイル baseName と
* AbstractXmlHandler 継承したインスタンスを生成して作成される。
*
* XmlParser xmlparser = AbstractXmlHandler.createParser(baseName,handler);
*/
public interface XmlParser<T>{
/**
* AbstractXmlHandler継承インスタンスが AbstractXmlHandler抽象メソッドである
* public abstract T result() throws Exception;
* が返す任意のオブジェクトを返す。
*
* @return T AbstractXmlHandler継承インスタンスが返す任意オブジェクト
*/
public T parse() throws Exception;
}
--------------------------------------
import org.xml.sax.helpers.DefaultHandler;
/**
* XML解析ハンドラ抽象クラス.
* 実装クラスで、org.xml.sax.helpers.DefaultHandler のメソッドをオーバライドして
* XML解析の結果を result() で、返すように実装すること。
*/
public abstract class AbstractXmlHandler<T> extends DefaultHandler{
public abstract T result() throws Exception;
/**
* XmlParser インスタンス生成.
* 3つの引数を持つ同じメソッド、createParser の3番目に、
* ResourceBundle.Control.TTL_DONT_CACHE を与えて実行するのと同じ効果があります。
* @param <T> result()が返す任意オブジェクトタイプ
* @param baseName XMLファイル ".xml" を除いた名称
* @param handler AbstractXmlHandler継承インスタンス
* @return XmlParserインスタンス
*/
public final static <T> XmlParser createParser(String baseName,AbstractXmlHandler<T> handler){
return new XmlParserImpl<T>(baseName,handler);
}
/**
* XmlParser インスタンス生成(XML読込キャッシュ制御).
* ResourceBundle.Control の下でロードされたリソースバンドルの有効期間 (TTL) 値を指定する
* ことを可能にしたインスタンス生成です。
* 第3引数に、
* ResourceBundle.Control.TTL_DONT_CACHE :キャッシュをしない
* ResourceBundle.TTL_NO_EXPIRATION_CONTROL :有効期限なしのキャッシュをする。
* あるいは、値 0 は、ResourceBundle.Control#getTimeToLive の戻り値=0と同じ意味を持ち、
* キャッシュ有効期限をミリ秒で与えます。
* @param <T> result()が返す任意オブジェクトタイプ
* @param baseName XMLファイル ".xml" を除いた名称
* @param handler AbstractXmlHandler継承インスタンス
* @param cacheTime ResourceBundle.Control の下でロードされたリソースバンドルの有効期間 (TTL) 値、ミリ秒
* @return XmlParserインスタンス
*/
public final static <T> XmlParser createParser(String baseName,AbstractXmlHandler<T> handler,long cacheTime){
return new XmlParserImpl<T>(baseName,handler,cacheTime);
}
}
--------------------------------------
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.ResourceBundle;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
/**
* XmlParser 実装クラス.
* 解析対象 XMLファイル baseName と、AbstractXmlHandler インスタンスをコンストラクタで受け取る。
*/
final class XmlParserImpl<T> implements XmlParser{
private String baseName;
AbstractXmlHandler<T> handler;
long cacheTime;
protected XmlParserImpl(String baseName,AbstractXmlHandler<T> handler){
this.baseName = baseName;
this.handler = handler;
this.cacheTime = ResourceBundle.Control.TTL_DONT_CACHE;
}
protected XmlParserImpl(String baseName,AbstractXmlHandler<T> handler,long cacheTime){
this.baseName = baseName;
this.handler = handler;
this.cacheTime = cacheTime;
}
@Override
public T parse() throws Exception{
ResourceBundle.getBundle(this.baseName
,new ResourceBundle.Control(){
@Override
public List<String> getFormats(String _baseName){
if (_baseName==null) throw new NullPointerException();
return Arrays.asList("xml");
}
@Override
public ResourceBundle newBundle(String _baseName,Locale locale,String format,ClassLoader loader,@SuppressWarnings("unused") boolean reload)
throws IllegalAccessException,InstantiationException,IOException{
if (_baseName == null || locale == null || format == null || loader == null)
throw new NullPointerException();
if (format.equals("xml")){
String bundleName = toBundleName(_baseName, locale);
String resourceName = toResourceName(bundleName,format);
InputStream stream = loader.getResourceAsStream(resourceName);
if (stream != null){
_XMLparse xmlParse = new _XMLparse(stream);
try{
xmlParse.parse();
}catch(Exception e){
throw new IOException(e);
}
stream.close();
}
}
return new _DummyBundle();
}
@Override
public long getTimeToLive(String _baseName,Locale _locale){
if (_baseName==null || _locale==null){
throw new NullPointerException();
}
return XmlParserImpl.this.cacheTime;
}
}
);
return this.handler.result();
}
class _XMLparse {
private InputStream steam;
_XMLparse(InputStream stream){
this.steam = stream;
}
void parse() throws Exception{
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
saxParser.parse(this.steam,XmlParserImpl.this.handler);
}
}
class _DummyBundle extends ResourceBundle {
private Properties props;
_DummyBundle(){
this.props = new Properties();
}
@Override
protected Object handleGetObject(String key) {
return this.props.getProperty(key);
}
@Override
public Enumeration<String> getKeys() {
return null;
}
}
}