package org.phosphoresce.commons.exception;

import java.io.PrintStream;
import java.io.PrintWriter;

import org.phosphoresce.commons.util.ExceptionUtil;

/**
 * 例外要因オブジェクトを保持する例外拡張クラス。<br>
 * Java 2 SDK 1.4よりルートケースがトレースされるようになったが、
 * それ以前のJDKの場合、または1.4におけるmore...より詳細なルートケース
 * をトレースする場合には当クラスを上位クラスとして例外クラスを設ける。<br>
 *
 * @author Kitagawa<br>
 *
 *<!--
 * 更新日		更新者			更新内容
 * 2005/11/22	Kitagawa		新規作成
 *-->
 */
public abstract class RootHoldingException extends Exception {

	/** ルートケース例外オブジェクト */
	private Throwable parent = null;

	/**
	 * コンストラクタ<br>
	 */
	public RootHoldingException() {
		//
	}

	/**
	 * コンストラクタ<br>
	 * @param cause ルートケース例外オブジェクト
	 */
	public RootHoldingException(Throwable cause) {
		super(cause);
		this.parent = cause;
	}

	/**
	 * コンストラクタ<br>
	 * @param message メッセージ
	 * @param cause ルートケース例外オブジェクト
	 */
	public RootHoldingException(String message, Throwable cause) {
		super(message, cause);
		this.parent = cause;
	}

	/**
	 * コンストラクタ<br>
	 * @param message メッセージ
	 */
	public RootHoldingException(String message) {
		super(message);
	}

	/**
	 * ルートケース例外を保持するか判定します。<br>
	 * @return ルートケース例外を保持する場合trueを返却
	 */
	public final boolean hasParent() {
		return parent != null;
	}

	/**
	 * ルートケース例外オブジェクトを取得します。<br>
	 * @return ルートケース例外オブジェクトを返却します。
	 */
	public final Throwable getParent() {
		return parent;
	}

	/**
	 * スタックトレースをStringオブジェクトとして取得します。<br>
	 * @return スタックトレース
	 */
	public String getStackTraceValue() {
		return ExceptionUtil.getStackTraceValue(this);
	}

	/**
	 * 標準の出力先に対してスタックトレースを出力します。<br>
	 * @see java.lang.Throwable#printStackTrace()
	 */
	public void printStackTrace() {
		super.printStackTrace();
		if (hasParent()) {
			parent.printStackTrace();
		}
	}

	/**
	 * 指定されたPrintStreamオブジェクトに対してスタックトレースを出力します。<br>
	 * @see java.lang.Throwable#printStackTrace(java.io.PrintStream)
	 */
	public void printStackTrace(PrintStream stream) {
		super.printStackTrace(stream);
		if (hasParent()) {
			parent.printStackTrace(stream);
		}
	}

	/**
	 * 指定されたPrintWriterオブジェクトに対してスタックトレースを出力します。<br>
	 * @see java.lang.Throwable#printStackTrace(java.io.PrintWriter)
	 */
	public void printStackTrace(PrintWriter writer) {
		super.printStackTrace(writer);
		if (hasParent()) {
			parent.printStackTrace(writer);
		}
	}
}

