/*
 * Common Library for TBAS Softwares
 *
 * All Rights Reserved.
 * (c) Copyright 2002 by Tsukuba Bunko.
 *
 * $Id: DeserializerMapping.java,v 1.1 2003/08/31 08:20:49 ppoi Exp $
 */
package tsukuba_bunko.resource;

import	java.util.Enumeration;
import	java.util.Map;
import	java.util.ResourceBundle;


/**
 * データ型名と <code>ResourceDeserializer</code> のマップを管理します。このクラスは thread-safe ではありませんので、malti-thread
 * 環境で使用する場合は、同期の制御を行ってください。
 * @author	$Author: ppoi $
 * @version	$Revision: 1.1 $
 */
public class DeserializerMapping	{

	/**
	 * データ型名 - ResourceDeserializer マップ
	 */
	private Map	_registry = new java.util.HashMap( 89 );


	/**
	 * <code>DeserializerMapping</code> のインスタンスを作成します。
	 */
	public DeserializerMapping()
	{
		super();
	}


	/**
	 * データ型 <code>dataType</code> に <code>ResourceDeserializer</code> クラス
	 * <code>deserializerClass</code> を関連づけます。
	 * @param	typeName	データ型名
	 * @param	deserializer	使用する <code>ResourceDeserializer</code>
	 * @exception	IllegalArgumentException	<code>deserializerClass</code> が妥当な <code>ResourceDeserializer</code> サブクラスではない場合
	 */
	public void register( String typeName, ResourceDeserializer deserializer )
	{
		deserializer.setDeserializerMapping( this );
		deserializer.setTypeName( typeName );
		_registry.put( typeName, deserializer );
	}

	/**
	 * データ型 <code>typeName</code> に関連づけられた <code>ResourceDeserializer</code> クラスを削除します。
	 * @param	typeName
	 */
	public void unregister( String typeName )
	{
		_registry.remove( typeName );
	}

	/**
	 * <code>dataType</code> に関連づけられた <code>ResourceDeserializer</code> を取得します。
	 * @param	dataType	データ型名
	 * @return	関連づけられている <code>ResourceDeserializer</code>
	 * @exception	IllegalStateException	<code>ValueDeserialzier</code> の取得に失敗した場合
	 */
	public ResourceDeserializer getResourceDeserializer( String dataType )
	{
		return (ResourceDeserializer)_registry.get( dataType );
	}

	/**
	 * 指定された reosurce bundle を使用して <code>DeserializerMapping</code> のインスタンスを作成します。
	 * @param	bundleName	ResourceBundle のベースクラス名
	 * @return	作成された <code>DeserializerMapping</code> のインスタンス
	 */
	public static DeserializerMapping newInstance( String bundleName )
	{
		DeserializerMapping	mapping = new DeserializerMapping();

		ResourceBundle	source = ResourceBundle.getBundle( bundleName );
		ClassLoader	cl = DeserializerMapping.class.getClassLoader();

		Enumeration	keys = source.getKeys();
		String	key = null;
		while( keys.hasMoreElements() )	{
			key = (String)keys.nextElement();
			String	className = source.getString( key );
			try	{
				mapping.register( key, (ResourceDeserializer)cl.loadClass(className).newInstance() );
			}
			catch( Exception e )	{
				System.err.println( "[libtbas] ERROR : illegal class \"" + className + "\"" );
				e.printStackTrace();
			}
		}

		return mapping;
	}

	/**
	 * リソースで指定された内容から <code>DeserializerMapping</code> のインスタンスを作成します。
	 * @return	作成された <code>DeserializerMapping</code> のインスタンス
	 */
	public static DeserializerMapping newInstance()
	{
		return newInstance( System.getProperty("libtbas.resource.mapping", "tsukuba_bunko.resource.mapping") );
	}
}
