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.db.DBTableModel;
020import org.opengion.hayabusa.db.DBColumn;
021import org.opengion.hayabusa.html.JsonReader;
022import org.opengion.fukurou.util.ErrorMessage;
023import org.opengion.fukurou.util.StringUtil;
024import static org.opengion.fukurou.util.StringUtil.nval;
025
026import java.util.Locale;
027
028/**
029 * JSONを DBTableModelオブジェクトに読み取るタグです。
030 *
031 * JSONの読み取りにはpluginのJsonReaderを利用します。
032 * 標準はエンジンの出力形式の読み取りを行うJsonReader_Defaultです。
033 *
034 * 入力件数を"DB.COUNT" キーでリクエストにセットしています。
035 *
036 * @og.formSample
037 * ●形式:
038 *     <og:readJSON
039 *         command      = "NEW"
040 *         maxRowCount  = "10000"               読取最大件数(0:[無制限])
041 *     >
042 *      ...
043 *     <og:readJSON />
044 * ●body:なし
045 *
046 * ●Tag定義:
047 *   <og:readTable
048 *       readerClass        【TAG】実際に読み出すクラス名の略称(TableReader_**** の ****)をセットします(初期値:Default)
049 *       JSONData           【TAG】読み取るJSONデータをセットします。タグのBODYでもセット可能です。
050 *       maxRowCount        【TAG】読取時の最大取り込み件数をセットします (初期値:DB_MAX_ROW_COUNT[=1000])(0:[無制限])
051 *       tableId            【TAG】(通常使いません)sessionから所得する DBTableModelオブジェクトの ID
052 *       command            【TAG】コマンド(NEW,RENEW)をセットします(初期値:NEW)
053 *       modifyType         【TAG】ファイル取り込み時の モディファイタイプ(A(追加),C(更新),D(削除))を指定します
054 *       displayMsg         【TAG】query の結果を画面上に表示するメッセージIDを指定します(初期値:MSG0033[ 件検索しました])
055 *       notfoundMsg        【TAG】検索結果がゼロ件の場合に表示するメッセージリソースIDを指定します(初期値:MSG0077[対象データはありませんでした])
056 *       checkColumns       【TAG】読み取り元ファイルの整合性チェックを行うカラム列をカンマ指定します
057 *       nullCheck          【TAG】NULL チェックすべきカラム列をカンマ区切り(CVS形式)で指定します
058 *       language           【TAG】タグ内部で使用する言語コード[ja/en/zh/…]を指定します
059 *       stopZero           【TAG】読込件数が0件のとき処理を続行するかどうか[true/false]を指定します(初期値:false[続行する])
060 *       scope              【TAG】キャッシュする場合のスコープ[request/page/session/applicaton]を指定します(初期値:session)
061 *       mainTrans          【TAG】(通常使いません)タグで処理される処理がメインとなるトランザクション処理かどうかを指定します(初期値:false)
062 *       skipRowCount       【TAG】(通常は使いません)データの読み飛ばし件数を設定します
063 *       useRenderer        【TAG】読取処理でラベルをコードリソースに逆変換を行うかどうかを指定します (初期値:false)
064 *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null) 
065 *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null) 
066 *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:true) 
067 *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:true) 
068 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
069 *   />
070 *
071 * ●使用例
072 *
073 *     <og:readJSON
074 *         command        = "NEW"
075 *         readerClass    = "Default"             
076 *         maxRowCount    = "10000"               読取最大件数(0:[無制限])
077 *         checkColumns   = "OYA,KO,HJO,SU"       整合性チェックするカラム列("*" で全カラム)
078 *         nullCheck      = "OYA,KO,SU"           NULLチェックを実行します("*" で全カラム)
079 *         stopZero       = "true"                取得0件の場合に以降の処理を停止します
080 *     >
081 *       [JSON Data]
082 *     <og:readJSON />
083 *
084 * @og.group ファイル入力
085 *
086 * @version  4.0
087 * @author   Takahashi Masakazu
088 * @since    JDK5.0,
089 */
090public class ReadJSONTag extends CommonTagSupport {
091        //* このプログラムのVERSION文字列を設定します。   {@value} */
092        private static final String             VERSION                         = "5.7.7.2 (2014/06/20)";
093
094        private static final long               serialVersionUID        = 577220140620L;
095
096        private static final int                ERROR_ROW_COUNT         = 200;                                                                                                  // 4.0.0 (2007/05/25)
097
098        /** command 引数に渡す事の出来る コマンド  新規作成 {@value} */
099        public static final String              CMD_NEW                         = "NEW";
100        /** command 引数に渡す事の出来る コマンド  再検索 {@value} */
101        public static final String              CMD_RENEW                       = "RENEW";
102        private static final String[]   COMMAND_LIST            = new String[] { CMD_NEW, CMD_RENEW };
103
104        private String                                  jsonData                        = null;                                                                                         //変換JSONデータ
105        private String                                  readerClass                     = "Default";
106        private int                                             maxRowCount                     = -1;
107        private String                                  displayMsg                      = HybsSystem.sys( "VIEW_DISPLAY_MSG" );
108        private String                                  notfoundMsg                     = "MSG0077";                                                                                    // 対象データはありませんでした。
109        private int                                             executeCount            = -1;                                                                                                   // 検索/実行件数
110        private String                                  modifyType                      = null;
111        private String                                  checkColumns            = null;                                                                                         //  取り込み時チェック
112        private String                                  nullCheck                       = null;                                                                                         //  nullチェック確認
113        private transient DBTableModel  table                           = null;
114        private String                                  command                         = CMD_NEW;
115        private String                                  tableId                         = HybsSystem.TBL_MDL_KEY;
116        private boolean                                 stopZero                        = false;                                                                                                //  stopZero属性追加
117        private boolean                                 isMainTrans                     = true;                                                                                         //  DBLastSqlの処理の見直し
118        private int                                             skipRowCount            = 0;                                                                                                    //  データの読み飛ばし設定
119
120        //  読取処理でコードリソースのラベル変換を行うかどうか。
121        private boolean                                 useRenderer                     = false;
122
123        /**
124         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
125         *
126         *
127         * @return      後続処理の指示( EVAL_BODY_BUFFERED )
128         */
129        @Override
130        public int doStartTag() {
131                if( useTag() ) {
132
133                        return EVAL_BODY_BUFFERED ;     // Body を評価する。( extends BodyTagSupport 時)
134                }
135                return  SKIP_BODY ;                             // Body を評価しない
136        }
137        
138        /**
139         * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
140         *
141         * @return      後続処理の指示(SKIP_BODY)
142         */
143        @Override
144        public int doAfterBody() {
145                if( jsonData == null || jsonData.length() <= 0 ) {
146                        jsonData = getBodyString();
147                }
148                return SKIP_BODY;
149        }
150
151        /**
152         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
153         *
154         *
155         * @return      後続処理の指示
156         */
157        @Override
158        public int doEndTag() {
159                debugPrint();
160                if( !useTag() ) { return EVAL_PAGE; }
161
162                if( jsonData != null && jsonData.length() > 0 && check( command, COMMAND_LIST ) ) {
163                        useMainTrans( isMainTrans );
164                        startQueryTransaction( tableId );
165
166                        if( "session".equals( getScope() ) ) {
167                                removeSessionAttribute( tableId );
168                                removeSessionAttribute( HybsSystem.VIEWFORM_KEY );
169                        }
170
171                        if( maxRowCount < 0 ) {
172                                maxRowCount = sysInt( "DB_MAX_ROW_COUNT" );
173                        }
174
175                        create( jsonData );
176
177                        if( table != null ) {
178                                //  checkTableColumn 前に、modifyType 設定を行います。
179                                executeCount = table.getRowCount();
180                                if( modifyType != null ) {
181                                        for( int row = 0; row < executeCount; row++ ) {
182                                                table.setModifyType( row, modifyType );
183                                        }
184                                }
185
186                                ErrorMessage errMsg = checkTableColumn( table );
187                                if( errMsg != null && !errMsg.isOK() ) {
188                                        jspPrint( TaglibUtil.makeHTMLErrorTable( errMsg, getResource() ) );
189                                        return SKIP_PAGE;
190                                }
191
192                        }
193                        // トランザクションチェックを行います。
194                        if( !commitTableObject( tableId, table ) ) {
195                                jspPrint( "ReadTableTag Query処理が割り込まれました。DBTableModel は登録しません。" );
196                                return SKIP_PAGE;
197                        }
198
199                        StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_SMALL );
200
201                        // 実行件数の表示 command="NEW" のときのみ、displayMsg を表示させます。
202                        if( CMD_NEW.equals( command ) ) {
203                                if( executeCount > 0 && displayMsg != null && displayMsg.length() > 0 ) {
204                                        buf.append( executeCount );
205                                        buf.append( getResource().getLabel( displayMsg ) );
206                                        buf.append( HybsSystem.BR );
207                                }
208                                else if( executeCount == 0 && notfoundMsg != null && notfoundMsg.length() > 0 ) {
209                                        buf.append( getResource().getLabel( notfoundMsg ) );
210                                        buf.append( HybsSystem.BR );
211                                }
212                        }
213
214                        // 読込件数を、"DB.COUNT" キーでリクエストにセットする。
215                        setRequestAttribute( "DB.COUNT", String.valueOf( executeCount ) );
216
217                        jspPrint( buf.toString() );
218                }
219
220                // stopZero機能を追加
221                final int rtnCode;
222                if( executeCount < 0 && stopZero ) {
223                        rtnCode = SKIP_PAGE;
224                }
225                else {
226                        rtnCode = EVAL_PAGE;
227                }
228
229                return rtnCode;
230        }
231
232        /**
233         * タグリブオブジェクトをリリースします。
234         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
235         *
236         */
237        @Override
238        protected void release2() {
239                super.release2();
240                readerClass = "Default";
241                maxRowCount = -1;
242                displayMsg = HybsSystem.sys( "VIEW_DISPLAY_MSG" );
243                notfoundMsg = "MSG0077"; // 対象データはありませんでした。
244                executeCount = -1; // 検索/実行件数
245                modifyType = null;
246                command = CMD_NEW;
247                table = null;
248                tableId = HybsSystem.TBL_MDL_KEY;
249                checkColumns = null; // 取り込み時チェック
250                nullCheck = null;
251                stopZero = false;
252                isMainTrans = true;
253                skipRowCount = 0;
254                useRenderer = false;
255                jsonData = null;
256        }
257
258        /**
259         * TableReader の実オブジェクトを生成して,BufferedReader に書き込みます。
260         *
261         *
262         * @param       out     出力するBufferedReaderオブジェクト
263         */
264        protected void create( final String out ) {
265                String className = HybsSystem.sys( "JsonReader_" + readerClass );
266                JsonReader reader = (JsonReader) HybsSystem.newInstance( className );
267                reader.setResourceManager( getResource() );
268                reader.setMaxRowCount( maxRowCount );
269                reader.setSkipRowCount( skipRowCount );
270                reader.setUseRenderer( useRenderer );
271                reader.setDebug( isDebug() );
272                reader.readDBTable( out );
273                table = reader.getDBTableModel();
274        }
275
276        /**
277         * カラム文字列(CSV形式)から、カラム番号配列を作成します。
278         * 簡易メソッドです。
279         * 引数が、"*" の場合は、全カラムを指定したことになります。
280         * null の場合は、サイズが 0 の配列を返します。
281         *
282         *
283         * @param       clms    カラム文字列(CSV形式)
284         * @param       table   DBTableModelオブジェクト
285         *
286         * @return      カラム番号配列(無い場合は、長さ0の配列)
287         */
288        private int[] makeClmNos( final String clms, final DBTableModel table ) {
289                final int[] clmNo;
290
291                if( clms == null ) {
292                        clmNo = new int[0];
293                }
294                else if( "*".equals( clms ) ) {
295                        int size = table.getColumnCount();
296                        clmNo = new int[size];
297                        for( int i = 0; i < size; i++ ) {
298                                clmNo[i] = i;
299                        }
300                }
301                else {
302                        String[] clmStr = StringUtil.csv2Array( clms );
303                        int size = clmStr.length;
304                        clmNo = new int[size];
305                        for( int i = 0; i < size; i++ ) {
306                                clmNo[i] = table.getColumnNo( clmStr[i] );
307                        }
308                }
309
310                return clmNo;
311        }
312
313        /**
314         * checkColumns に指定されたカラムをチェックします。
315         * カラムオブジェクトのDBType属性に対応したチェックを行います。
316         * チェック結果で、エラーが発生した場合は、ErrorMessage オブジェクトを
317         * 返します。
318         * DBColumn#valueCheck( String ) の結果のErrorMessageをすべて append
319         * していきます。
320         * debug=true で、エラー時の詳細なデータを出力します。
321         *
322         * @param       table   DBTableModelオブジェクト
323         *
324         * @return      カラムキー + 値 のエラーメッセージオブジェクト
325         */
326        private ErrorMessage checkTableColumn( final DBTableModel table ) {
327                ErrorMessage errMsg = new ErrorMessage( "Check Columns Error!" );
328
329                int rowCnt = table.getRowCount();
330                int[] chkClmNo = makeClmNos( checkColumns, table );
331                int[] nllclmNo = makeClmNos( nullCheck, table );
332
333                for( int row = 0; row < rowCnt; row++ ) {
334                        String[] vals = table.getValues( row );
335                        DBColumn[] dbClms = table.getDBColumns();
336                        boolean isError = false;
337
338                        // checkColumns 処理
339                        for( int i = 0; i < chkClmNo.length; i++ ) {
340                                int no = chkClmNo[i];
341                                ErrorMessage msg = dbClms[no].valueCheck( vals[no] );
342                                if( msg.getKekka() > ErrorMessage.OK ) {
343                                        isError = true;
344                                        errMsg.append( row + 1, dbClms[no].valueCheck( vals[no] ) );
345                                }
346                        }
347
348                        // nullCheck 処理
349                        for( int i = 0; i < nllclmNo.length; i++ ) {
350                                int no = nllclmNo[i];
351                                if( vals[no] == null || vals[no].length() == 0 ) {
352                                        isError = true;
353                                        String label = dbClms[no].getLabel();
354                                        // ERR0012 : 指定のデータがセットされていません。(NULLエラー)。key={0}
355                                        errMsg.addMessage( row + 1, ErrorMessage.NG, "ERR0012", label );
356                                }
357                        }
358
359                        // エラー時のデバッグ出力
360                        if( isDebug() && isError ) {
361                                errMsg.addMessage( row + 1, ErrorMessage.OK, "Debug Info", java.util.Arrays.toString( table.getValues( row ) ) );
362                        }
363
364                        if( errMsg.size() > ERROR_ROW_COUNT ) {
365                                break;
366                        }
367                }
368
369                return errMsg;
370        }
371
372        /**
373         * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します
374         *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY}])。
375         *
376         * @og.tag
377         * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に
378         * 渡す場合に、通常は、session を利用します。その場合の登録キーです。
379         * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、
380         * この tableId 属性を利用して、メモリ空間を分けます。
381         *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY}])。
382         *
383         * @param       id sessionに登録する時の ID
384         */
385        public void setTableId( final String id ) {
386                tableId = nval( getRequestParameter( id ), tableId );
387        }
388
389        /**
390         * 【TAG】実際に読み出すクラス名の略称(JsonReader_**** の ****)をセットします({@og.doc03Link readerClass 初期値:Default})。
391         *
392         * @og.tag
393         * 実際に読み出すクラス名(の略称)をセットします。
394         * これは、org.opengion.plugin.json 以下の JsonReader_**** クラスの **** を
395         * 与えます。これらは、JsonReader インターフェースを継承したサブクラスです。
396         * 
397         * @param   readerClass クラス名(の略称)
398         */
399        public void setReaderClass( final String readerClass ) {
400                this.readerClass = nval( getRequestParameter( readerClass ), this.readerClass );
401        }
402
403        /**
404         * 【TAG】読取時の最大取り込み件数をセットします
405         *              (初期値:DB_MAX_ROW_COUNT[={@og.value org.opengion.hayabusa.common.SystemData#DB_MAX_ROW_COUNT}])。
406         *
407         * @og.tag
408         * DBTableModelのデータとして登録する最大件数をこの値に設定します。
409         * サーバーのメモリ資源と応答時間の確保の為です。
410         * 0 をセットすると、無制限(Integer.MAX_VALUE)になります。
411         * (初期値:ユーザー定数のDB_MAX_ROW_COUNT[={@og.value org.opengion.hayabusa.common.SystemData#DB_MAX_ROW_COUNT}])。
412         *
413         *
414         * @param   count 読取時の最大取り込み件数
415         * @see         org.opengion.hayabusa.common.SystemData#DB_MAX_ROW_COUNT
416         */
417        public void setMaxRowCount( final String count ) {
418                maxRowCount = nval( getRequestParameter( count ), maxRowCount );
419                if( maxRowCount == 0 ) {
420                        maxRowCount = Integer.MAX_VALUE;
421                }
422        }
423
424        /**
425         * 【TAG】コマンド(NEW,RENEW)をセットします(初期値:NEW)。
426         *
427         * @og.tag
428         * コマンドは,HTMLから(get/post)指定されますので,CMD_xxx で設定される
429         * フィールド定数値のいづれかを、指定できます。
430         * 何も設定されない、または、null の場合は、"NEW" が初期値にセットされます。
431         *
432         * @param       cmd コマンド(public static final 宣言されている文字列)
433         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.ReadTableTag.CMD_NEW">コマンド定数</a>
434         */
435        public void setCommand( final String cmd ) {
436                String cmd2 = getRequestParameter( cmd );
437                if( cmd2 != null && cmd2.length() > 0 ) {
438                        command = cmd2.toUpperCase( Locale.JAPAN );
439                }
440        }
441
442        /**
443         * 【TAG】query の結果を画面上に表示するメッセージIDを指定します(初期値:MSG0033[ 件検索しました])。
444         *
445         * @og.tag
446         * ここでは、検索結果の件数や登録された件数をまず出力し、
447         * その次に、ここで指定したメッセージをリソースから取得して
448         * 表示します。
449         * 表示させたくない場合は, displayMsg = "" をセットしてください。
450         * 初期値は、検索件数を表示します。
451         *
452         * @param   id ディスプレイに表示させるメッセージ ID
453         */
454        public void setDisplayMsg( final String id ) {
455                if( id != null ) {
456                        displayMsg = id;
457                }
458        }
459
460        /**
461         * 【TAG】検索結果がゼロ件の場合に表示するメッセージリソースIDを指定します(初期値:MSG0077[対象データはありませんでした])。
462         *
463         * @og.tag
464         * ここでは、検索結果がゼロ件の場合のみ、特別なメッセージを表示させます。
465         * 従来は、displayMsg と兼用で、『0 件検索しました』という表示でしたが、
466         * displayMsg の初期表示は、OFF になりましたので、ゼロ件の場合のみ別に表示させます。
467         * 表示させたくない場合は, notfoundMsg = "" をセットしてください。
468         * 初期値は、MSG0077[対象データはありませんでした]です。
469         *
470         * @param       id ディスプレイに表示させるメッセージ ID
471         */
472        public void setNotfoundMsg( final String id ) {
473                String ids = getRequestParameter( id );
474                if( ids != null ) {
475                        notfoundMsg = ids;
476                }
477        }
478
479        /**
480         * 【TAG】取り込み時の モディファイタイプ(A(追加),C(更新),D(削除))を指定します。
481         *
482         * @og.tag
483         * JSON読み込み時に、そのデータをA(追加)、C(更新)、D(削除)の
484         * モディファイタイプをつけた状態にします。
485         * その状態で、そのまま、update する事が可能になります。
486         *
487         * @param   type ファイル取り込み時の モディファイタイプ(A,C,D属性)
488         */
489        public void setModifyType( final String type ) {
490                modifyType = getRequestParameter( type );
491        }
492
493        /**
494         * 【TAG】整合性チェックを行うカラム列をカンマ指定します。
495         *
496         * @og.tag
497         * カラムオブジェクトのDBType属性に対応したチェックを行います。
498         * 指定のカラム名をカンマ区切り(CSV)で複数指定できます。
499         * 全てのカラムのチェックを行う場合は、allColumnCheck = "true" を
500         * 指定して下さい。
501         * 分解方法は、通常のパラメータ取得後に、CSV分解します。
502         *
503         *
504         * @param   clms 整合性チェックを行うカラム列(カンマ区切り文字)
505         */
506        public void setCheckColumns( final String clms ) {
507                checkColumns = nval( getRequestParameter( clms ), checkColumns );
508        }
509
510        /**
511         * 【TAG】NULL チェックすべきカラム列をカンマ区切り(CVS形式)で指定します。
512         *
513         * @og.tag nullCheck="AAA,BBB,CCC,DDD"
514         * 分解方法は、通常のパラメータ取得後に、CSV分解します。
515         *
516         * @param   clms カラム列(CVS形式)
517         */
518        public void setNullCheck( final String clms ) {
519                nullCheck = nval( getRequestParameter( clms ), nullCheck );
520        }
521
522        /**
523         * 【TAG】読込件数が0件のとき処理を続行するかどうか[true/false]を指定します(初期値:false[続行する])。
524         *
525         * @og.tag
526         * 初期値は、false(続行する)です。
527         *
528         *
529         * @param  cmd 読込件数が0件のとき、処理を [true:中止する/false:続行する]
530         */
531        public void setStopZero( final String cmd ) {
532                stopZero = nval( getRequestParameter( cmd ), stopZero );
533        }
534
535        /**
536         * 【TAG】(通常使いません)タグで処理される処理がメインとなるトランザクション処理かどうかを指定します(初期値:false)。
537         *
538         * @og.tag
539         * この値は、ファイルダウンロード処理に影響します。この値がtrueに指定された時にcommitされたDBTableModelが
540         * ファイルダウンロードの対象の表になります。
541         *
542         * このパラメーターは、通常、各タグにより実装され、ユーザーが指定する必要はありません。
543         * 但し、1つのJSP内でDBTableModelが複数生成される場合に、前に処理したDBTableModelについてファイルダウンロードをさせたい
544         * 場合は、後ろでDBTableModelを生成するタグで、明示的にこの値をfalseに指定することで、ファイルダウンロード処理の対象から
545         * 除外することができます。
546         *
547         *
548         * @param  flag メイントランザクションかどうか
549         */
550        public void setMainTrans( final String flag ) {
551                isMainTrans = nval( getRequestParameter( flag ), isMainTrans );
552        }
553
554        /**
555         * 【TAG】(通常は使いません)データの読み飛ばし件数を設定します。
556         *
557         * @og.tag
558         * データの読み始めの初期値を指定します。
559         * 先頭行が、0行としてカウントしますので、設定値は、読み飛ばす
560         * 件数になります。(1と指定すると、1件読み飛ばし、2行目から読み込みます。)
561         * 読み飛ばしは、コメント行などは、無視しますので、実際の行数分読み飛ばします。
562         * #NAME属性や、columns 属性は、有効です。
563         *
564         *
565         * @param       count 読み始めの初期値
566         */
567        public void setSkipRowCount( final String count ) {
568                skipRowCount = nval( getRequestParameter( count ), skipRowCount );
569        }
570
571        /**
572         * 【TAG】読取処理でラベルをコードリソースに逆変換を行うかどうかを指定します
573         *
574         * @og.tag
575         * コードリソースのカラムに対して、ラベルからコードを求める逆変換を行うことで、
576         * Renderer 系で出力したデータを取り込むことができるようにします。
577         *
578         * JSONでの出力ではRenderer系で出力する事は少ないと思われるため、初期値はfalseとしておきます。
579         *
580         *
581         * @param  flag コードリソースのラベル逆変換を行うかどうか
582         */
583        public void setUseRenderer( final String flag ) {
584                useRenderer = nval( getRequestParameter( flag ), useRenderer );
585        }
586
587        /**
588         * 【TAG】テーブルモデルに取り込むJSONデータ
589         *
590         * @og.tag
591         * テーブルモデルに取り込むためのJSONデータを指定します。
592         * タグのBODYでも指定可能です。
593         *
594         * @param json 取り込むJSON形式データ
595         */
596        public void setJSONData( final String json ) {
597                jsonData = nval( getRequestParameter( json ), jsonData );
598        }
599
600        /**
601         * このオブジェクトの文字列表現を返します。
602         * 基本的にデバッグ目的に使用します。
603         *
604         * @return このクラスの文字列表現
605         */
606        @Override
607        public String toString() {
608                return org.opengion.fukurou.util.ToString.title( this.getClass().getName() ).println( "VERSION", VERSION ).println( "readerClass", readerClass ).println( "maxRowCount", maxRowCount ).println( "displayMsg", displayMsg ).println( "executeCount", executeCount ).println( "modifyType", modifyType ).println( "checkColumns", checkColumns ).println( "nullCheck", nullCheck ).println( "command", command ).println( "tableId", tableId ).println( "Other...", getAttributes().getAttribute() ).fixForm().toString();
609        }
610}