/*
 * Copyright (c) 2009 The openGion Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.opengion.hayabusa.taglib;

import org.opengion.hayabusa.common.HybsSystem;
import org.opengion.hayabusa.common.HybsSystemException;
import org.opengion.hayabusa.db.DBTableModel;
import org.opengion.hayabusa.db.DBColumn;
import org.opengion.hayabusa.db.Query;
import org.opengion.hayabusa.db.QueryFactory;
import org.opengion.fukurou.util.XHTMLTag;
import org.opengion.fukurou.util.Attributes;

import static org.opengion.fukurou.util.StringUtil.nval ;

import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;

/**
 * プルダウンメニューの選択項目をSELECT文の結果から作成するタグです。
 *
 * 基本的には、ｑueryタグと同じ使い方をします。
 * このオブジェクトに、 queryId を与えることにより、queryId に対応した Query オブジェクト
 * （のサブクラスのオブジェクト）が作成されます。
 * ここで指定するSELECT文は、『SELECT KEY、LABEL1、LABEL2、･･･ FROM TABLE ･･･』形式 を
 * している必要があります。特別なケースとして、『SELECT KEY FROM TABLE ･･･』形式の場合は、
 * LABEL に KEY が 使用されます。
 * SystemData の USE_SQL_INJECTION_CHECK が true か、quotCheck 属性が true の場合は、
 * ＳＱＬインジェクション対策用のクォーティションチェックを行います。リクエスト引数に
 * クォーティション(')が含まれると、エラーになります。
 * 同様にUSE_XSS_CHECKがtrueか、xssCheck属性がtrueの場合は、
 * クロスサイトススクリプティング(XSS)対策のためless/greater than signのチェックを行います。
 * 
 *
 * @og.formSample
 * ●形式：
 *     &lt;og:queryOption &gt;
 *         &lt;jsp:text &gt; SELECT文 &lt;/jsp:text&gt;
 *     &lt;/og:queryOption &gt;
 * ●body：あり
 *
 * ●使用例
 *     &lt;og:select name="CDC" &gt;
 *         &lt;og:queryOption&gt;
 *             &lt;jsp:text&gt;
 *                 select NOSYN,NOSYN,NMSYN from DB01 ORDER BY 1
 *             &lt;/jsp:text&gt;
 *         &lt;/og:queryOption&gt;
 *     &lt;/og:select&gt;
 *
 *     &lt;og:select name="CDC" &gt;                選択項目の一番上に空白をセットしたいときoptionタグを組合せることも可能です。
 *         &lt;og:option msg="" /&gt;               初期値を設定したいときはvalue属性を使います。
 *         &lt;og:queryOption value="61200" separator=":" &gt;
 *             &lt;jsp:text&gt;
 *                 select CDBK,CDBK,NMBK from DB02 ORDER BY 1
 *             &lt;/jsp:text&gt;
 *         &lt;/og:queryOption&gt;
 *     &lt;/og:select&gt;
 *
 * @og.group 選択データ制御
 *
 * @version  4.0
 * @author   Kazuhiko Hasegawa
 * @since    JDK5.0,
 */
public class QueryOptionTag extends CommonTagSupport {
	//* このプログラムのVERSION文字列を設定します。	{@value} */
	private static final String VERSION = "4.0.0 (2005/08/31)" ;

	private static final long serialVersionUID = 3562 ;	// 3.5.6.2 (2004/07/05)

	private transient DBTableModel	table		= null;
	private String	selValue	= null;
	private String	defaultVal	= null;
	// 4.0.0.0 (2007/10/10) dbid の初期値を、"DEFAULT" から null に変更
//	private String	dbid		= "DEFAULT";
	private String	dbid		= null;
	private String	sql			= null;
	private String	separator	= " ";		// 項目区切り文字
	private boolean	quotCheck	= HybsSystem.sysBool( "USE_SQL_INJECTION_CHECK" );	// 4.0.0 (2005/08/31)
	private int		classUseNo	= -1;	// 3.8.5.2 (2006/06/09) オプションに追加するクラス属性
	private int		groupUseNo	= -1;	// 3.8.5.2 (2006/06/09) キーブレイク時に追加するグループ文字
	private boolean	addKey		= false;		// 4.0.0 (2006/11/15) 項目一つのときにﾗﾍﾞﾙﾘｿｰｽ表示時にキーも付加する。
	private int		titleUseNo		= -1;	// 4.3.8.0 (2009/08/01) オプションのtitle属性
	private boolean	xssCheck	= HybsSystem.sysBool( "USE_XSS_CHECK" );	// 5.0.0.2 (2009/09/15)

	/**
	 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
	 *
	 * @return  int
	 */
	@Override
	public int doStartTag() {
		return( EVAL_BODY_BUFFERED );	// Body を評価する。（ extends BodyTagSupport 時）
	}

	/**
	 * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
	 *
	 * @og.rev 3.1.1.0 (2003/03/28) ボディの内容を取得する処理を、CommonTagSupport で行う。
	 * @og.rev 3.6.0.8 (2004/11/19) エラー発生時に確実にリリースされるように try finally 追加
	 * @og.rev 3.7.1.0 (2005/04/26) DBTableModel がすでにセットされている場合は、SQL処理不要。
	 * @og.rev 4.0.0 (2005/01/31) lang ⇒ ResourceManager へ変更
	 * @og.rev 4.0.0 (2005/08/31) useQuotCheck() によるＳＱＬインジェクション対策
	 * @og.rev 3.8.6.3 (2006/11/30) SQL 文の前後のスペースを取り除きます。
	 * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfo オブジェクトを設定
	 * @og.rev 4.3.6.0 (2009/04/01) EventColumn対応
	 * @og.rev 5.0.0.5 (2009/08/28) XSS対策
	 *
	 * @return  int
	 */
	@Override
	public int doAfterBody() {
		// 3.7.1.0 (2005/04/26) DBTableModel がすでにセットされている場合は、SQL処理不要。
		if( table != null ) { return(SKIP_BODY); }

		// 4.0.0 (2005/08/31) useQuotCheck() によるＳＱＬインジェクション対策
		useQuotCheck( quotCheck );
		// 5.0.0.2 (2009/09/15) XSS対策
		useXssCheck( xssCheck );
		
		sql = getBodyString().trim();
		String rawsql = getBodyRawString().trim(); // 4.3.6.0 生のSQLを保持
		
		// 4.3.6.0 (2009/04/01) セッションへのSQL文登録
		String[] selectVals = getEventColumn(); // 親タグからイベントカラム設定を取る
		if( selectVals[0] != null && selectVals[0].length() > 0 ){
			addEventColumnSQL( selectVals[1], rawsql );
		}

		Query query = QueryFactory.newInstance();		// 4.0.0 (2005/01/31)
		try {
			query.setConnectionID( dbid );
			query.setResourceManager( getResource() );	// 4.0.0 (2005/01/31)

			query.setStatement( sql );
			query.setApplicationInfo( getApplicationInfo() );	// 3.8.7.0 (2006/12/15)
			query.execute();

			table = query.getDBTableModel();

			// 4.0.0 (2005/11/30) 検索結果の件数を、"DB.COUNT" キーでリクエストにセットする。
		}
		finally {
			if( query != null ) { query.close(); }
			QueryFactory.close( query );
		}
		return(SKIP_BODY);
	}

	/**
	 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
	 *
	 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
	 * @og.rev 3.3.2.0 (2003/07/07) defaultVal 属性の追加。
	 * @og.rev 3.5.4.0 (2003/11/25) selVal 属性を追加。
	 * @og.rev 5.0.2.0 (2009/11/01) 複数パラメーターの選択に対応
	 *
	 * @return  int
	 */
	@Override
	public int doEndTag() {
		debugPrint();		// 4.0.0 (2005/02/28)
		SelectTag select = (SelectTag)findAncestorWithClass( this,SelectTag.class );
		if( select == null ) {
			String errMsg = "このタグは、SelectTag のBODY に記述する必要があります。";
			throw new HybsSystemException( errMsg );
		}
		String selVal = nval( select.getValue(),defaultVal );	// 3.5.4.0 (2003/11/25)
//		selValue = nval( selValue,selVal );						// 3.5.4.0 (2003/11/25)
		selValue = "|" + nval( selValue,selVal ) + "|";			// 5.0.2.0 (2009/11/01)
		makeLabel( select );

		return(EVAL_PAGE);
	}

	/**
	 * タグリブオブジェクトをリリースします。
	 * キャッシュされて再利用されるので、フィールドの初期設定を行います。
	 *
	 * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加
	 * @og.rev 3.0.1.0 (2003/03/03) セパレーターを指定できる様に変更。
	 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
	 * @og.rev 3.3.2.0 (2003/07/07) defaultVal 属性の追加。
	 * @og.rev 3.8.5.2 (2006/06/09) classUseNo , groupUseNo 属性の追加。
	 * @og.rev 4.0.0 (2005/08/31) quotCheck , addKey 属性の追加
	 * @og.rev 4.0.0.0 (2007/10/10) dbid の初期値を、"DEFAULT" から null に変更
	 *
	 */
	@Override
	protected void release2() {
		super.release2();
		table		= null;
		selValue	= null;
		defaultVal	= null;
//		dbid		= "DEFAULT";
		dbid		= null;
		sql			= null;
		separator	= " ";
		classUseNo	= -1;	// 3.8.5.2 (2006/06/09) オプションに追加するクラス属性
		groupUseNo	= -1;	// 3.8.5.2 (2006/06/09) キーブレイク時に追加するグループ文字
		quotCheck	= HybsSystem.sysBool( "USE_SQL_INJECTION_CHECK" );	// 4.0.0 (2005/08/31)
		addKey		= false;		// 4.0.0 (2006/11/15) 項目一つのときにﾗﾍﾞﾙﾘｿｰｽ表示時にキーも付加する。
		titleUseNo		= -1;
		xssCheck	= HybsSystem.sysBool( "USE_XSS_CHECK" );	// 5.0.0.2 (2009/09/15)
	}

	/**
	 * DBTableModelをセットします。
	 *
	 * サブクラスより、DBTableModelをセットするのに使います。
	 *
	 * @og.rev 3.7.1.0 (2005/04/26) 新規追加
	 *
	 * @param   table DBTableModel
	 */
	protected void setTableModel( final DBTableModel table ) {
		this.table = table ;
	}

	/**
	 * オプションを作成します。
	 *
	 * DBTableModel の１番目の値を "value" に、それ以降を文字列を連結させて
	 * BODY属性 に登録するOptionを作成します。
	 *
	 * @og.rev 3.0.1.0 (2003/03/03) 『SELECT KEY FROM TABLE ･･･』形式の場合は、LABEL に KEY を使用。
	 * @og.rev 3.8.0.9 (2005/10/17) 複数選択可能時に全選択を設定する。
	 * @og.rev 3.8.5.2 (2006/06/09) classUseNo 属性と groupUseNo 属性を追加
	 * @og.rev 3.8.9.2 (2007/07/28) グループと、クラスの設定方法のバグ修正
	 * @og.rev 4.3.8.0 (2009/08/01) titleUseNo属性追加
	 * @og.rev 5.0.2.0 (2009/11/01) 複数パラメーターの選択に対応
	 *
	 * @param   select SelectTag
	 */
	private void makeLabel( final SelectTag select ) {
		boolean multipleAll = select.isMultipleAll();	// 3.8.0.9 (2005/10/17)
		int rowCnt = table.getRowCount();		// 3.5.5.7 (2004/05/10)

		String bkGroupKey = "";
		String grpLabel ;
		for( int row=0; row<rowCnt; row++ ) {
			// 3.8.5.2 (2006/06/09) groupUseNo 属性
			if( groupUseNo >= 0 ) {
				String groupKey = table.getValue( row,groupUseNo );
				grpLabel = getRendererValue( row,groupUseNo );
				if( !bkGroupKey.equals( groupKey ) ) {		// キーブレイク
					// 3.8.9.2 (2007/07/28) グループと、クラスの設定方法のバグ修正
//					bkGroupKey = groupKey;
//					if( row != 0 ) { select.addOption( "</optgroup>" ); }
//					select.addOption( "<optgroup label=\"" + grpLabel + "\">" );

					if( ! "".equals( bkGroupKey ) ) {
						select.addOption( "</optgroup>" );
					}
					if( ! "".equals( groupKey ) ) {
						select.addOption( "<optgroup label=\"" + grpLabel + "\">" );
					}
					bkGroupKey = groupKey;
				}
			}

			Attributes attri = new Attributes();
			String value = table.getValue( row,0 );
			attri.set( "value", value );

			// 5.0.2.0 (2009/11/01)
//			if( ( selValue != null && selValue.equals( value ) ) || multipleAll ) {
			if( ( selValue != null && selValue.length() > 0 && selValue.indexOf( "|" + value + "|" ) >= 0 ) || multipleAll ) {
				attri.set( "selected", "selected" );
			}

			// 3.8.5.2 (2006/06/09) classUseNo 属性
			if( classUseNo >= 0 ) {
				attri.add( "class", table.getValue( row,classUseNo ) );
			}

			StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
			boolean titleFlg = false; // 4.3.8.0 (2009/08/01) title属性を付けるかどうか
			if( table.getColumnCount() == 1 ) {
				// 項目が一つの queryOption では、ラベルリソースが使用されます。
				if( addKey ) { buf.append( value ).append( ":" ); }
				buf.append( getResource().getLabel( value ) );
				
				// 4.3.8.0 (2009/08/01) titleUseNo 属性 セットされている場合かつラベルと異なる場合はtitle属性に追加
				if( titleUseNo >= 0 && !getResource().getLabel( value ).equals( table.getValue( row,titleUseNo ) )) {
					titleFlg = true;
				}
			}
			else {
	//			if( groupUseNo >= 0 ) {
	//				buf.append( grpLabel );
	//				buf.append( separator );
	//			}
				String label = getRendererValue( row,1 );
				buf.append( label );
	//			attri.set( "label", label );
				for( int clm=2; clm<table.getColumnCount(); clm++ ) {
					// 4.3.8.0 (2009/08/01) titleUseNo追加
					// if( clm == groupUseNo || clm == classUseNo ) { continue; }
					if( clm == groupUseNo || clm == classUseNo || clm==titleUseNo) { continue; }
					buf.append( separator );
					buf.append( getRendererValue( row,clm ) );
				}
				
				// 4.3.8.0 (2009/08/01) titleUseNo 属性 セットされている場合かつラベルと異なる場合はtitle属性に追加
				if( titleUseNo >= 0 && !label.equals( table.getValue( row,titleUseNo ) )) {
					titleFlg = true;
				}
			}
			
			// 4.3.7.2 (2009/06/22) タイトル属性セット
			if( titleFlg ){
				attri.add( "title", table.getValue( row,titleUseNo ) );
			}
			
			attri.set( "body", buf.toString() );
			select.addOption( XHTMLTag.option( attri ) );
		}
//		if( groupUseNo >= 0 && "".equals( bkGroupKey ) ) {
		if( groupUseNo >= 0 && ! "".equals( bkGroupKey ) ) {	// 3.8.9.2 (2007/07/28)
			select.addOption( "</optgroup>" );
		}
	}

	/**
	 * 【TAG】Optionの初期値で選ばれる値を指定します。
	 *
	 * @og.tag Optionの初期値で選ばれる値を指定します。
	 *
	 * @param   val Optionの初期値で選ばれる値
	 */
	public void setValue( final String val ) {
		selValue = getRequestParameter( val );
	}

	/**
	 * 【TAG】value値がNULLの場合に使用される初期値を設定します。
	 *
	 * @og.tag
	 * value値がNULLの場合に、この初期値をセットします。
	 *
	 * @og.rev 3.3.2.0 (2003/07/07) defaultVal 属性の追加。(新規作成)
	 *
	 * @param	val 初期値
	 */
	public void setDefaultVal( final String val ) {
		defaultVal = getRequestParameter( val );
	}

	/**
	 * 【TAG】複数のラベルを合成するときに使用する項目区切り文字をセットします(初期値:スペース)。
	 *
	 * @og.tag
	 * 初期値は、スペースです。
	 *
	 * @og.rev 3.0.1.0 (2003/03/03) セパレーターを指定できる様に変更。
	 *
	 * @param   sep 項目区切り文字
	 */
	public void setSeparator( final String sep ) {
		separator = nval( getRequestParameter( sep ),separator );
	}

	/**
	 * 【TAG】オプションに追加する class 属性の カラム番号を指定します。
	 *
	 * @og.tag
	 * オプションは、データベースを検索して作成されますが、そのSQL文のカラム情報を
	 * 使用して オプションに class 属性を追加します。
	 * 各オプションに色をつける場合は、この class 属性に対応する CSS ファイルを用意します。
	 * ここでは、class 属性に使用する SQL文の カラム番号( 先頭が 0 ) を指定します。
	 * 通常、カラム番号=0 は キー情報、=1 はラベル情報 です。2 か 3 を指定します。
	 * 初期値は、使用しない(-1)です。
	 *
	 * @og.rev 3.8.5.2 (2006/06/09) 新規追加
	 *
	 * @param   no オプションに追加するクラス属性
	 */
	public void setClassUseNo( final String no ) {
		classUseNo = nval( getRequestParameter( no ),classUseNo );
		if( classUseNo == 0 || classUseNo == 1 ) {
			String errMsg = "通常、カラム番号=0 は キー情報、=1 はラベル情報 です。2 か 3 を指定して下さい。";
			throw new HybsSystemException( errMsg );
		}
	}

	/**
	 * 【TAG】オプションのグループ化を行うカラム番号を指定します。
	 *
	 * @og.tag
	 * オプションは、データベースを検索して作成されますが、そのSQL文のカラム情報を
	 * 使用して オプションをグループ化します。グループ化は optgroup要素をブレイク時に
	 * 出力する事で対応します。
	 * ここでは、グループ化に使用する SQL文の カラム番号( 先頭が 0 ) を指定します。
	 * 通常、カラム番号=0 は キー情報、=1 はラベル情報 です。2 か 3 を指定します。
	 * 初期値は、使用しない(-1)です。
	 *
	 * @og.rev 3.8.5.2 (2006/06/09) 新規追加
	 *
	 * @param   no キーブレイク時に追加するグループ文字
	 */
	public void setGroupUseNo( final String no ) {
		groupUseNo = nval( getRequestParameter( no ),groupUseNo );
		if( groupUseNo == 0 || groupUseNo == 1 ) {
			String errMsg = "通常、カラム番号=0 は キー情報、=1 はラベル情報 です。2 か 3 を指定して下さい。";
			throw new HybsSystemException( errMsg );
		}
	}

	/**
	 * 【TAG】リクエスト情報の クォーティション(') 存在チェックを実施するかどうか(true/false)を設定します(初期値:USE_SQL_INJECTION_CHECK)。
	 *
	 * @og.tag
	 * ＳＱＬインジェクション対策の一つとして、暫定的ではありますが、SQLのパラメータに
	 * 渡す文字列にクォーティション(') を許さない設定にすれば、ある程度は防止できます。
	 * 数字タイプの引数には、 or 5=5 などのクォーティションを使用しないコードを埋めても、
	 * 数字チェックで検出可能です。文字タイプの場合は、必ず (')をはずして、
	 * ' or 'A' like 'A のような形式になる為、(')チェックだけでも有効です。
	 * (') が含まれていたエラーにする（true)／かノーチェックか(false)を指定します。
	 * 初期値は、SystemData#USE_SQL_INJECTION_CHECK です。
	 *
	 * @og.rev 4.0.0 (2005/08/31) 新規追加
	 *
	 * @param   flag クォーティションチェックする ("true")／しない (それ以外)
	 */
	public void setQuotCheck( final String flag ) {
		quotCheck = nval( getRequestParameter( flag ),quotCheck );
	}

	/**
	 * 【TAG】(通常は使いません)Queryオブジェクトを作成する時のDB接続IDを指定します。
	 *
	 * @og.tag
	 * Queryオブジェクトを作成する時のDB接続IDを指定します。
	 * これは、システムリソースで、DEFAULT_DB_URL 等で指定している データベース接続先
	 * 情報に、XX_DB_URL を定義することで、 dbid="XX" とすると、この 接続先を使用して
	 * データベースにアクセスできます。
	 *
	 * @param	id データベース接続ID
	 */
	public void setDbid( final String id ) {
		dbid = nval( getRequestParameter( id ),dbid );
	}

	/**
	 * 【TAG】項目が一つだけの場合のﾗﾍﾞﾙﾘｿｰｽに、キー情報を追加するかどうかを指定します(初期値:false)。
	 *
	 * @og.tag
	 * Queryオブジェクトの項目が一つの場合、ﾗﾍﾞﾙ部には、ﾗﾍﾞﾙﾘｿｰｽを使用します。
	 * この時、ﾗﾍﾞﾙ無しの場合は、キーが表示されますが、ﾗﾍﾞﾙありの場合は、キーは表示されず
	 * ﾗﾍﾞﾙのみ表示されます。
	 * 都合によっては、キーも表示したい場合がありますので、その様なケースでは、
	 * addKey = "true を設定する事で、キー:ﾗﾍﾞﾙ のセットをﾗﾍﾞﾙとして扱います。
	 * 初期値はfalse(キーは付加しない)です。
	 *
	 * @param	id データベース接続ID
	 */
	public void setAddKey( final String id ) {
		addKey = nval( getRequestParameter( id ),addKey );
	}
	
	/**
	 * 【TAG】リクエスト情報の HTMLTag開始/終了文字(&gt;&lt;) 存在チェックを実施するかどうか(true/false)を設定します(初期値:USE_XSS_CHECK)。
	 *
	 * @og.tag
	 * クロスサイトスクリプティング(XSS)対策の一環としてless/greater than signについてのチェックを行います。
	 * (&gt;&lt;) が含まれていたエラーにする（true)／かノーチェックか(false)を指定します。
	 * 初期値は、SystemData#USE_XMLLTAG_CHECK です。
	 *
	 * @og.rev 5.0.0.2 (2009/09/15) 新規追加
	 *
	 * @param flag boolean XSSチェックする (true)／しない (false)
	 */
	public void setXssCheck( final String flag ) {
		xssCheck = nval( getRequestParameter( flag ),xssCheck );
	}

	/**
	 * row行，colum列 のデータの値を返します。
	 *
	 * これは、データの値そのものではなく、その値のラベル文字を返します。
	 *
	 * @param   row int
	 * @param   column int
	 * @return  row行，colum列 のデータの値
	 */
	private String getRendererValue( final int row,final int column ) {
		String val = table.getValue( row,column );
		DBColumn clm = table.getDBColumn( column );
		return clm.getRendererValue( val );
	}

	/**
	 * 【TAG】オプションに追加する title 属性の カラム番号を指定します。
	 *
	 * @og.tag
	 * オプションは、データベースを検索して作成されますが、そのSQL文のカラム情報を
	 * 使用して オプションに title 属性を追加します。
	 * title属性はマウスオーバー時にツールチップとして表示されるため、
	 * プルダウンの横幅を短くしたい場合に有効です。
	 * 通常、カラム番号=0 は キー情報、=1 はラベル情報 です。2 か 3 を指定します。
	 * 初期値は、使用しない(-1)です。
	 *
	 * @og.rev 4.3.8.0 (2009/08/01) 新規追加
	 *
	 * @param   no オプションに追加するtitle属性
	 */
	public void setTitleUseNo( final String no ) {
		titleUseNo = nval( getRequestParameter( no ),titleUseNo );
		if( titleUseNo == 0 || titleUseNo == 1 ) {
			String errMsg = "通常、カラム番号=0 は キー情報、=1 はラベル情報 です。2 か 3 を指定して下さい。";
			throw new HybsSystemException( errMsg );
		}
	}

	/**
	 * シリアライズ用のカスタムシリアライズ書き込みメソッド
	 *
	 * @og.rev 4.0.0 (2006/09/31) 新規追加
	 * @serialData
	 *
	 * @param strm ObjectOutputStream
	 */
	private void writeObject( final ObjectOutputStream strm ) throws IOException {
		strm.defaultWriteObject();
	}

	/**
	 * シリアライズ用のカスタムシリアライズ読み込みメソッド
	 *
	 * ここでは、transient 宣言された内部変数の内、初期化が必要なフィールドのみ設定します。
	 *
	 * @og.rev 4.0.0 (2006/09/31) 新規追加
	 * @serialData
	 *
	 * @param strm ObjectInputStream
	 * @see #release2()
	 */
	private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException {
		strm.defaultReadObject();
	}

	/**
	 * 親のog:selectタグのnameとeventColumn設定を返します。
	 * 
	 * @og.rev 4.3.6.0 (2009/04/01)
	 *
	 */
	private String[] getEventColumn(){
		SelectTag seltag = (SelectTag)findAncestorWithClass(this,SelectTag.class);
		String[] selectVal = new String[2];
		selectVal[0] = seltag.getEventColumn();
		selectVal[1] = seltag.get("name");
		return selectVal;
	}

	/**
	 * このオブジェクトの文字列表現を返します。
	 * 基本的にデバッグ目的に使用します。
	 *
	 * @return このクラスの文字列表現
	 */
	public String toString() {
		return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
				.println( "VERSION"		,VERSION	)
				.println( "selValue"	,selValue	)
				.println( "defaultVal"	,defaultVal	)
				.println( "dbid"		,dbid		)
				.println( "sql"			,sql		)
				.println( "separator"	,separator	)
				.println( "quotCheck"	,quotCheck	)
				.println( "Other..."	,getAttributes().getAttribute() )
				.fixForm().toString() ;
	}
}
