/*
このファイルの中身は、NTT オープンソースライセンス　バージョン 1.0（「本
契約」という）の適用を受けます。
本契約を遵守しない限り、このファイルを使用してはなりません。
本契約のコピーは、次のＵＲＬから入手できます。
【配布サイトのURL】 http://www.oss.ecl.ntt.co.jp/lms/

本契約に基づき頒布されるソフトウェアは、現状のまま、明示又は黙示のあらゆ
る種類の保証なしで、頒布されます。本契約に基づく権利及び制限を律する特定
の文言については、本契約を参照してください。

「オリジナルコード」は、 NTT Cyber Space Laboratories Code です。 
「オリジナルコード」の「初期開発者」は、日本電信電話株式会社です。  
日本電信電話株式会社により創作された部分は、Copyright (C) 2004 
日本電信電話株式会社 です。
全ての権利が留保されます。 
「コントリビュータ」：_____________________________________ 


The contents of this file are subject to the NTT Opensource License
Version 1.0 (the License); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
【配布サイトのURL】 http://www.oss.ecl.ntt.co.jp/lms/

Software distributed under the License is distributed on an AS IS
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.

The Original Code is NTT Cyber Space Laboratories Code .

The Initial Developer of the Original Code is NIPPON TELEGRAPH AND 
TELEPHONE CORPORATION.
Portions created by the NIPPON TELEGRAPH AND TELEPHONE CORPORATION 
are Copyright (C) 2004 NIPPON TELEGRAPH AND TELEPHONE CORPORATION. 
All Rights Reserved.

Contributor(s) ______________________________________.
*/

//
// CopyRight (C) 2003, NTT All rights reserved.
//
//	アップロードファイル部品クラス
//			変更履歴
//				2004.01.08	新規作成	五木田 泰史
//
package jp.co.ntt.lms;

import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Hashtable;
import java.util.StringTokenizer;

/**
 * アップロードファイル部品クラス
 *
 * <PRE>
 *   アップロードファイルの各部品。
 * </PRE>
 *
 */
public class Part
{
	private static String dataType = "Content-Disposition: form-data; ";
	private static String mimeType = "Content-Type: ";
	private boolean binary = false;
	private int paramsLength = 0;
	private int contentLength = 0;
	private int writebytes = 0;
	private String key = null;
	private Hashtable params = new Hashtable();
	private ByteArrayOutputStream ostream = new ByteArrayOutputStream();

	/**
	 * パラメータリスト取得
	 * @return Hashtable パラメータリスト
	 */
	public Hashtable getParams()
	{
		return params;
	}

	/**
	 * バイナリーチェック
	 * @return boolean バイナリー判定
	 */
	public boolean isBinary()
	{
		return binary;
	}

	/**
	 * パラメータ設定
	 * @param String パラメータ
	 * @return void
	 */
	void setParams(String paramString)
	{
		params.put("Content-Type", "text/plain");
		if(paramString.startsWith(mimeType))
		{
			params.put("Content-Type",
						trimln(substring(paramString, mimeType)));
			return;
		}
		String param = substring(paramString, dataType);
		StringTokenizer st = new StringTokenizer(param, ";");
		int count = st.countTokens();
		if (count < 1) return;
		StringTokenizer st2;
		String key, value;
		for(int i=0; i < count; i++)
		{
			String strCon = st.nextToken();
			int index = strCon.indexOf( '=' );
			if( index > -1 ) {
				key = strCon.substring( 0, index );
				value = trim(strCon.substring( index + 1, strCon.length() ));
				if ("name".equals(key)){
					this.key = value;
				}else{
					// 通常のnameのキーはハッシュに保管しない
					if(this.key != null)
					{
						params.put(this.key, value);
					}
				}
			}
		}
		if(count < 2)
		{
			binary = false;
		}
		else
		{
			binary = true;
		}
	}

	/**
	 * パラメータ長設定
	 * @param int パラメータ長
	 * @return void
	 */
	void setParamsLength(int paramsLength)
	{
		this.paramsLength = paramsLength;
	}

	/**
	 * パラメータ長取得
	 * @return int パラメータ長
	 */
	int getParamsLength()
	{
		return paramsLength;
	}

	/**
	 * コンテント長設定
	 * @param int コンテント長
	 * @return void
	 */
	void setContentLength(int contentLength)
	{
		this.contentLength = contentLength;
	}

	/**
	 * コンテント長取得
	 * @return int コンテント長
	 */
	int getContentLength()
	{
		return contentLength;
	}

	/**
	 * キーによる文字列分割処理
	 * @param String 分割前パラメータ
	 * @param String 分割キー
	 * @return String 分割後パラメータ
	 */
	private String substring(String str, String key)
	{
		if(str.indexOf(key) == 0)
		{
			return str.substring(key.length());
		}
		return str;
	}

	/**
	 * 空白除去処理
	 * @param String 除去前パラメータ
	 * @return String 除去後パラメータ
	 */
	private String trim(String str)
	{
		if (str.endsWith("\n"))
		{
			return str.substring(1, str.length()-3);
		}
		else
		{
			return str.substring(1, str.length()-1);
		}
	}

	/**
	 * 改行含む空白除去処理
	 * @param String 除去前パラメータ
	 * @return String 除去後パラメータ
	 */
	private String trimln(String str)
	{
		if (str.endsWith("\n"))
		{
			return str.substring(0, str.length()-2);
		}
		return str;
	}

	/**
	 * コンテント設定
	 * @param byte[] コンテント
	 * @return void
	 * @exception UnsupportedEncodingException サポートエンコード例外エラー
	 */
	void setContent(byte[] buf)
	throws UnsupportedEncodingException
	{
		if(binary)
		{
			if((writebytes+buf.length) <= contentLength)
			{
				ostream.write(buf, 0, buf.length);
				writebytes += buf.length;
			}
			else
			{
				ostream.write(buf, 0, (contentLength-writebytes));
			}
		}
		else
		{
			String value = new String(buf,"Windows-31J");

			// すでに保管済みの部分があれば、改行をつけて連結する
			String tmp = (String)params.get(key);
			if(tmp != null){
				value = tmp + "\n" + value;
			}
			params.put(key, trimln(value));
		}
	}

	/**
	 * バイナリーコンテント取得
	 * @return byte[] バイナリーコンテント
	 */
	public byte[] getBinaryContent()
	{
		return ostream.toByteArray();
	}

	/**
	 * コンストラクタ
	 */
	Part()
	{
		;
	}
}