/*
 * LOGICAL-PARADOX.ORG b-tree library
 * Copyright (C)2004,2005 satoshi akabane(akabane@logical-paradox.org)
 * $Id: BtreeFactory.java,v 1.2 2005/05/16 15:36:45 rampil Exp $
 */
package org.logical_paradox.common.btree;

import java.util.HashMap;
import java.util.Properties;

/**
 * Btreeライブラリ用のデータ構造を生成するファクトリクラスのためのabstract factory．<br>
 * アプリケーションは必ずこの基底クラスを実装したクラスを生成する必要がある．<br>
 * このファクトリでは，BtreeKeyの実装とBtreeObjectの実装を返す．
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.2 $
 */
public abstract class BtreeFactory {
	public static final String DEFAULT_BTREE_FACTORY = "org.logical_paradox.common.btree.DefaultBtreeFactory";
	public static final String JVM_SPECIFIED_BTREE_FACTORY_KEY = "org.logical_paradox.common.btree.factory_class";

	// ファクトリプール
	private static final HashMap _factoryPool = new HashMap();

	// デフォルトコンストラクタ
	protected BtreeFactory() {
	}
	/**
	 * JVMで指定されたクラスでBtreeファクトリを生成する．<br>
	 * JVMで指定されていない場合，デフォルトのファクトリが選択される．
	 * @return 生成されたbtreeファクトリ
	 * @throws Exception ファクトリクラスの生成に失敗した
	 */
	public static final BtreeFactory getInstance() throws Exception {
		String factoryClassName = System.getProperty(JVM_SPECIFIED_BTREE_FACTORY_KEY);
		if(factoryClassName == null || factoryClassName.trim().length() == 0) {
			// JVMの引数でファクトリが指定されなかった場合はデフォルト
			factoryClassName = DEFAULT_BTREE_FACTORY;
		}
		return BtreeFactory.getInstance(factoryClassName);
	}
	/**
	 * 指定されたクラスのファクトリを生成する．<br>
	 * ファクトリがファクトリプールに既に存在している場合，それを返す．<br>
	 * ファクトリがファクトリプールに存在しない場合，新しくインスタンスを生成して返し，プーリングする．
	 * @param classname ファクトリクラス名
	 * @return 生成されたbtreeファクトリ
	 * @throws Exception ファクトリクラスの生成に失敗した
	 */
	public static final BtreeFactory getInstance(String classname) throws Exception {
		BtreeFactory factory = (BtreeFactory)_factoryPool.get(classname);
		if(factory == null || factory instanceof BtreeFactory) {
			factory = (BtreeFactory)Class.forName(classname).newInstance();
			_factoryPool.put(classname, factory);
		}
		return factory;
	}
	/**
	 * このファクトリで生成されるファイルの設定値を返す
	 * 
	 * @return 設定値
	 * @throws BtreeException 設定値を返すことができない場合
	 */
	protected abstract Properties getProperty() throws BtreeException;

	/**
	 * ファイルハンドルを返す<br>
	 * ただしこのメソッドを呼び出しても，ファイル自体はオープンされていないことに注意
	 * 
	 * @param filename ファイル名
	 * @return BtreeFile ファイル
	 * @throws BtreeException 何らかの理由でファイルハンドルの生成に失敗した
	 */
	public abstract BtreeFile getFileHandle(String filename) throws BtreeException;

	/**
	 * 利用可能リストを返す
	 * ただし，作成された利用可能リストはオープンされない
	 * @param filename ファイル名
	 * @return 利用可能リスト
	 * @throws BtreeException 利用可能リストの作成に失敗した
	 */
	public abstract BtreeAvailableList getBtreeAvailableList(String filename) throws BtreeException;
	/**
	 * 新しいBtreeKeyを返す
	 *
	 * @param o 引数オブジェクト
	 * @return BtreeKey キー
	 * @exception BtreeException 生成に失敗した場合
	 * @see org.logical_paradox.common.btree.BtreeKey
	 */
	public abstract BtreeKey newKey(Object o) throws BtreeException;
	/**
	 * 新しいBtreeKeyを返す
	 * @param stream バイト列
	 * @return 復元されたBtreeKey
	 * @throws BtreeException バイト列がBtreeKeyの復元ができなかった場合
	 */
	public abstract BtreeKey newKey(byte[] stream) throws BtreeException;

	/**
	 * BtreeKeyのバイトサイズを返す
	 *
	 * @return int バイトサイズ
	 * @see org.logical_paradox.common.btree.BtreeKey
	 */
	public abstract int keyByteSize();
}

// end of BtreeFactory.java
