001/*
002 * Copyright (c) 2009 The openGion Project.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013 * either express or implied. See the License for the specific language
014 * governing permissions and limitations under the License.
015 */
016package org.opengion.hayabusa.taglib;
017
018import org.opengion.hayabusa.common.HybsSystem;
019import org.opengion.hayabusa.common.HybsSystemException;
020import org.opengion.hayabusa.db.DBTableModel;
021import org.opengion.hayabusa.db.DBColumn;
022import org.opengion.hayabusa.db.Query;
023import org.opengion.hayabusa.db.QueryFactory;
024import org.opengion.fukurou.util.XHTMLTag;
025import org.opengion.fukurou.util.Attributes;
026import org.opengion.fukurou.db.Transaction;
027import org.opengion.fukurou.db.TransactionReal;
028
029import static org.opengion.fukurou.util.StringUtil.nval ;
030
031import java.io.ObjectOutputStream;
032import java.io.ObjectInputStream;
033import java.io.IOException;
034
035/**
036 * プルダウンメニューの選択項目をSELECT文の結果から作成するタグです。
037 *
038 * 基本的には、queryタグと同じ使い方をします。
039 * このオブジェクトに、 queryId を与えることにより、queryId に対応した Queryオブジェクト
040 * (のサブクラスのオブジェクト)が作成されます。
041 * ここで指定するSELECT文は、『SELECT KEY、LABEL1、LABEL2、・・・ FROM TABLE ・・・』形式 を
042 * している必要があります。特別なケースとして、『SELECT KEY FROM TABLE ・・・』形式の場合は、
043 * LABEL に KEY が 使用されます。
044 * SystemData の USE_SQL_INJECTION_CHECK が true か、quotCheck 属性が true の場合は、
045 * SQLインジェクション対策用のクォーティションチェックを行います。リクエスト引数に
046 * クォーティション(')が含まれると、エラーになります。
047 * 同様にUSE_XSS_CHECKがtrueか、xssCheck属性がtrueの場合は、
048 * クロスサイトススクリプティング(XSS)対策のためless/greater than signのチェックを行います。
049 *
050 * ※ このタグは、Transaction タグの対象です。
051 *
052 * @og.formSample
053 * ●形式:
054 *     <og:queryOption >
055 *          SELECT文 
056 *     </og:queryOption >
057 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{@XXXX} を解析します)
058 *
059 * ●Tag定義:
060 *   <og:queryOption
061 *       value              【TAG】Optionの初期値で選ばれる値を指定します
062 *       separator          【TAG】複数のラベルを合成するときに使用する項目区切り文字をセットします(初期値:スペース)
063 *       defaultVal         【TAG】value値がNULLの場合に使用される初期値を設定します
064 *       language           【TAG】タグ内部で使用する言語コード[ja/en/zh/…]を指定します
065 *       quotCheck          【TAG】リクエスト情報の クォーティション(') 存在チェックを実施するかどうか[true/false]を設定します (初期値:USE_SQL_INJECTION_CHECK[=true])
066 *       dbid               【TAG】(通常は使いません)Queryオブジェクトを作成する時のDB接続IDを指定します
067 *       addKey             【TAG】項目が一つだけの場合のラベルリソースに、キー情報を追加するかどうかを指定します(初期値:false)
068 *       classUseNo         【TAG】オプションに追加する class 属性の カラム番号を指定します
069 *       groupUseNo         【TAG】オプションのグループ化を行うカラム番号を指定します
070 *       titleUseNo         【TAG】オプションに追加する title 属性の カラム番号を指定します
071 *       xssCheck           【TAG】リクエスト情報の HTMLTag開始/終了文字(><) 存在チェックを実施するかどうか[true/false]を設定します (初期値:USE_XSS_CHECK[=true])
072 *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null)
073 *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null)
074 *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:true)
075 *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:true)
076 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
077 *   >   ... Body ...
078 *   </og:queryOption>
079 *
080 * ●使用例
081 *     <og:select name="CDC" >
082 *         <og:queryOption>
083 *                 select NOSYN,NOSYN,NMSYN from DB01 ORDER BY 1
084 *         </og:queryOption>
085 *     </og:select>
086 *
087 *     <og:select name="CDC" >                選択項目の一番上に空白をセットしたいときoptionタグを組合せることも可能です。
088 *         <og:option lbl="" />               初期値を設定したいときはvalue属性を使います。
089 *         <og:queryOption value="61200" separator=":" >
090 *                 select CDBK,CDBK,NMBK from DB02 ORDER BY 1
091 *         </og:queryOption>
092 *     </og:select>
093 *
094 * @og.group 選択データ制御
095 *
096 * @version  4.0
097 * @author   Kazuhiko Hasegawa
098 * @since    JDK5.0,
099 */
100public class QueryOptionTag extends CommonTagSupport {
101        //* このプログラムのVERSION文字列を設定します。   {@value} */
102        private static final String VERSION = "5.7.1.0 (2013/12/06)" ;
103
104        private static final long serialVersionUID = 571020131206L ;
105
106        private transient DBTableModel  table           = null;
107        private String  selValue        = null;
108        private String  defaultVal      = null;
109        // 4.0.0.0 (2007/10/10) dbid の初期値を、"DEFAULT" から null に変更
110//      private String  dbid            = "DEFAULT";
111        private String  dbid            = null;
112        private String  sql                     = null;
113        private String  separator       = " ";          // 項目区切り文字
114        private boolean quotCheck       = HybsSystem.sysBool( "USE_SQL_INJECTION_CHECK" );      // 4.0.0 (2005/08/31)
115        private int             classUseNo      = -1;   // 3.8.5.2 (2006/06/09) オプションに追加するクラス属性
116        private int             groupUseNo      = -1;   // 3.8.5.2 (2006/06/09) キーブレイク時に追加するグループ文字
117        private boolean addKey          = false;                // 4.0.0 (2006/11/15) 項目一つのときにラベルリソース表示時にキーも付加する。
118        private int             titleUseNo              = -1;   // 4.3.8.0 (2009/08/01) オプションのtitle属性
119        private boolean xssCheck        = HybsSystem.sysBool( "USE_XSS_CHECK" );        // 5.0.0.2 (2009/09/15)
120        private String  rawSql          = null; // 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
121
122        /**
123         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
124         *
125         * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
126         *
127         * @return      後続処理の指示( EVAL_BODY_BUFFERED )
128         */
129        @Override
130        public int doStartTag() {
131                // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
132                if( useTag() ) {
133                        return( EVAL_BODY_BUFFERED );   // Body を評価する。( extends BodyTagSupport 時)
134                }
135                return ( SKIP_BODY );                           // Body を評価しない
136        }
137
138        /**
139         * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
140         *
141         * @og.rev 3.1.1.0 (2003/03/28) ボディの内容を取得する処理を、CommonTagSupport で行う。
142         * @og.rev 3.6.0.8 (2004/11/19) エラー発生時に確実にリリースされるように try finally 追加
143         * @og.rev 3.7.1.0 (2005/04/26) DBTableModel がすでにセットされている場合は、SQL処理不要。
144         * @og.rev 4.0.0.0 (2005/01/31) lang ⇒ ResourceManager へ変更
145         * @og.rev 4.0.0.0 (2005/08/31) useQuotCheck() によるSQLインジェクション対策
146         * @og.rev 3.8.6.3 (2006/11/30) SQL 文の前後のスペースを取り除きます。
147         * @og.rev 3.8.7.0 (2006/12/15) アクセスログ取得の為,ApplicationInfoオブジェクトを設定
148         * @og.rev 4.3.6.0 (2009/04/01) EventColumn対応
149         * @og.rev 5.0.0.5 (2009/08/28) XSS対策
150         * @og.rev 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
151         * @og.rev 5.1.9.0 (2010/08/01) TransactionTag 対応。上位に TransactionTag があれば、そこからConnection をもらう。
152         * @og.rev 5.3.7.0 (2011/07/01) TransactionReal の引数変更
153         * @og.rev 5.3.8.0 (2011/08/01) Transaction発生箇所でclose()
154         *
155         * @return      後続処理の指示(SKIP_BODY)
156         */
157        @Override
158        public int doAfterBody() {
159                // 3.7.1.0 (2005/04/26) DBTableModel がすでにセットされている場合は、SQL処理不要。
160                if( table != null ) { return(SKIP_BODY); }
161
162                // 4.0.0 (2005/08/31) useQuotCheck() によるSQLインジェクション対策
163                useQuotCheck( quotCheck );
164                // 5.0.0.2 (2009/09/15) XSS対策
165                useXssCheck( xssCheck );
166
167                sql = getBodyString().trim();
168//              String rawsql = getBodyRawString().trim(); // 4.3.6.0 生のSQLを保持
169                rawSql = getBodyRawString().trim();
170
171                // 4.3.6.0 (2009/04/01) セッションへのSQL文登録
172                // 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
173//              String[] selectVals = getEventColumn(); // 親タグからイベントカラム設定を取る
174//              if( selectVals[0] != null && selectVals[0].length() > 0 ){
175//                      addEventColumnSQL( selectVals[1], rawsql );
176//              }
177
178                Query query = QueryFactory.newInstance();               // 4.0.0 (2005/01/31)
179                Transaction tran = null;
180                try {
181                        // 5.1.9.0 (2010/08/01) TransactionTag 対応
182//                      final Transaction tran ;
183                        TransactionTag tranTag = (TransactionTag)findAncestorWithClass( this,TransactionTag.class );
184                        if( tranTag == null ) {
185//                              tran = new TransactionReal( dbid,getApplicationInfo() );
186                                tran = new TransactionReal( getApplicationInfo() );             // 5.3.7.0 (2011/07/01) 引数変更
187                        }
188                        else {
189                                tran = tranTag.getTransaction();
190                        }
191                        query.setTransaction( dbid,tran );      // 5.1.9.0 (2010/08/01) TransactionTag 対応
192
193//                      query.setConnectionID( dbid );
194                        query.setResourceManager( getResource() );      // 4.0.0 (2005/01/31)
195
196                        query.setStatement( sql );
197//                      query.setApplicationInfo( getApplicationInfo() );       // 3.8.7.0 (2006/12/15)
198                        query.execute();
199
200                        table = query.getDBTableModel();
201
202                        // 4.0.0 (2005/11/30) 検索結果の件数を、"DB.COUNT" キーでリクエストにセットする。
203                }
204                finally {
205//                      if( query != null ) { query.close(); }
206                        QueryFactory.close( query );
207                        if( tran != null ) { tran.close(); }            // 5.3.8.0 (2011/08/01) Transaction発生箇所でclose()
208                }
209                return(SKIP_BODY);
210        }
211
212        /**
213         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
214         *
215         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
216         * @og.rev 3.3.2.0 (2003/07/07) defaultVal 属性の追加。
217         * @og.rev 3.5.4.0 (2003/11/25) selVal 属性を追加。
218         * @og.rev 5.0.2.0 (2009/11/01) 複数パラメーターの選択に対応
219         * @og.rev 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
220         * @og.rev 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
221         * @og.rev 5.7.1.0 (2013/12/06) SelectTag ⇒ OptionAncestorIF に変更して、DatalistTag にも対応。
222         *
223         * @return      後続処理の指示
224         */
225        @Override
226        public int doEndTag() {
227                debugPrint();           // 4.0.0 (2005/02/28)
228                // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
229                if( useTag() ) {
230//                      SelectTag select = (SelectTag)findAncestorWithClass( this,SelectTag.class );
231                        OptionAncestorIF select = (OptionAncestorIF)findAncestorWithClass( this,OptionAncestorIF.class );
232                        if( select == null ) {
233//                              String errMsg = "このタグは、SelectTag のBODY に記述する必要があります。";
234                                String errMsg = "<b>" + getTagName() + "タグは、SelectTag または、DatalistTag のBODY に記述する必要があります。</b>";
235                                throw new HybsSystemException( errMsg );
236                        }
237                        String selVal = nval( select.getValue(),defaultVal );   // 3.5.4.0 (2003/11/25)
238        //              selValue = nval( selValue,selVal );                                             // 3.5.4.0 (2003/11/25)
239                        selValue = "|" + nval( selValue,selVal ) + "|";                 // 5.0.2.0 (2009/11/01)
240                        makeLabel( select );
241
242                        // 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
243                        select.setRawParam( rawSql );
244                }
245                return(EVAL_PAGE);
246        }
247
248        /**
249         * タグリブオブジェクトをリリースします。
250         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
251         *
252         * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加
253         * @og.rev 3.0.1.0 (2003/03/03) セパレーターを指定できる様に変更。
254         * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。
255         * @og.rev 3.3.2.0 (2003/07/07) defaultVal 属性の追加。
256         * @og.rev 3.8.5.2 (2006/06/09) classUseNo , groupUseNo 属性の追加。
257         * @og.rev 4.0.0.0 (2005/08/31) quotCheck , addKey 属性の追加
258         * @og.rev 4.0.0.0 (2007/10/10) dbid の初期値を、"DEFAULT" から null に変更
259         * @og.rev 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
260         *
261         */
262        @Override
263        protected void release2() {
264                super.release2();
265                table           = null;
266                selValue        = null;
267                defaultVal      = null;
268//              dbid            = "DEFAULT";
269                dbid            = null;
270                sql                     = null;
271                separator       = " ";
272                classUseNo      = -1;   // 3.8.5.2 (2006/06/09) オプションに追加するクラス属性
273                groupUseNo      = -1;   // 3.8.5.2 (2006/06/09) キーブレイク時に追加するグループ文字
274                quotCheck       = HybsSystem.sysBool( "USE_SQL_INJECTION_CHECK" );      // 4.0.0 (2005/08/31)
275                addKey          = false;                // 4.0.0 (2006/11/15) 項目一つのときにラベルリソース表示時にキーも付加する。
276                titleUseNo              = -1;
277                xssCheck        = HybsSystem.sysBool( "USE_XSS_CHECK" );        // 5.0.0.2 (2009/09/15)
278                rawSql          = null; // 5.1.7.0 (2010/06/01) 動的プルダウン実装見直し
279        }
280
281        /**
282         * DBTableModelをセットします。
283         *
284         * サブクラスより、DBTableModelをセットするのに使います。
285         *
286         * @og.rev 3.7.1.0 (2005/04/26) 新規追加
287         *
288         * @param       table   DBTableModelオブジェクト
289         */
290        protected void setTableModel( final DBTableModel table ) {
291                this.table = table ;
292        }
293
294        /**
295         * オプションを作成します。
296         *
297         * DBTableModel の1番目の値を "value" に、それ以降を文字列を連結させて
298         * BODY属性 に登録するOptionを作成します。
299         *
300         * @og.rev 3.0.1.0 (2003/03/03) 『SELECT KEY FROM TABLE ・・・』形式の場合は、LABEL に KEY を使用。
301         * @og.rev 3.8.0.9 (2005/10/17) 複数選択可能時に全選択を設定する。
302         * @og.rev 3.8.5.2 (2006/06/09) classUseNo 属性と groupUseNo 属性を追加
303         * @og.rev 3.8.9.2 (2007/07/28) グループと、クラスの設定方法のバグ修正
304         * @og.rev 4.3.8.0 (2009/08/01) titleUseNo属性追加
305         * @og.rev 5.0.2.0 (2009/11/01) 複数パラメーターの選択に対応
306         * @og.rev 5.7.1.0 (2013/12/06) SelectTag ⇒ OptionAncestorIF に変更して、DatalistTag にも対応。
307         *
308         * @param   select SelectTagオブジェクト
309         */
310//      private void makeLabel( final SelectTag select ) {
311        private void makeLabel( final OptionAncestorIF select ) {
312                boolean multipleAll = select.isMultipleAll();   // 3.8.0.9 (2005/10/17)
313                int rowCnt = table.getRowCount();               // 3.5.5.7 (2004/05/10)
314
315                String bkGroupKey = "";
316                String grpLabel ;
317                for( int row=0; row<rowCnt; row++ ) {
318                        // 3.8.5.2 (2006/06/09) groupUseNo 属性
319                        if( groupUseNo >= 0 ) {
320                                String groupKey = table.getValue( row,groupUseNo );
321                                grpLabel = getRendererValue( row,groupUseNo );
322                                if( !bkGroupKey.equals( groupKey ) ) {          // キーブレイク
323                                        // 3.8.9.2 (2007/07/28) グループと、クラスの設定方法のバグ修正
324//                                      bkGroupKey = groupKey;
325//                                      if( row != 0 ) { select.addOption( "</optgroup>" ); }
326//                                      select.addOption( "<optgroup label=\"" + grpLabel + "\">" );
327
328                                        if( ! "".equals( bkGroupKey ) ) {
329                                                select.addOption( "</optgroup>" );
330                                        }
331                                        if( ! "".equals( groupKey ) ) {
332                                                select.addOption( "<optgroup label=\"" + grpLabel + "\">" );
333                                        }
334                                        bkGroupKey = groupKey;
335                                }
336                        }
337
338                        Attributes attri = new Attributes();
339                        String value = table.getValue( row,0 );
340                        attri.set( "value", value );
341
342                        // 5.0.2.0 (2009/11/01)
343//                      if( ( selValue != null && selValue.equals( value ) ) || multipleAll ) {
344                        if( ( selValue != null && selValue.length() > 0 && selValue.indexOf( "|" + value + "|" ) >= 0 ) || multipleAll ) {
345                                attri.set( "selected", "selected" );
346                        }
347
348                        // 3.8.5.2 (2006/06/09) classUseNo 属性
349                        if( classUseNo >= 0 ) {
350                                attri.add( "class", table.getValue( row,classUseNo ) );
351                        }
352
353                        StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_MIDDLE );
354                        boolean titleFlg = false; // 4.3.8.0 (2009/08/01) title属性を付けるかどうか
355                        if( table.getColumnCount() == 1 ) {
356                                // 項目が一つの queryOption では、ラベルリソースが使用されます。
357                                if( addKey ) { buf.append( value ).append( ":" ); }
358                                buf.append( getResource().getLabel( value ) );
359
360                                // 4.3.8.0 (2009/08/01) titleUseNo 属性 セットされている場合かつラベルと異なる場合はtitle属性に追加
361                                if( titleUseNo >= 0 && !getResource().getLabel( value ).equals( table.getValue( row,titleUseNo ) )) {
362                                        titleFlg = true;
363                                }
364                        }
365                        else {
366        //                      if( groupUseNo >= 0 ) {
367        //                              buf.append( grpLabel );
368        //                              buf.append( separator );
369        //                      }
370                                String label = getRendererValue( row,1 );
371                                buf.append( label );
372        //                      attri.set( "label", label );
373                                for( int clm=2; clm<table.getColumnCount(); clm++ ) {
374                                        // 4.3.8.0 (2009/08/01) titleUseNo追加
375                                        // if( clm == groupUseNo || clm == classUseNo ) { continue; }
376                                        if( clm == groupUseNo || clm == classUseNo || clm==titleUseNo) { continue; }
377                                        buf.append( separator );
378                                        buf.append( getRendererValue( row,clm ) );
379                                }
380
381                                // 4.3.8.0 (2009/08/01) titleUseNo 属性 セットされている場合かつラベルと異なる場合はtitle属性に追加
382                                if( titleUseNo >= 0 && !label.equals( table.getValue( row,titleUseNo ) )) {
383                                        titleFlg = true;
384                                }
385                        }
386
387                        // 4.3.7.2 (2009/06/22) タイトル属性セット
388                        if( titleFlg ){
389                                attri.add( "title", table.getValue( row,titleUseNo ) );
390                        }
391
392                        attri.set( "body", buf.toString() );
393                        select.addOption( XHTMLTag.option( attri ) );
394                }
395//              if( groupUseNo >= 0 && "".equals( bkGroupKey ) ) {
396                if( groupUseNo >= 0 && ! "".equals( bkGroupKey ) ) { // 3.8.9.2 (2007/07/28)
397                        select.addOption( "</optgroup>" );
398                }
399        }
400
401        /**
402         * 【TAG】Optionの初期値で選ばれる値を指定します。
403         *
404         * @og.tag Optionの初期値で選ばれる値を指定します。
405         *
406         * @param   val Optionの初期値で選ばれる値
407         */
408        public void setValue( final String val ) {
409                selValue = getRequestParameter( val );
410        }
411
412        /**
413         * 【TAG】value値がNULLの場合に使用される初期値を設定します。
414         *
415         * @og.tag
416         * value値がNULLの場合に、この初期値をセットします。
417         *
418         * @og.rev 3.3.2.0 (2003/07/07) defaultVal 属性の追加。(新規作成)
419         *
420         * @param       val 初期値
421         */
422        public void setDefaultVal( final String val ) {
423                defaultVal = getRequestParameter( val );
424        }
425
426        /**
427         * 【TAG】複数のラベルを合成するときに使用する項目区切り文字をセットします(初期値:スペース)。
428         *
429         * @og.tag
430         * 初期値は、スペースです。
431         *
432         * @og.rev 3.0.1.0 (2003/03/03) セパレーターを指定できる様に変更。
433         *
434         * @param   sep 項目区切り文字
435         */
436        public void setSeparator( final String sep ) {
437                separator = nval( getRequestParameter( sep ),separator );
438        }
439
440        /**
441         * 【TAG】オプションに追加する class 属性の カラム番号を指定します。
442         *
443         * @og.tag
444         * オプションは、データベースを検索して作成されますが、そのSQL文のカラム情報を
445         * 使用して オプションに class 属性を追加します。
446         * 各オプションに色をつける場合は、この class 属性に対応する CSS ファイルを用意します。
447         * ここでは、class 属性に使用する SQL文の カラム番号( 先頭が 0 ) を指定します。
448         * 通常、カラム番号=0 は キー情報、=1 はラベル情報 です。2 か 3 を指定します。
449         * 初期値は、使用しない(-1)です。
450         *
451         * @og.rev 3.8.5.2 (2006/06/09) 新規追加
452         *
453         * @param   no オプションに追加するクラス属性
454         */
455        public void setClassUseNo( final String no ) {
456                classUseNo = nval( getRequestParameter( no ),classUseNo );
457                if( classUseNo == 0 || classUseNo == 1 ) {
458                        String errMsg = "通常、カラム番号=0 は キー情報、=1 はラベル情報 です。2 か 3 を指定して下さい。";
459                        throw new HybsSystemException( errMsg );
460                }
461        }
462
463        /**
464         * 【TAG】オプションのグループ化を行うカラム番号を指定します。
465         *
466         * @og.tag
467         * オプションは、データベースを検索して作成されますが、そのSQL文のカラム情報を
468         * 使用して オプションをグループ化します。グループ化は optgroup要素をブレイク時に
469         * 出力する事で対応します。
470         * ここでは、グループ化に使用する SQL文の カラム番号( 先頭が 0 ) を指定します。
471         * 通常、カラム番号=0 は キー情報、=1 はラベル情報 です。2 か 3 を指定します。
472         * 初期値は、使用しない(-1)です。
473         *
474         * @og.rev 3.8.5.2 (2006/06/09) 新規追加
475         *
476         * @param   no キーブレイク時に追加するグループ文字
477         */
478        public void setGroupUseNo( final String no ) {
479                groupUseNo = nval( getRequestParameter( no ),groupUseNo );
480                if( groupUseNo == 0 || groupUseNo == 1 ) {
481                        String errMsg = "通常、カラム番号=0 は キー情報、=1 はラベル情報 です。2 か 3 を指定して下さい。";
482                        throw new HybsSystemException( errMsg );
483                }
484        }
485
486        /**
487         * 【TAG】リクエスト情報の クォーティション(') 存在チェックを実施するかどうか[true/false]を設定します
488         *              (初期値:USE_SQL_INJECTION_CHECK[={@og.value org.opengion.hayabusa.common.SystemData#USE_SQL_INJECTION_CHECK}])。
489         *
490         * @og.tag
491         * SQLインジェクション対策の一つとして、暫定的ではありますが、SQLのパラメータに
492         * 渡す文字列にクォーティション(') を許さない設定にすれば、ある程度は防止できます。
493         * 数字タイプの引数には、 or 5=5 などのクォーティションを使用しないコードを埋めても、
494         * 数字チェックで検出可能です。文字タイプの場合は、必ず (')をはずして、
495         * ' or 'A' like 'A のような形式になる為、(')チェックだけでも有効です。
496         * (') が含まれていたエラーにする(true)/かノーチェックか(false)を指定します。
497         * (初期値:システム定数のUSE_SQL_INJECTION_CHECK[={@og.value org.opengion.hayabusa.common.SystemData#USE_SQL_INJECTION_CHECK}])。
498         *
499         * @og.rev 4.0.0.0 (2005/08/31) 新規追加
500         *
501         * @param   flag クォーティションチェック [true:する/それ以外:しない]
502         * @see         org.opengion.hayabusa.common.SystemData#USE_SQL_INJECTION_CHECK
503         */
504        public void setQuotCheck( final String flag ) {
505                quotCheck = nval( getRequestParameter( flag ),quotCheck );
506        }
507
508        /**
509         * 【TAG】(通常は使いません)Queryオブジェクトを作成する時のDB接続IDを指定します。
510         *
511         * @og.tag
512         * Queryオブジェクトを作成する時のDB接続IDを指定します。
513         * これは、システムリソースで、DEFAULT_DB_URL 等で指定している データベース接続先
514         * 情報に、XX_DB_URL を定義することで、 dbid="XX" とすると、この 接続先を使用して
515         * データベースにアクセスできます。
516         *
517         * @param       id データベース接続ID
518         */
519        public void setDbid( final String id ) {
520                dbid = nval( getRequestParameter( id ),dbid );
521        }
522
523        /**
524         * 【TAG】項目が一つだけの場合のラベルリソースに、キー情報を追加するかどうかを指定します(初期値:false)。
525         *
526         * @og.tag
527         * Queryオブジェクトの項目が一つの場合、ラベル部には、ラベルリソースを使用します。
528         * この時、ラベル無しの場合は、キーが表示されますが、ラベルありの場合は、キーは表示されず
529         * ラベルのみ表示されます。
530         * 都合によっては、キーも表示したい場合がありますので、その様なケースでは、
531         * addKey = "true を設定する事で、キー:ラベル のセットをラベルとして扱います。
532         * 初期値はfalse(キーは付加しない)です。
533         *
534         * @param       id データベース接続ID
535         */
536        public void setAddKey( final String id ) {
537                addKey = nval( getRequestParameter( id ),addKey );
538        }
539
540        /**
541         * 【TAG】リクエスト情報の HTMLTag開始/終了文字(&gt;&lt;) 存在チェックを実施するかどうか[true/false]を設定します
542         *              (初期値:USE_XSS_CHECK[={@og.value org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK}])。
543         *
544         * @og.tag
545         * クロスサイトスクリプティング(XSS)対策の一環としてless/greater than signについてのチェックを行います。
546         * (&gt;&lt;) が含まれていたエラーにする(true)/かノーチェックか(false)を指定します。
547         * (初期値:システム定数のUSE_XSS_CHECK[={@og.value org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK}])。
548         *
549         * @og.rev 5.0.0.2 (2009/09/15) 新規追加
550         *
551         * @param       flag    XSSチェック [true:する/false:しない]
552         * @see         org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK
553         */
554        public void setXssCheck( final String flag ) {
555                xssCheck = nval( getRequestParameter( flag ),xssCheck );
556        }
557
558        /**
559         * row行,colum列 のデータの値を返します。
560         *
561         * これは、データの値そのものではなく、その値のラベル文字を返します。
562         *
563         * @param   row         行番号
564         * @param   column      カラム番号
565         *
566         * @return  row行,colum列 のデータの値
567         */
568        private String getRendererValue( final int row,final int column ) {
569                String val = table.getValue( row,column );
570                DBColumn clm = table.getDBColumn( column );
571                return clm.getRendererValue( val );
572        }
573
574        /**
575         * 【TAG】オプションに追加する title 属性の カラム番号を指定します。
576         *
577         * @og.tag
578         * オプションは、データベースを検索して作成されますが、そのSQL文のカラム情報を
579         * 使用して オプションに title 属性を追加します。
580         * title属性はマウスオーバー時にツールチップとして表示されるため、
581         * プルダウンの横幅を短くしたい場合に有効です。
582         * 通常、カラム番号=0 は キー情報、=1 はラベル情報 です。2 か 3 を指定します。
583         * 初期値は、使用しない(-1)です。
584         *
585         * @og.rev 4.3.8.0 (2009/08/01) 新規追加
586         *
587         * @param   no オプションに追加するtitle属性
588         */
589        public void setTitleUseNo( final String no ) {
590                titleUseNo = nval( getRequestParameter( no ),titleUseNo );
591                if( titleUseNo == 0 || titleUseNo == 1 ) {
592                        String errMsg = "通常、カラム番号=0 は キー情報、=1 はラベル情報 です。2 か 3 を指定して下さい。";
593                        throw new HybsSystemException( errMsg );
594                }
595        }
596
597        /**
598         * シリアライズ用のカスタムシリアライズ書き込みメソッド
599         *
600         * @og.rev 4.0.0.0 (2006/09/31) 新規追加
601         * @serialData 一部のオブジェクトは、シリアライズされません。
602         *
603         * @param       strm    ObjectOutputStreamオブジェクト
604         * @throws IOException  入出力エラーが発生した場合
605         */
606        private void writeObject( final ObjectOutputStream strm ) throws IOException {
607                strm.defaultWriteObject();
608        }
609
610        /**
611         * シリアライズ用のカスタムシリアライズ読み込みメソッド
612         *
613         * ここでは、transient 宣言された内部変数の内、初期化が必要なフィールドのみ設定します。
614         *
615         * @og.rev 4.0.0.0 (2006/09/31) 新規追加
616         * @serialData 一部のオブジェクトは、シリアライズされません。
617         *
618         * @param       strm    ObjectInputStreamオブジェクト
619         * @see #release2()
620         * @throws IOException  シリアライズに関する入出力エラーが発生した場合
621         * @throws ClassNotFoundException       クラスを見つけることができなかった場合
622         */
623        private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException {
624                strm.defaultReadObject();
625        }
626
627//      /**
628//       * 親のog:selectタグのnameとeventColumn設定を返します。
629//       *
630//       * @og.rev 4.3.6.0 (2009/04/01)
631//       *
632//       */
633//      private String[] getEventColumn(){
634//              SelectTag seltag = (SelectTag)findAncestorWithClass(this,SelectTag.class);
635//              String[] selectVal = new String[2];
636//              selectVal[0] = seltag.getEventColumn();
637//              selectVal[1] = seltag.get("name");
638//              return selectVal;
639//      }
640
641        /**
642         * このオブジェクトの文字列表現を返します。
643         * 基本的にデバッグ目的に使用します。
644         *
645         * @return このクラスの文字列表現
646         */
647        @Override
648        public String toString() {
649                return org.opengion.fukurou.util.ToString.title( this.getClass().getName() )
650                                .println( "VERSION"             ,VERSION        )
651                                .println( "selValue"    ,selValue       )
652                                .println( "defaultVal"  ,defaultVal     )
653                                .println( "dbid"                ,dbid           )
654                                .println( "sql"                 ,sql            )
655                                .println( "separator"   ,separator      )
656                                .println( "quotCheck"   ,quotCheck      )
657                                .println( "Other..."    ,getAttributes().getAttribute() )
658                                .fixForm().toString() ;
659        }
660}