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

import java.util.HashMap;
import java.util.Map;

import jp.co.cybec.cb3.exception.AccessorUnknownException;
import jp.co.cybec.cb3.exception.ConfigFileDefinitionException;
import jp.co.cybec.cb3.exception.ConfigurationRuntimeException;
import jp.co.cybec.cb3.util.CB3BeanFactory;
import jp.co.cybec.cb3.util.logging.ErrorCodeConstant;
import jp.co.cybec.cb3.util.logging.LogMessageConstant;
import jp.co.cybec.cb3.util.logging.LogMessageFactory;

/**
 * データアクセスコンテキストの実装クラス。<br>
 * サービスで使用するデータアクセッサと、キー（＝設定ファイル名）の組み合わせをMapに保持し、
 * lookupメソッドで返します。
 * データアクセッサは、Springにより生成され、データアクセスコンテキストに注入されます。
 * @author Naoko Sugimoto
 */
public class DataAccessContextImpl implements DataAccessContext, DataAccessContextLifeCycle {

	/** データアクセッサ */
	private Map<String, Accessor> dataAccessors = new HashMap<String, Accessor>();

	/** メッセージ */
	private static final LogMessageFactory MESSAGE = new LogMessageFactory(
			LogMessageConstant.CB3_MESSAGE_FILENAME);

	/**
	 * コンストラクタ。<br>
	 * データアクセッサを初期化します。
	 * @param dataAccessors データアクセッサと、キー（＝設定ファイル名）を組み合わせたMap。
	 * @throws AccessorUnknownException アクセッサの初期化で予期しない例外が発生した場合に発生する。
	 */
	public DataAccessContextImpl(Map<String, Accessor> dataAccessors) throws AccessorUnknownException {
		this.dataAccessors = dataAccessors;

		try {
			for (String key : dataAccessors.keySet()) {
				// Accessorの初期化。XMLファイルの読み込みを行う。
				((AccessorsLifeCycle)dataAccessors.get(key)).initialize(key);
			}
		} catch (RuntimeException e) {
			if (e instanceof ConfigurationRuntimeException) {
				throw e;
			} else {
				// 予期しない例外が発生した場合に、アクセッサの処理で発生したということが分かるようにするため置き換える。
				throw new AccessorUnknownException(MESSAGE.getErrorMessage(
						ErrorCodeConstant.ACCESSOR_001, LogMessageConstant.CB3_ACCESSOR_002), e);
			}
		}
	}

	/**
	 * データアクセッサを返します。
	 * @param key アクセッサキー
	 * @return データアクセッサ
	 */
	public Accessor lookup(String key) {

		if (dataAccessors.get(key) == null) {
			throw new ConfigFileDefinitionException(
					MESSAGE.getErrorMessage(
							ErrorCodeConstant.ACCESSOR_002,
							LogMessageConstant.CB3_ACCESSOR_001,
							CB3BeanFactory.getInstance().getApplicationContextFilePath(),
							key
					)
			);
		}
		return dataAccessors.get(key);
	}

	/**
	 * アクセッサコンテキストの終了処理です。<br>
	 * データアクセッサの終了処理を呼び出します。
	 */
	public void release() {
		for (String key : dataAccessors.keySet()) {
			// Accessorの終了。閉じ忘れたResultSetやストリームのcloseなどを行う。
			((AccessorsLifeCycle)dataAccessors.get(key)).release();
		}
	}
}
