/*
 * Copyright (c) 2009 The openGion Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.opengion.hayabusa.db;

import org.opengion.hayabusa.common.HybsSystem ;
import org.opengion.hayabusa.common.SystemManager ;
import org.opengion.fukurou.util.Cleanable;

import java.util.Map;
import java.util.WeakHashMap ;

/**
 * Selectionオブジェクトを取得する為に使用するファクトリクラスです。
 *
 * Selectionオブジェクト のキー(codeName)を元に、オブジェクトをキャッシュ管理
 * することが、主な機能です。
 *
 * @og.rev 3.5.5.7 (2004/05/10) 新規作成
 * @og.group 選択データ制御
 *
 * @version  4.0
 * @author   Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
public final class SelectionFactory {
	// private static final Map<String,Selection>  codeMap = new WeakHashMap<String,Selection>();
	private static final Map<String,Selection>  dbMap   = new WeakHashMap<String,Selection>( HybsSystem.BUFFER_SMALL );
	private static final Map<String,Selection>  dbRadioMap   = new WeakHashMap<String,Selection>( HybsSystem.BUFFER_SMALL ); // 4.3.3.6 (2008/11/15)

	// 4.0.0 (2005/01/31) Cleanable インターフェースによる初期化処理
	static {
		Cleanable clr = new Cleanable() {
			public void clear() {
				SelectionFactory.clear();
			}
		};

		SystemManager.addCleanable( clr );
	}

	/**
	 *  デフォルトコンストラクターをprivateにして、
	 *  オブジェクトの生成をさせないようにする。
	 *
	 */
	private SelectionFactory() {
	}

	/**
	 * コードデータオブジェクトより、コードリソースSelectionオブジェクトを構築します。
	 *
	 * @og.rev 4.0.0.0 (2007/11/07) DBColumnにSelectionオブジェクトをキャッシュするように変更
	 *
	 * @param   cdData CodeData コードデータ
	 *
	 * @return  Selectionオブジェクト
	 */
//	public static Selection newCodeSelection( final CodeData cdData ) {
//		String key = cdData.getColumn() ;
//		Selection select = codeMap.get( key );
//		if( select == null ) {
//			synchronized( codeMap ) {
//				select = new Selection_CODE( cdData );
//				codeMap.put( key,select );
//			}
//		}
//		return select;
//	}

	/**
	 * DB検索(SQL)文字列より、データベースSelectionオブジェクトを構築します。
	 * Selection_DB では、検索行毎のクエリーがあるため、name + query でキャッシュします。
	 *
	 * @og.rev 4.0.0 (2006/11/15) lang 属性を追加します。
	 *
	 * @param   query DB検索(SQL)文字列
	 * @param	dbid  データベース接続先ID
	 * @param	lang  リソースを使用する場合の言語
	 *
	 * @return  Selectionオブジェクト
	 */
	public static Selection newDBSelection( final String query,final String dbid,final String lang ) {
		String key = query+dbid+lang;
		Selection select = dbMap.get( key );

		if( select == null || select.isTimeOver() ) {
			synchronized( dbMap ) {
				select = new Selection_DB( query,dbid,lang );
				dbMap.put( key,select );
			}
		}
		return select;
	}

	/**
	 * DB検索(SQL)文字列より、データベースSelectionオブジェクトを構築します。
	 * Selection_DB では、検索行毎のクエリーがあるため、name + query でキャッシュします。
	 *
	 * @og.rev 4.3.3.6 (2008/11/15) 新規作成
	 *
	 * @param   query DB検索(SQL)文字列
	 * @param	dbid  データベース接続先ID
	 * @param	lang  リソースを使用する場合の言語
	 *
	 * @return  Selectionオブジェクト
	 */
	public static Selection newDBRadioSelection( final String query,final String dbid,final String lang ) {
		String key = query+dbid+lang;
		Selection select = dbRadioMap.get( key );

		if( select == null || select.isTimeOver() ) {
			synchronized( dbRadioMap ) {
				select = new Selection_DBRADIO( query,dbid,lang );
				dbRadioMap.put( key,select );
			}
		}
		return select;
	}

	/**
	 * Selectionオブジェクトをプールからすべて削除します。
	 * システム全体を初期化するときや、動作が不安定になったときに行います。
	 * プールの方法自体が,一種のキャッシュ的な使いかたしかしていない為,
	 * 実行中でも、いつでもプールを初期化できます。
	 *
	 * @og.rev 4.3.3.6 (2008/11/15) DBRadioMap追加
	 */
	public static void clear() {
		// synchronized( codeMap ) { codeMap.clear(); }
		synchronized( dbMap   ) { dbMap.clear(); }
		synchronized( dbRadioMap ) { dbRadioMap.clear(); } // 4.3.3.6 (2008/11/15)
	}
}
