package jp.cssj.cti.servlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Map.Entry;

import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jp.cssj.cti.CTIDriver;
import jp.cssj.cti.CTIDriverManager;
import jp.cssj.cti.CTISession;

/**
 * <p>
 * JSP/Servletの出力をPDFに変換するためのフィルタです。
 * <p>
 * 以下のコンテキスト・パラメータを使います。
 * <dl>
 * <dt>cssj.host</dt>
 * <dd>CSSJサーバーのホスト名</dd>
 * 
 * <dt>cssj.port</dt>
 * <dd>CSSJサーバーのポート番号</dd>
 * 
 * <dt>cssj.password</dt>
 * <dd>CSSJサーバーのパスワード</dd>
 * <dl>
 * 
 * <p>
 * フィルタ・パラメータは以下の通りです。
 * <dl>
 * <dt>resources</dt>
 * <dd>リソースのパスのリスト(カンマ区切り)</dd>
 * <dt>prop.*</dt>
 * <dd>CSSJに渡すプロパティです。*をプロパティ名に置き換えてください。</dd>
 * </dl>
 * 
 * <p>
 * パスはjavax.servlet.ServletRequest#getRequestDispatcherに渡すのと同じ形式です。
 * </p>
 * <p>
 * 設定例はwebapp/WEB-INF/web.xmlを参照してください。
 * </p>
 * 
 * <p>
 * なお、このサーブレットは動的に変換するリソースを切り替える機能はありません。
 * より柔軟な処理が必要な場合は、AbstractCSSJFilterを継承してプログラミングしてください。
 * </p>
 * 
 * @author <a href="mailto:miyabe at gnn.co.jp">MIYABE Tatsuhiko </a>
 * @version $Id: CSSJFilter.java,v 1.3 2005/08/18 04:51:26 harumanx Exp $
 */
public class CSSJFilter extends AbstractCSSJFilter {
	private String host, password;

	private int port;

	private String[] resources = null;

	private Map properties = null;

	public void init(FilterConfig config) throws ServletException {
		this.host = config.getServletContext().getInitParameter("cssj.host");
		this.port = Integer.parseInt(config.getServletContext()
				.getInitParameter("cssj.port"));
		this.password = config.getServletContext().getInitParameter(
				"cssj.password");
		String resources = config.getInitParameter("resources");
		if (resources != null) {
			ArrayList list = new ArrayList();
			for (StringTokenizer i = new StringTokenizer(resources, ","); i
					.hasMoreTokens();) {
				list.add(i.nextToken());
			}
			this.resources = (String[]) list.toArray(new String[list.size()]);
		}

		this.properties = new HashMap();
		for (Enumeration i = config.getInitParameterNames(); i
				.hasMoreElements();) {
			String name = (String) i.nextElement();
			if (name.startsWith("prop.")) {
				String value = config.getInitParameter(name);
				this.properties.put(name.substring(5), value);
			}
		}
		this.properties = Collections.unmodifiableMap(this.properties);
	}

	public void destroy() {
		// do nothing
	}

	protected CTISession createSession(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// ドライバを取得
		CTIDriver driver = CTIDriverManager.createDriverFor(this.host,
				this.port);
		// 接続する(ユーザー名は"user"で固定)
		return driver.createSession("user", this.password);
	}

	protected void prepare(CTISession session, HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// プロパティを設定
		for (Iterator i = this.properties.entrySet().iterator(); i.hasNext();) {
			Entry entry = (Entry) i.next();
			session.setProperty((String) entry.getKey(), (String) entry
					.getValue());
		}

		// リソースを送信
		if (this.resources != null) {
			for (int i = 0; i < this.resources.length; ++i) {
				String uri = this.resources[i];
				this.sendResource(session, request, response, uri, null);
			}
		}
	}
}