package jp.sf.amateras.functions.utils;

import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 国際化されたメッセージを取得するためのユーティリティクラスです。
 *
 * @author Naoki Takezoe
 */
public class TextUtils {

	private static String bundleName = "messages";

	private static ResourceBundle defaultBundle = null;

	private static Map<Locale, ResourceBundle> bundleMap = new ConcurrentHashMap<Locale, ResourceBundle>();

	/**
	 * 使用するResourceBundleのバンドル名を設定します。
	 * デフォルトではmessagesというバンドル名が使用されます。
	 *
	 * @param bundleName バンドル名
	 */
	public static void setBundleName(String bundleName){
		TextUtils.bundleName = bundleName;
	}

	/**
	 * 国際化されたメッセージを取得します。
	 * <p>
	 * 引数で指定したロケールに対応するResourceBundleが存在しない場合や、
	 * 対応するResourceBundleに指定したキーを持つメッセージが存在しない場合は
	 * また、デフォルトのResourceBundleで定義されたメッセージが返却されます。
	 * キーに対応するエントリが存在しない場合はキーの文字列をそのまま返却します。
	 * </p>
	 * <p>
	 * デフォルトのResourceBundleが存在しない場合はMissingResourceExceptionがスローされます。
	 * </p>
	 *
	 * @param key メッセージのキー
	 * @param locale ロケール
	 * @return キーに対応するメッセージ
	 * @throw MissingResourceException デフォルトのResourceBundleが存在しない場合
	 */
	public static String getText(String key, Locale locale) throws MissingResourceException {
		if(defaultBundle == null){
			defaultBundle = ResourceBundle.getBundle(bundleName, new Locale(""));
		}

		ResourceBundle bundle = bundleMap.get(locale);
		if(bundle == null){
			bundle = ResourceBundle.getBundle(bundleName, locale);
			if(bundle.getLocale().getCountry().equals(locale.getCountry()) ||
					bundle.getLocale().getLanguage().equals(locale.getLanguage())){
				bundleMap.put(locale, bundle);
			} else {
				bundle = defaultBundle;
			}
		}

		String text = "";
		try {
			text = bundle.getString(key);
		} catch(MissingResourceException ex){
			text = key;
		}
		return text;
	}

}
