Java properties ファイル関連ロジックのメモ

package xxxx.service;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * プロパティファイルを管理するクラス。
 * 
 * プロパティファイル読み込み
 * 自動的にリロード
 * 複数のプロパティファイルを読み込み
 * プロパティの中身をキャッシュ
 */
public class CacheProperties{

	/** CachePropertiesをキャッシュするオブジェクト */
	private static Map __cache = new HashMap();

	/** ログ */
	private static Log __log = LogFactory.getLog(CacheProperties.class);

	/** プロパティ */
	private Properties _prop = new Properties();

	/** プロパティファイル */
	private File _propFile;

	/** プロパティファイルの最終更新日時 */
	private long _lastModified;

	public CacheProperties(){
	}

	/**
	 * コンストラクタ。
	 * 
	 * @param file プロパティファイル
	 */
	public CacheProperties(File file){

		_propFile = file;
	}

	/**
	 * インスタンスの取得。
	 * 
	 * @param fileName プロパティファイル名
	 * @return CachePropertiesインスタンス
	 * @throws Exception 
	 */
	public static CacheProperties getInstance(String fileName)
			throws Exception {

		URL url;

		//url = ClassLoader.getSystemResource(fileName);
		url = CacheProperties.class.getClassLoader().getResource(fileName);

		if (url == null) {
			FileNotFoundException e = new FileNotFoundException(fileName);
			__log.error("ファイルが見つかりません。", e);
			throw new Exception("error.no.file");
		}

		return getInstance(new File(url.getPath()));
	}

	/**
	 * インスタンスの取得。
	 * 
	 * @param file プロパティファイル
	 * @return CachePropertiesインスタンス
	 * @throws Exception
	 */
	public static synchronized CacheProperties getInstance(File file)
			throws Exception {

		CacheProperties cacheProperties =
				(CacheProperties) __cache.get(file.getAbsolutePath());

		if (cacheProperties == null) {
			cacheProperties = new CacheProperties(file);

			cacheProperties.load();

			__cache.put(file.getAbsolutePath(), cacheProperties);
		}
		else {
			if (cacheProperties.isUpdate()) {
				cacheProperties.load();
			}
		}

		return cacheProperties;
	}

	/**
	 * プロパティファイルからデータを読み込む。
	 * 
	 * @throws Exception 
	 */
	private void load() throws Exception {

		InputStream in = null;

		try {
			in = new BufferedInputStream(new FileInputStream(_propFile));
			_prop.load(in);

			setLastModified(_propFile.lastModified());
		}
		catch (IOException e) {
			__log.error("システムエラーが発生しました。", e);
			throw new Exception("error.system.err");
		}
		finally {
			in.close();
		}
	}

	/**
	 * プロパティ値の取得。
	 * 
	 * @param key キー
	 * @return プロパティ値
	 * @throws Exception 
	 */
	public String getProperty(String key) throws Exception {

		return getProperty(key, "");
	}

	/**
	 * プロパティ値の取得。
	 * 
	 * @param key キー
	 * @param defaultValue デフォルト値
	 * @return プロパティ値
	 * @throws Exception
	 */
	public synchronized String getProperty(String key, String defaultValue)
			throws Exception {

		String value;

		if (isUpdate()) {
			load();
		}

		value = _prop.getProperty(key, defaultValue);

		return value;
	}

	/**
	 * プロパティ値の取得。
	 * 
	 * @param key キー
	 * @return プロパティ値(int)
	 * @throws Exception
	 */
	public int getPropertyAsInt(String key) throws Exception {

		return getPropertyAsInt(key, 0);
	}

	/**
	 * プロパティ値の取得。
	 * 
	 * @param key キー
	 * @param defaultValue デフォルト値
	 * @return プロパティ値(int)
	 * @throws Exception 
	 */
	public int getPropertyAsInt(String key, int defaultValue)
			throws Exception {

		String value;
		try {
			value = getProperty(key);
		}
		catch (Exception e) {
			throw e;
		}
		return value.equals("") ? defaultValue : Integer.parseInt(value);
	}

	/**
	 * プロパティ値の取得。
	 * 
	 * @param key キー
	 * @return プロパティ値(long)
	 * @throws Exception
	 */
	public long getPropertyAsLong(String key) throws Exception {

		return getPropertyAsInt(key, 0);
	}

	/**
	 * プロパティ値の取得。
	 * 
	 * @param key キー
	 * @param defaultValue デフォルト値
	 * @return プロパティ値(long)
	 * @throws Exception 
	 */
	public long getPropertyAsLong(String key, long defaultValue)
			throws Exception {

		String value;
		try {
			value = getProperty(key);
		}
		catch (Exception e) {
			throw e;
		}

		return value.equals("") ? defaultValue : Long.parseLong(value);
	}

	/** プロパティ値の取得。
	 * 
	 * @param key キー
	 * @return プロパティ値(byte)
	 * @throws Exception
	 */
	public byte getPropertyAsByte(String key) throws Exception {

		byte b = 0;
		return getPropertyAsByte(key, b);
	}

	/**
	 * プロパティ値の取得。
	 * 
	 * @param key キー
	 * @param defaultValue デフォルト値
	 * @return プロパティ値(byte)
	 * @throws Exception 
	 */
	public byte getPropertyAsByte(String key, byte defaultValue)
			throws Exception {

		String value;
		try {
			value = getProperty(key);
		}
		catch (Exception e) {
			throw e;
		}

		return value.equals("") ? defaultValue : Byte.parseByte(value);
	}

	/**
	 * プロパティ値の取得。
	 * 
	 * @param key キー
	 * @return プロパティ値(boolean)
	 * @throws Exception
	 */
	public boolean getPropertyAsBoolean(String key) throws Exception {

		return getPropertyAsBoolean(key, false);
	}

	/**
	 * プロパティ値の取得。
	 * 
	 * @param key キー
	 * @param defaultValue デフォルト値
	 * @return プロパティ値(boolean)
	 * @throws Exception 
	 */
	public boolean getPropertyAsBoolean(String key, boolean defaultValue)
			throws Exception {

		String value;
		try {
			value = getProperty(key);
		}
		catch (Exception e) {
			throw e;
		}

		return value.equals("") ? defaultValue : Boolean.valueOf(value)
				.booleanValue();
	}

	/**
	 * プロパティファイルが更新されているかどうかを判定する。
	 * 
	 * @return ファイルが更新されていればtrue, それ以外はfalse
	 */
	private synchronized boolean isUpdate() {

		boolean ret;

		if (_lastModified != _propFile.lastModified()) {
			ret = true;
		}
		else {
			ret = false;
		}

		return ret;
	}

	/**
	 * 最終更新日時のセット。
	 * 
	 * @param lastModified
	 */
	private synchronized void setLastModified(long lastModified) {

		_lastModified = lastModified;
	}

	/**
	 * 単体テスト用
	 * 
	 * @param args
	 */
	public static void main(String[] args) throws Exception {

		CacheProperties props;
		String val = "";

		props = CacheProperties.getInstance("autoex.xml");
		val = props.getProperty("rmi.autoex.bindname");
		System.out.println(val);
	}
}