/*
 * LogMessageFactory.java
 * Copyright (C) 2008 Cyber Beans Corporation. All rights reserved.
 */
package jp.co.cybec.cb3.util.logging;

import java.text.MessageFormat;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import jp.co.cybec.cb3.exception.MessageResourceException;

/**
 * メッセージIDをキーにしてメッセージを取得するためのクラスです。
 * @author Naoko Sugimoto
 */
public class LogMessageFactory {

	/** リソースバンドル */
	private ResourceBundle bundle = null;
	/** プロパティファイル名 */
	private String propertyFileName = null;

	/**
	 * コンストラクタ。
	 *
	 * @param propertyFileName プロパティファイル名
	 * @throws MessageResourceException メッセージプロパティファイルがクラスパス上に見つからない場合。
	 */
	public LogMessageFactory(String propertyFileName) throws MessageResourceException {
		try {
			bundle = ResourceBundle.getBundle(propertyFileName);
		} catch (MissingResourceException e) {
			throw new MessageResourceException("[" + propertyFileName + ".properties]がクラスパス上に見つかりません。", e);
		}
		this.propertyFileName = propertyFileName;
	}

	/**
	 * メッセージIDを指定してメッセージを取得します。
	 *
	 * @param messageId メッセージID
	 * @return メッセージ
	 */
	public String getMessage(String messageId) {
		try {
			//"MessageID:[XXXX] メッセージ内容。"
			StringBuilder message = new StringBuilder();
			message.append(getMessageIdentifier());
			message.append("MessageID:[");
			message.append(messageId);
			message.append("] ");
			message.append(bundle.getString(messageId));
			return message.toString();
		} catch (MissingResourceException e) {
			return "メッセージID[" + messageId + "]が[" + propertyFileName + ".properties]上に見つかりません。";
		}
	}

	/**
	 * メッセージIDを指定してメッセージを取得します。
	 *
	 * @param messageId メッセージID
	 * @param args 置換文字列
	 * @return メッセージ
	 */
	public String getMessage(String messageId, Object... args) {
		try {
			//"MessageID:[XXXX] メッセージ内容。"
			StringBuilder message = new StringBuilder();
			message.append(getMessageIdentifier());
			message.append("MessageID:[");
			message.append(messageId);
			message.append("] ");
			message.append(bundle.getString(messageId));
			return MessageFormat.format(message.toString(), args);
		} catch (MissingResourceException e) {

			//"メッセージID[XXXX]が[xxxx.properties]上に見つかりません。メッセージ引数：[xx, xxx, ...]"
			StringBuilder message = new StringBuilder();
			message.append("メッセージID[");
			message.append(messageId);
			message.append("]が[");
			message.append(propertyFileName);
			message.append(".properties]上に見つかりません。メッセージ引数：[");
			for (Object arg: args) {
				message.append(arg);
				message.append(", ");
			}
			// 末尾の「,」を削除。
			if (message.lastIndexOf(", ") == message.length() - 2) {
				message.delete(message.length() - 2, message.length());
			}
			message.append("]");
			return message.toString();
		}
	}

	/**
	 * エラーコードとメッセージIDを指定してメッセージを取得します。
	 *
	 * @param errorCode エラーコード
	 * @param messageId メッセージID
	 * @return メッセージ
	 */
	public String getErrorMessage(String errorCode, String messageId) {
		try {
			//"ErrorCode:[XXXX] MessageID:[XXXX] メッセージ内容。"
			StringBuilder message = new StringBuilder();
			message.append(getMessageIdentifier());
			message.append("ErrorCode:[");
			message.append(errorCode);
			message.append("] ");
			message.append("MessageID:[");
			message.append(messageId);
			message.append("] ");
			message.append(bundle.getString(messageId));
			return message.toString();
		} catch (MissingResourceException e) {
			return "メッセージID[" + messageId + "]が[" + propertyFileName + ".properties]上に見つかりません。";
		}
	}

	/**
	 * エラーコードとメッセージIDを指定してメッセージを取得します。
	 *
	 * @param errorCode エラーコード
	 * @param messageId メッセージID
	 * @param args 置換文字列
	 * @return メッセージ
	 */
	public String getErrorMessage(String errorCode, String messageId, Object... args) {
		try {
			//"ErrorCode:[XXXX] MessageID:[XXXX] メッセージ内容。"
			StringBuilder message = new StringBuilder();
			message.append(getMessageIdentifier());
			message.append("ErrorCode:[");
			message.append(errorCode);
			message.append("] ");
			message.append("MessageID:[");
			message.append(messageId);
			message.append("] ");
			message.append(bundle.getString(messageId));
			return MessageFormat.format(message.toString(), args);
		} catch (MissingResourceException e) {

			//"メッセージID[XXXX]が[xxxx.properties]上に見つかりません。メッセージ引数：[xx, xxx, ...]"
			StringBuilder message = new StringBuilder();
			message.append("メッセージID[");
			message.append(messageId);
			message.append("]が[");
			message.append(propertyFileName);
			message.append(".properties]上に見つかりません。メッセージ引数：[");
			for (Object arg: args) {
				message.append(arg);
				message.append(", ");
			}
			// 末尾の「,」を削除。
			if (message.lastIndexOf(", ") == message.length() - 2) {
				message.delete(message.length() - 2, message.length());
			}
			message.append("]");
			return message.toString();
		}
	}

	/**
	 * メッセージ識別子を取得します。<br>
	 * パッケージにより下記のように出力形式が変わります。
	 * <pre>
	 * Coreパッケージでの出力形式："JobProcessID:[XXXX] ServiceID:[XXXX] "
	 * Advancedパッケージでの出力形式："JobProcessID:[XXXX] JobID:[XXXX] TaskID:[XXXX] ServiceID:[XXXX] "
	 * </pre>
	 *
	 * @return メッセージ識別子
	 * @see LogMessageIdentifier
	 */
	private String getMessageIdentifier() {
		StringBuilder message = new StringBuilder();
		if (LogMessageIdentifier.getJobProcessId() != null) {
			message.append("JobProcessID:[");
			message.append(LogMessageIdentifier.getJobProcessId());
			message.append("] ");
		}
		if (LogMessageIdentifier.getJobId() != null) {
			message.append("JobID:[");
			message.append(LogMessageIdentifier.getJobId());
			message.append("] ");
		}
		if (LogMessageIdentifier.getTaskId() != null) {
			message.append("TaskID:[");
			message.append(LogMessageIdentifier.getTaskId());
			message.append("] ");
		}
		if (LogMessageIdentifier.getServiceId() != null) {
			message.append("ServiceID:[");
			message.append(LogMessageIdentifier.getServiceId());
			message.append("] ");
		}
		return message.toString();
	}

}
