/*
 * $Id: SearchEngine.java,v 1.5 2005/11/06 14:46:25 rampil Exp $
 * Copyright (c) 2004 LOGICAL-PARADOX.ORG
 */
package org.logical_paradox.koike.core.search;

import org.logical_paradox.koike.core.KoikeConfig;
import org.logical_paradox.koike.core.document.DocumentAccessor;
import org.logical_paradox.koike.core.indexer.IndexAccessor;
import org.logical_paradox.koike.core.parser.Parser;

/**
 * 検索エンジンの基底クラス
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.5 $
 */
public abstract class SearchEngine {
	/** コンフィグレーション */
	private KoikeConfig config;
	/** インデックスアクセサ */
	private IndexAccessor indexAccessor;
	/** ドキュメントアクセサ */
	private DocumentAccessor documentAccessor;
	/** パーザー */
	private Parser parser;

	/**
	 * コンストラクタ．
	 * @param cfg コンフィグレーション
	 * @throws Exception インスタンスの生成時に発生した例外
	 */
	protected SearchEngine(KoikeConfig cfg) throws Exception {
		config = cfg;
		init();
	}
	/**
	 * サーチエンジンの共通初期化コード
	 * 初期化処理を個別に実装したい場合、このメソッドをサブクラスでオーバーライドすること
	 * @throws Exception 初期化処理中に発生した例外
	 */
	protected void init() throws Exception {
	}
	/**
	 * コンフィグレーションを返す
	 * @return コンフィグレーション
	 */
	protected KoikeConfig getConfig() {
		return config;
	}
	/**
	 * 検索処理を実行する
	 * 検索処理自体はサブクラスが実装する
	 * @param condition 検索条件
	 * @return 結果セット
	 * @throws SearchException 検索処理中に発生した障害
	 */
	public abstract SearchResult search(SearchCondition condition) throws SearchException;

	/**
	 * 選択されているパーザーを返す
	 * @return パーザー
	 */
	protected synchronized Parser getParser() {
		if(parser == null) {
			parser = new Parser(config.getNgramTermLength());
		}
		return parser;
	}
	/**
	 * インデックスシステムに対するアクセスインターフェースを返す
	 * インターフェースがまだ生成されていない場合、生成して返す<br>
	 * 1度でも初期化された場合、2度目以降の呼出では初期化されない。
	 * @return インデックスシステムに接続するためのインターフェース
	 * @throws SearchException 生成に失敗した
	 */
	protected synchronized IndexAccessor getIndexAccessor() throws SearchException {
		if(indexAccessor == null) {
			try {
				indexAccessor = getConfig().getInterfaceFactory().getIndexAccessor();
			} catch (Exception e) {
				e.printStackTrace();
				throw new SearchException(e);
			}
		}
		return indexAccessor;
	}
	/**
	 * ドキュメント管理システムに対するアクセスインターフェースを返す
	 * インターフェースがまだ生成されていない場合、生成して返す<br>
	 * 1度でも初期化された場合、2度目以降の呼出では初期化されない。
	 * @return ドキュメント管理システムに接続するためのインターフェース
	 * @throws SearchException 生成に失敗した
	 */
	protected synchronized DocumentAccessor getDocumentAccessor() throws SearchException {
		if(documentAccessor == null) {
			try {
				documentAccessor = getConfig().getInterfaceFactory().getDocumentAccessor();
			} catch (Exception e) {
				e.printStackTrace();
				throw new SearchException(e);
			}
		}
		return documentAccessor;
	}
}
