/*
 * LOGICAL-PARADOX.ORG
 * Copyright (C)2004 satoshi akabane(akabane@logical-paradox.org)
 * $Id: LookupFactory.java,v 1.5 2005/07/31 03:03:06 rampil Exp $
 */
package org.logical_paradox.rss.lookup;

import java.util.HashMap;
import java.util.ResourceBundle;

import org.logical_paradox.rss.dsr.RSSDistributedServiceRegistry;
import org.logical_paradox.rss.lookup.impl.HashMapLookup;
import org.logical_paradox.rss.lookup.impl.RMILookup;

/**
 * 広域分散リソースネットワーク発見サービスのファクトリ
 * 
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.5 $
 */
public class LookupFactory {
	/** リソース */
	private static ResourceBundle resource = null;
	/** デフォルトリソース名 */
	public static final String DEFAULT_FACTORY_RESOURCE = "lookupfactory";

	/** RMI接続 */
	public static final int ON_RMI = 1;
	/** JVM上のローカルレジストリ */
	public static final int ON_HASHMAP = 2;

	/** デフォルトのルックアップメソッド */
	public static final int DEFAULT_LOOKUP_IMPL = ON_RMI;

	/** ハッシュマップルックアップのインスタンスマップ */
	public static final HashMap hashMapLookups = new HashMap();

	/**
	 * デフォルトの発見サービスを返す
	 * @param バインドターゲット
	 * @return 発見サービス
	 */
	public static Lookup getLookup(String bindTarget) throws Exception {
		if(resource == null) {
			setLookupFactoryResource(DEFAULT_FACTORY_RESOURCE);
		}
		return getLookup(bindTarget, Integer.parseInt(resource.getString("DEFAULT_LOOKUP_TYPE")));
	}
	/**
	 * ルックアップファクトリのデフォルト設定を取得するリソースを設定する
	 * @param rn リソース名
	 */
	public static void setLookupFactoryResource(String rn) {
		resource = ResourceBundle.getBundle(rn);
	}
	/**
	 * バインドターゲットを登録する
	 * @param service サービス
	 * @throws Exception 登録に失敗した
	 */
	public static void register(RSSDistributedServiceRegistry service) throws Exception {
		if(resource == null) {
			setLookupFactoryResource(DEFAULT_FACTORY_RESOURCE);
		}
		register(service, Integer.parseInt(resource.getString("DEFAULT_LOOKUP_TYPE")));
	}
	/**
	 * バインドターゲットを登録する
	 * @param service サービス
	 * @param type 発見サービスの種類
	 * @throws Exception 登録に失敗した
	 */
	public static void register(RSSDistributedServiceRegistry service, int type) throws Exception {
		switch(type) {
			// RMI
			case ON_RMI:
				new RMILookup().register(service);
			// HashMap
			case ON_HASHMAP:
				String key = service.getName() + ":" + type;
				HashMapLookup lookup = (HashMapLookup)hashMapLookups.get(key);
				if(lookup == null) {
					lookup = new HashMapLookup(service.getName());
					hashMapLookups.put(key, lookup);
				}
				lookup.register(service);
				break;
			default:
				throw new IllegalArgumentException();
		}
	}
	/**
	 * 指定タイプの発見サービスを返す
	 * @param バインドターゲット
	 * @param type 発見サービスの種類
	 * @return 発見サービス
	 */
	public static Lookup getLookup(String bindTarget, int type) throws Exception {
		switch(type) {
			// RMI
			case ON_RMI:
				return new RMILookup(bindTarget);
			// HashMap
			case ON_HASHMAP:
				// bindTargetとtypeの組み合わせで，既にインスタンスが生成されている場合
				// 以前に生成したものを再利用する
				String key = bindTarget + ":" + type;
				HashMapLookup lookup = (HashMapLookup)hashMapLookups.get(key);
				if(lookup == null) {
					lookup = new HashMapLookup(bindTarget);
					hashMapLookups.put(key, lookup);
				}
				return lookup;
			default:
				throw new IllegalArgumentException();
		}
	}
}
