/*
 * LOGICAL-PARADOX.ORG
 * Copyright (C)2005 satoshi akabane(akabane@logical-paradox.org)
 * $Id: MethodHandlerFactory.java,v 1.1 2005/05/11 17:48:20 rampil Exp $
 */
package org.logical_paradox.httpd.method;

import java.util.HashMap;
import java.util.Map;

import org.logical_paradox.httpd.HttpdProperties;

/**
 * httpプロトコルのメソッドハンドラファクトリ
 * 与えられたHTTPメソッドに対応するハンドラクラスを生成します．
 * @author satoshi akabane@logical-paradox.org
 * @version $Revision: 1.1 $
 */
public class MethodHandlerFactory {
	/** GETメソッド */
	public static final String HTTP_GET = "GET";
	/** POSTメソッド */
	public static final String HTTP_POST = "POST";
	/** HEADメソッド */
	public static final String HTTP_HEAD = "HEAD";
	/** EXITメソッド */
	public static final String HTTP_EXIT = "EXIT";

	/** デフォルトファクトリ(singleton) */
	private static MethodHandlerFactory defaultFactory = new MethodHandlerFactory();
	/** メソッドハンドラクラスのマップ */
	private static final Map handlers;

	/*
	 * スタティックイニシャライザ
	 * メソッドハンドラのマップを初期化する
	 */
	static {
		HashMap m = new HashMap();
		// GET
		m.put(HTTP_GET, HttpdProperties.getProperty(HttpdProperties.MHDLR_GET));
		// POST
		m.put(HTTP_POST, HttpdProperties.getProperty(HttpdProperties.MHDLR_POST));
		// HEAD
		m.put(HTTP_HEAD, HttpdProperties.getProperty(HttpdProperties.MHDLR_HEAD));
		// EXIT
		m.put(HTTP_EXIT, HttpdProperties.getProperty(HttpdProperties.MHDLR_EXIT));

		handlers = m;
	}
	/**
	 * コンストラクタ
	 */
	protected MethodHandlerFactory() {
	}
	/**
	 * デフォルトファクトリのインスタンスを設定する
	 * @param newFactory デフォルトファクトリのインスタンス
	 */
	protected void setInstance(MethodHandlerFactory newFactory) {
		defaultFactory = newFactory;
	}
	/**
	 * デフォルトのメソッドハンドラファクトリのインスタンスを返す
	 * @return デフォルトのメソッドハンドラファクトリ
	 */
	public static final MethodHandlerFactory getInstance() {
		return defaultFactory;
	}

	/**
	 * 指定されたHTTPメソッドに対応するハンドラクラスを生成して返す
	 * @param type タイプ(HTTPメソッド)
	 * @return 生成されたハンドラクラス(null=未登録)
	 */
	public HttpMethodHandler getMethodHandler(String type) {
		Object handler = handlers.get(type);
		if(handler == null) {
			// 指定されたメソッドに対応するハンドラクラスが登録されていない場合
			return null;
		} else if(handler instanceof String) {
			// マップに格納されているのがハンドラクラスではない(=まだインスタンス化されていない)
			try {
				Class clazz = Class.forName((String)handler);
				HttpMethodHandler hdl = (HttpMethodHandler)clazz.newInstance();
				handlers.put(type, hdl);
				return hdl;
			} catch (Exception e) {
				e.printStackTrace();
				return null;
			}
		} else if(handler instanceof HttpMethodHandler) {
			// マップに格納されているのがハンドラクラスそのものの場合、それ自体を返す
			return (HttpMethodHandler)handler;
		} else {
			// それ以外の妙なクラスのインスタンスが格納されている
			throw new IllegalStateException();
		}
	}
}
