/*
このファイルの中身は、NTT オープンソースライセンス　バージョン 1.0（「本
契約」という）の適用を受けます。
本契約を遵守しない限り、このファイルを使用してはなりません。
本契約のコピーは、次のＵＲＬから入手できます。
【配布サイトのURL】 http://www.oss.ecl.ntt.co.jp/lms/

本契約に基づき頒布されるソフトウェアは、現状のまま、明示又は黙示のあらゆ
る種類の保証なしで、頒布されます。本契約に基づく権利及び制限を律する特定
の文言については、本契約を参照してください。

「オリジナルコード」は、 NTT Cyber Space Laboratories Code です。 
「オリジナルコード」の「初期開発者」は、日本電信電話株式会社です。  
日本電信電話株式会社により創作された部分は、Copyright (C) 2004 
日本電信電話株式会社 です。
全ての権利が留保されます。 
「コントリビュータ」：_____________________________________ 


The contents of this file are subject to the NTT Opensource License
Version 1.0 (the License); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
【配布サイトのURL】 http://www.oss.ecl.ntt.co.jp/lms/

Software distributed under the License is distributed on an AS IS
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.

The Original Code is NTT Cyber Space Laboratories Code .

The Initial Developer of the Original Code is NIPPON TELEGRAPH AND 
TELEPHONE CORPORATION.
Portions created by the NIPPON TELEGRAPH AND TELEPHONE CORPORATION 
are Copyright (C) 2004 NIPPON TELEGRAPH AND TELEPHONE CORPORATION. 
All Rights Reserved.

Contributor(s) ______________________________________.
*/
package jp.co.ntt.lms.installer.util;

import java.io.InputStream;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;

/**
 * ログ出力関連のユーティリティクラス。
 * @author T.Nishiki
 */
public class LoggerUtil {
	/**
	 * ログレベル：メソッドＩ／Ｏログ。
	 */
	public static final Level LEVEL_METHOD_IO = Level.FINE;

	/**
	 * ログマネージャにプロパティを設定します。<br>
	 *
	 * @param propertyURI プロパティを取得でいるＵＲＩ。
	 * @see LogManager#readConfiguration(InputStream)
	 */
	public static void setLoggingProperty(String propertyURI) {
		// ログ・プロパティリソースの入力ストリーム
		InputStream logPropertiesStream = null;
		try {
			ClassLoader loader = ClassLoader.getSystemClassLoader();
			logPropertiesStream = loader.getResourceAsStream(propertyURI);
			// ストリームを取得できたら、ログマネージャに設定
			if (logPropertiesStream != null) {
				LogManager logManager = LogManager.getLogManager();
				logManager.readConfiguration(logPropertiesStream);
			}
		}
		// 何かしらエラーが発生した場合、ログ設定が完結していないので、
		// 標準エラー出力で出力する。
		catch (Throwable th) {
			th.printStackTrace();
		}
		finally {
			// ストリームのクローズ
			if (logPropertiesStream != null) {
				try {
					logPropertiesStream.close();
				}
				catch (Exception e) {
					e.printStackTrace();
				}
				logPropertiesStream = null;
			}
		}
	}

	/**
	 * Classオブジェクトを利用して、ログオブジェクトを取得します。<br>
	 *
	 * @param cls 取得するログオブジェクトを識別するためにクラス・オブジェクト。
	 * @return clsに対応するログ出力オブジェクト。
	 *           clsがnull場合、Objectクラスに対応するログ出力オブジェクト。
	 * @see Class#getName()
	 */
	public static Logger getLogger(Class cls) {
		if (cls == null) {
			return Logger.getLogger(Object.class.getName());
		}
		return Logger.getLogger(cls.getName());
	}

	/**
	 * メソッドの開始ログを出力します。
	 * @param logger ログ出力オブジェクト。
	 * @param message 出力するメッセージ。
	 */
	public static void methodHead(Logger logger, String message) {
		if (logger != null && logger.isLoggable(LEVEL_METHOD_IO)) {
			logger.log(LEVEL_METHOD_IO,
				"HEAD " + message);
		}
	}

	/**
	 * メソッドの終了ログを出力します。
	 * @param logger ログ出力オブジェクト。
	 * @param message 出力するメッセージ。
	 */
	public static void methodTail(Logger logger, String message) {
		if (logger != null && logger.isLoggable(LEVEL_METHOD_IO)) {
			logger.log(LEVEL_METHOD_IO,
				"TAIL " + message);
		}
	}

	/**
	 * メソッドの終了ログを出力します。
	 * @param logger ログ出力オブジェクト。
	 * @param message 出力するメッセージ。
	 * @param returnedValue メソッドの戻り値。
	 */
	public static void methodTail(
			Logger logger, String message, Object returnedValue) {
		if (logger != null && logger.isLoggable(LEVEL_METHOD_IO)) {
			logger.log(LEVEL_METHOD_IO,
				"TAIL " + message + ":return[" + returnedValue + "]");
		}
	}

	/**
	 * メソッドの終了ログを出力します。
	 * @param logger ログ出力オブジェクト。
	 * @param message 出力するメッセージ。
	 * @param returnedValue メソッドの戻り値。
	 */
	public static void methodTail(
			Logger logger, String message, boolean returnedValue) {
		if (logger != null && logger.isLoggable(LEVEL_METHOD_IO)) {
			logger.log(LEVEL_METHOD_IO,
				"TAIL " + message + ":return[" + returnedValue + "]");
		}
	}

	/**
	 * メソッドの終了ログを出力します。
	 * @param logger ログ出力オブジェクト。
	 * @param message 出力するメッセージ。
	 * @param returnedValue メソッドの戻り値。
	 */
	public static void methodTail(
			Logger logger, String message, char returnedValue) {
		if (logger != null && logger.isLoggable(LEVEL_METHOD_IO)) {
			logger.log(LEVEL_METHOD_IO,
				"TAIL " + message + ":return[" + returnedValue + "]");
		}
	}

	/**
	 * メソッドの終了ログを出力します。
	 * @param logger ログ出力オブジェクト。
	 * @param message 出力するメッセージ。
	 * @param returnedValue メソッドの戻り値。
	 */
	public static void methodTail(
			Logger logger, String message, long returnedValue) {
		if (logger != null && logger.isLoggable(LEVEL_METHOD_IO)) {
			logger.log(LEVEL_METHOD_IO,
				"TAIL " + message + ":return[" + returnedValue + "]");
		}
	}

	/**
	 * メソッドの終了ログを出力します。
	 * @param logger ログ出力オブジェクト。
	 * @param message 出力するメッセージ。
	 * @param returnedValue メソッドの戻り値。
	 */
	public static void methodTail(
			Logger logger, String message, double returnedValue) {
		if (logger != null && logger.isLoggable(LEVEL_METHOD_IO)) {
			logger.log(LEVEL_METHOD_IO,
				"TAIL " + message + ":return[" + returnedValue + "]");
		}
	}

	/**
	 * 例外がスローされたときのログを出力します。
	 * @param logger ログ出力オブジェクト。
	 * @param e スローされた例外オブジェクト。
	 */
	public static void throwable(Logger logger, Exception e) {
		if (logger != null && logger.isLoggable(Level.WARNING)) {
			logger.log(Level.WARNING, "Exception occured:", e);
		}
	}

	/**
	 * Throwableがスローされたときのログを出力します。
	 * @param logger ログ出力オブジェクト。
	 * @param th スローされたThrowableオブジェクト。
	 */
	public static void throwable(Logger logger, Throwable th) {
		if (logger != null && logger.isLoggable(Level.SEVERE)) {
			logger.log(Level.SEVERE, "Throwable occured:", th);
		}
	}

	/**
	 * メソッドの開始／終了ログがログ出力可能か判定します。
	 * @param logger ログ出力オブジェクト。
	 * @return 出力可能な場合true、出力しない場合false。
	 * @see #methodHead(Logger, String)
	 * @see #methodTail(Logger, String)
	 * @see #methodTail(Logger, String, boolean)
	 * @see #methodTail(Logger, String, char)
	 * @see #methodTail(Logger, String, double)
	 * @see #methodTail(Logger, String, long)
	 * @see #methodTail(Logger, String, Object)
	 */
	public static boolean isLoggableMethod(Logger logger) {
		return logger.isLoggable(LEVEL_METHOD_IO);
	}

	/**
	 * システムのプロパティをログ出力します。<br>
	 * ログレベルは、CONFIGです。
	 * @see Level#CONFIG
	 */
	public static void logSystemProperties(Logger logger) {
		if (logger.isLoggable(Level.CONFIG)) {
			Properties properties = System.getProperties();
			Set keys = new TreeSet(properties.keySet());
			for (Iterator i = keys.iterator(); i.hasNext();) {
				String key = (String)i.next();
				String value = properties.getProperty(key);
				logger.config("[" + key + "][" + value + "]");
			}
		}
	}
}
