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 java.io.File;
019import java.io.IOException;
020import java.io.Writer;
021import java.nio.charset.StandardCharsets;
022import java.nio.file.Files;
023import java.nio.file.Paths;
024import java.util.LinkedHashMap;
025import java.util.Locale;
026import java.util.Map;
027import java.util.Set;
028
029import org.opengion.fukurou.system.Closer;
030import org.opengion.fukurou.util.ArraySet;
031import org.opengion.fukurou.util.ErrorMessage;
032import org.opengion.fukurou.util.FileUtil;
033import org.opengion.fukurou.util.HttpConnect;
034import org.opengion.fukurou.util.JSONScan;
035import org.opengion.fukurou.util.StringUtil;
036import org.opengion.fukurou.util.ToString;
037import org.opengion.hayabusa.common.HybsSystem;
038import org.opengion.hayabusa.common.HybsSystemException;
039import org.opengion.hayabusa.db.DBColumn;
040import org.opengion.hayabusa.db.DBTableModel;
041import org.opengion.hayabusa.db.DBTableModelUtil;
042
043import static org.opengion.fukurou.util.StringUtil.nval;
044
045/**
046 * IOr (Information Organizer) に接続し、取得したデータベースを表示するタグです。
047 *
048 * IOr へデータ取得を要求して受取った JSON形式 の文字列を、DBTableModel にセットします。
049 * IOr から取得したデータより loadFile が優先されます。
050 *
051 * このタグの結果(DBTableModel)は、通常の QueryTag と同様に
052 * ViewFormTag で一覧表示や、WriteTableTag でファイル出力が可能です。
053 *
054 * SystemData の USE_SQL_INJECTION_CHECK が true か、quotCheck 属性が true の場合は、
055 * SQLインジェクション対策用のシングルクォートチェックを行います。リクエスト引数に
056 * シングルクォート(')が含まれると、エラーになります。
057 * 同様にUSE_XSS_CHECKがtrueか、xssCheck属性がtrueの場合は、
058 * クロスサイトススクリプティング(XSS)対策のためless/greater than signのチェックを行います。
059 *
060 * 実行後にリクエストパラメータに以下の値がセットされます。
061 *   DB.COUNT    : 実行結果の件数
062 *   DB.ERR_CODE : 実行結果のエラーコード
063 *   DB.ERR_MSG  : 実行結果のエラーメッセージ
064 *
065 * ※ このタグは、Transaction タグの対象です。
066 *
067 * @og.formSample
068 * ●形式:
069 *     <og:iorQuery
070 *         url           = "http://・・・ "    必須
071 *         authURL       = "http://・・・ "    必須
072 *         authUserPass  = "admin:******"   必須
073 *         appliName     = "データテーブル名"
074 *         callMethod    = "getReportInfo"
075 *     />
076 *
077 * ●body:あり(EVAL_BODY_BUFFERED:BODYを評価し、{@XXXX} を解析します)
078 *
079 * ●Tag定義:
080 *   <og:iorQuery
081 *       url              ○【TAG】アクセスする URL を指定します (必須)
082 *       proxyHost          【TAG】プロキシ経由で接続する場合の、プロキシホスト名を指定します
083 *       proxyPort          【TAG】プロキシ経由で接続する場合の、プロキシポート番号を指定します
084 *       timeout            【TAG】通信リンクのオープン時に、指定された秒単位のタイム・アウト値を使用します
085 *                                  (初期値:URL_CONNECT_TIMEOUT[={@og.value SystemData#URL_CONNECT_TIMEOUT}])
086 *       authURL          ○【TAG】JSONコードで認証するURLを指定します (必須)
087 *       authUserPass     ○【TAG】Basic認証を使用して接続する場合のユーザー:パスワードを指定します (必須)
088 *       companyId          【TAG】企業IDを指定します
089 *       appliName          【TAG】アプリケーションの名前を指定します
090 *       callMethod         【TAG】関数名を指定します
091 *       display            【TAG】接続の結果を表示するかどうかを指定します (初期値:false)
092 *       saveFile           【TAG】接続の結果をファイルに保存します
093 *       loadFile           【TAG】ファイルからURL接続結果に相当するデータを読み取ります
094 *       command            【TAG】コマンド (NEW,RENEW)をセットします
095 *       scope              【TAG】キャッシュする場合のスコープ[request/page/session/application]を指定します (初期値:session)
096 *       displayMsg         【TAG】検索結果を画面上に表示するメッセージリソースIDを指定します (初期値:VIEW_DISPLAY_MSG[=])
097 *       notfoundMsg        【TAG】検索結果がゼロ件の場合に表示するメッセージリソースIDを指定します
098 *                                  (初期値:MSG0077[対象データはありませんでした])
099 *       stopZero           【TAG】検索結果が0件のとき処理を続行するかどうか[true/false]を指定します (初期値:false[続行する])
100 *       tableId            【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します
101 *       stopError          【TAG】処理エラーの時に処理を中止するかどうか[true/false]を設定します (初期値:true)
102 *       dispError          【TAG】エラー時にメッセージを表示するか[true/false]を設定します。通常はstopErrorと併用 (初期値:true)
103 *       quotCheck          【TAG】リクエスト情報の シングルクォート(') 存在チェックを実施するかどうか[true/false]を設定します
104 *                                  (初期値:USE_SQL_INJECTION_CHECK)
105 *       xssCheck           【TAG】リクエスト情報の HTMLTag開始/終了文字(><) 存在チェックを実施するかどうか[true/false]を設定します
106 *                                  (初期値:USE_XSS_CHECK[=true])
107 *       mainTrans          【TAG】(通常は使いません)タグで処理される処理がメインとなるトランザクション処理かどうかを指定します (初期値:false)
108 *       useBeforeHtmlTag   【TAG】処理時間(queryTime)などの情報出力[true:有効/false:無効]を指定します (初期値:true)
109 *       useTimeView        【TAG】処理時間を表示する TimeView を表示するかどうかを指定します
110 *                                  (初期値:VIEW_USE_TIMEBAR[={@og.value SystemData#VIEW_USE_TIMEBAR}])
111 *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します (初期値:null)
112 *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します (初期値:null)
113 *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます (初期値:判定しない)
114 *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます (初期値:判定しない)
115 *       caseIf             【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます (初期値:判定しない)
116 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します (初期値:false)
117 *
118 *   >   ... Body ...
119 *   </og:iorQuery>
120 *
121 * ●使用例
122 *     <og:iorQuery
123 *         url           = "http://・・・ "
124 *         authURL       = "http://・・・ "
125 *         authUserPass  = "admin:******"
126 *         appliName     = "データテーブル名"
127 *         callMethod    = "getReportInfo"
128 *     >
129 *         <og:iorQueryParam
130 *             key  = "where"  value  = "{'PN':'{@PN}%','TANI':'{@TANI}'}"  />
131 *         </og:iorQueryParam
132 *     </og:iorQuery ・・・・・ >
133 *
134 * @og.rev 8.0.2.0 (2021/11/30) 新規作成
135 * @og.group その他部品
136 *
137 * @version  8.0
138 * @author   LEE.M
139 * @since    JDK17.0,
140 */
141public class IorQueryTag extends CommonTagSupport {
142        /** このプログラムのVERSION文字列を設定します。 {@value} */
143        private static final String VERSION = "8.0.2.0 (2021/11/30)" ;
144        private static final long serialVersionUID = 802020211130L ;
145
146        /** command 引数に渡す事の出来る コマンド  新規 {@value} */
147        public static final String CMD_NEW              = "NEW";                                                                                        // コマンド(新規)
148        /** command 引数に渡す事の出来る コマンド  再検索 {@value} */
149        public static final String CMD_RENEW    = "RENEW";                                                                                      // コマンド(再検索)
150        // String配列 から、Setに置き換えます。
151        private static final Set<String> COMMAND_SET = new ArraySet<>( CMD_NEW, CMD_RENEW );            // コマンド(Set)
152
153        /** エラーメッセージID */
154        protected static final String ERR_MSG_ID        = HybsSystem.ERR_MSG_KEY;                                               // エラーメッセージID
155
156        // IOr 応答結果のキー
157        private   static final String IOR_HTTP_STTS     = "status";                                                                             // ステータス
158        private   static final String IOR_HTTP_MSG      = "message";                                                                    // エラーメッセージ
159        /** ヘッダ配列のラベル */
160        protected static final String IOR_DISP_LBL      = "display_label";                                                              // ヘッダ配列のラベル
161        /** ヘッダ配列のキー */
162        protected static final String IOR_DISP_KEY      = "display";                                                                    // ヘッダ配列のキー
163        private   static final String IOR_SQL_MSG       = "information";                                                                // 処理後メッセージ
164        private   static final String IOR_SQL_CNT       = "insert_count";                                                               // 実行件数
165
166        // JSONによるフェーズ認証フォーマット
167        private static final String AUTH_JSON_FMT       = "{\"userInfo\":{\"companyId\":\"%s\",\"userId\":\"%s\",\"password\":\"%s\"}}";
168
169        /** JSONコード */
170        protected final Map<String,String> mapParam = new LinkedHashMap<>();                                            // JSONコード
171        /** テーブルモデル */
172        protected transient DBTableModel table;                                                                                                         // テーブルモデル
173
174        private   String        urlStr                          ;                                                                                                       // 接続するURL
175        private   String        proxyHost                       = HybsSystem.sys( "HTTP_PROXY_HOST" );                          // プロキシホスト名
176        private   int           proxyPort                       = HybsSystem.sysInt( "HTTP_PROXY_PORT" );                       // プロキシポート番号
177        private   int           timeout                         = HybsSystem.sysInt( "URL_CONNECT_TIMEOUT" );           // 接続タイムアウト時間
178        private   String        authURL                         ;                                                                                                       // JSONコードで認証するURL
179        private   String        authUserPass            ;                                                                                                       // ユーザー:パスワード
180        private   String        companyId                       = HybsSystem.sys( "IOR_COMPANYID" );                            // 企業ID
181        private   String        appliName                       ;                                                                                                       // アプリ名
182        private   String        callMethod                      ;                                                                                                       // 関数名
183        private   boolean       display                         ;                                                                                                       // 結果の表示可否
184        private   String        saveFile                        ;                                                                                                       // 保存ファイル
185        /** 読取ファイル */
186        protected String        loadFile                        ;                                                                                                       // 読取ファイル
187        private   String        command                         = CMD_NEW;                                                                                      // コマンド
188        private   String        displayMsg                      = HybsSystem.sys( "VIEW_DISPLAY_MSG" );                         // ディスプレイメッセージ
189        private   String        notfoundMsg                     = "MSG0077";                                                                            // 対象データはありませんでした。
190        private   boolean       stopZero                        ;                                                                                                       // 処理の停止可否
191        /** テーブルモデルID */
192        protected String        tableId                         = HybsSystem.TBL_MDL_KEY;                                                       // テーブルモデルID
193        /** エラー時の処理中止可否 */
194        protected boolean       stopError                       = true;                                                                                         // エラー時の処理中止可否
195        private   boolean       dispError                       = true;                                                                                         // 画面上のエラー出力可否
196        /** クオートチェック */
197        protected boolean       quotCheck                       = HybsSystem.sysBool( "USE_SQL_INJECTION_CHECK" );      // クオートチェック
198        private   boolean       xssCheck                        = HybsSystem.sysBool( "USE_XSS_CHECK" );                        // XSSチェック
199        private   boolean       useBeforeHtmlTag        = true;                                                                                         // 処理時間(queryTime)などの情報出力の可否
200        /** タイムバーの使用可否 */
201        protected boolean       useTimeView                     = HybsSystem.sysBool( "VIEW_USE_TIMEBAR" );                     // タイムバーの使用可否
202
203        private   String        user                            ;                                                                                                       // ユーザー
204        private   String        pass                            ;                                                                                                       // パスワード
205        /** BODY部 */
206        protected String        postData                        ;                                                                                                       // BODY部
207        /** 取得データ */
208        protected String        rtnData                         ;                                                                                                       // 取得データ
209        private   int           executeCount            ;                                                                                                       // 実行件数
210        /** 現在時刻 */
211        protected long          dyStart                         ;                                                                                                       // 現在時刻
212        private   boolean       isMainTrans                     = true;                                                                                         // DBLastSqlの処理見直し
213        private   String        fileURL                         = HybsSystem.sys( "FILE_URL" );                                         // ファイルURL
214
215        /**
216         * デフォルトコンストラクター
217         *
218         */
219        public IorQueryTag() { super(); }       // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
220
221        /**
222         * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。
223         *
224         * @return      後続処理の指示
225         */
226        @Override
227        public int doStartTag() {
228                if( !useTag() ) { return SKIP_BODY ; }
229
230                useXssCheck( xssCheck );
231                dyStart = System.currentTimeMillis();                                                                   // 現在時刻
232
233                if( ! check( command, COMMAND_SET ) ) {
234                        table = (DBTableModel)getObject( tableId );
235                        if( table == null )     { executeCount = 0; }
236                        else                            { executeCount = table.getRowCount(); }
237                        return SKIP_BODY;
238                }
239
240                useMainTrans( isMainTrans );
241                startQueryTransaction( tableId );
242
243                // scope="session" の場合のみ、削除します。
244                if( "session".equals( getScope() ) ) {
245                        removeSessionAttribute( tableId );
246                        removeSessionAttribute( HybsSystem.VIEWFORM_KEY );
247                }
248
249                // ユーザー:パスワード から ユーザーとパスワードを取得します。
250                checkUsrPw();
251
252                // 読取ファイル指定無し
253                if( loadFile == null ) {
254                        // JSON形式の共通要求キーを設定します。
255                        setComJson();
256                }
257                return EVAL_BODY_BUFFERED;                                                                                              // Body を評価する (extends BodyTagSupport 時)
258        }
259
260        /**
261         * Taglibのタグ本体を処理する doAfterBody() を オーバーライドします。
262         *
263         * @return      後続処理の指示(SKIP_BODY)
264         */
265        @Override
266        public int doAfterBody() {
267                // useQuotCheck() によるSQLインジェクション対策
268                useQuotCheck( quotCheck );
269
270                postData = getBodyString();
271
272                return SKIP_BODY;
273        }
274
275        /**
276         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
277         *
278         * @return      後続処理の指示
279         */
280        @Override
281        public int doEndTag() {
282                debugPrint();
283                if( !useTag() ) { return EVAL_PAGE ; }
284
285                int errCode = ErrorMessage.OK;                                                                                  // エラーコード
286                if( check( command, COMMAND_SET ) ) {
287                        // URLに対して応答結果を取得します。
288                        rtnData = outJson();
289
290                        // IOr の応答結果を特定のキーワードで分割します。
291                        final SplitReqJson splitJson = new SplitReqJson( rtnData );
292                        final String rtnStts = splitJson.getSttsJson();
293
294                        // 応答結果のHTTPステータスコードを設定します。
295                        errCode = getStatus( rtnStts );
296
297                        if( errCode == ErrorMessage.OK ) {
298                                // テーブルモデル作成します。
299                                table = makeDBTable( splitJson );
300
301                                // 処理後のメッセージを作成します。
302                                errCode = makeMessage();
303                        }
304                }
305
306                final int rtnCode;
307                // 異常
308                if( errCode >= ErrorMessage.NG ) {
309                        rtnCode = stopError ? SKIP_PAGE : EVAL_PAGE ;
310                }
311                // 正常/警告
312                else {
313                        // 実行件数 = ゼロ 且つ stopZero = true
314                        rtnCode = executeCount == 0 && stopZero ? SKIP_PAGE : EVAL_PAGE ;
315                }
316
317                // 処理時間(queryTime)などの情報出力の有効/無効を指定します。
318                if( useTimeView && useBeforeHtmlTag ) {
319                        final long dyTime = System.currentTimeMillis() - dyStart;
320                        jspPrint( "<div id=\"queryTime\" value=\"" + (dyTime) + "\"></div>" );
321                }
322                return rtnCode;
323        }
324
325        /**
326         * タグリブオブジェクトをリリースします。
327         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
328         */
329        @Override
330        protected void release2() {
331                super.release2();
332                mapParam.clear();                                                                                                               // JSONコードのクリア
333                table                           = null;                                                                                         // テーブルモデル
334                urlStr                          = null;                                                                                         // 接続するURL
335                proxyHost                       = HybsSystem.sys( "HTTP_PROXY_HOST" );                          // プロキシホスト名
336                proxyPort                       = HybsSystem.sysInt( "HTTP_PROXY_PORT" );                       // プロキシポート番号
337                timeout                         = HybsSystem.sysInt( "URL_CONNECT_TIMEOUT" );           // 接続タイムアウト時間
338                authURL                         = null;                                                                                         // JSONコードで認証するURL
339                authUserPass            = null;                                                                                         // ユーザー:パスワード
340                companyId                       = HybsSystem.sys( "IOR_COMPANYID" );                            // 企業ID
341                appliName                       = null;                                                                                         // アプリ名
342                callMethod                      = null;                                                                                         // 関数名
343                display                         = false;                                                                                        // 結果の表示可否
344                saveFile                        = null;                                                                                         // 保存ファイル
345                loadFile                        = null;                                                                                         // 読取ファイル
346                command                         = CMD_NEW;                                                                                      // コマンド
347                displayMsg                      = HybsSystem.sys( "VIEW_DISPLAY_MSG" );                         // ディスプレイメッセージ
348                notfoundMsg                     = "MSG0077";                                                                            // 対象データはありませんでした。
349                stopZero                        = false;                                                                                        // 処理の停止可否
350                tableId                         = HybsSystem.TBL_MDL_KEY;                                                       // テーブルモデル
351                stopError                       = true;                                                                                         // エラー時の処理中止可否
352                dispError                       = true;                                                                                         // 画面上のエラー出力可否
353                quotCheck                       = HybsSystem.sysBool( "USE_SQL_INJECTION_CHECK" );      // クオートチェック
354                xssCheck                        = HybsSystem.sysBool( "USE_XSS_CHECK" );                        // XSSチェック
355                useBeforeHtmlTag        = true;                                                                                         // 処理時間(queryTime)などの情報出力の可否
356                useTimeView                     = HybsSystem.sysBool( "VIEW_USE_TIMEBAR" );                     // タイムバーの使用可否
357
358                user                            = null;                                                                                         // ユーザー
359                pass                            = null;                                                                                         // パスワード
360                postData                        = null;                                                                                         // BODY部
361                rtnData                         = null;                                                                                         // 取得データ
362                executeCount            = 0;                                                                                            // 実行件数
363                dyStart                         = 0;                                                                                            // 現在時刻
364                isMainTrans                     = true;                                                                                         // DBLastSqlの処理見直し
365                fileURL                         = HybsSystem.sys( "FILE_URL" );                                         // ファイルURL
366        }
367
368        /**
369         * IorQuery オブジェクトに渡すパラメータをマッピングします。
370         *
371         * IorQueryParamTag クラスよりセットされます。
372         * 但し、以下のキーに対して IorQueryParamTag では指定できません。
373         * company_id、user_id、session_id、report_name、method
374         *
375         * @param       key     パラメータキー
376         * @param       val     パラメータ値
377         */
378        protected void addParam( final String key, final String val ) {
379                if( mapParam.containsKey( key ) ){
380                        final String errMsg = key + "のキーが重複しています。";
381                        throw new HybsSystemException( errMsg );
382                }
383                else {
384                        mapParam.put( key, val );
385                }
386        }
387
388        /**
389         * ユーザー:パスワード から ユーザーとパスワードを分割します。
390         */
391        protected void checkUsrPw() {
392                if( authUserPass.contains(":") ) {
393                        // ユーザー:パスワードを分割します。
394                        final String[] prm = StringUtil.csv2Array( authUserPass, ':' ,2 );
395                        user = prm[0];                                                                                                          // ユーザー
396                        pass = prm[1];                                                                                                          // パスワード
397                }
398                else {
399                        final String errMsg = "ユーザー:パスワード の形式で記述してください。";
400                        throw new HybsSystemException( errMsg );
401                }
402        }
403
404        /**
405         * JSON形式の共通要求キーを設定します。
406         * ・company_id   : 企業ID
407         * ・user_id      : ユーザーID
408         * ・session_id   : セッションID
409         * ・report_name  : アプリ名
410         * ・method       : メソッド
411         * 例:{"company_id":"XXXXX","user_id":"admin","session_id":"$session_id$" …}
412         */
413        protected void setComJson() {
414                // 企業ID
415                if( companyId != null ) { mapParam.put( "company_id", companyId ); }
416                // ユーザーID
417                if( !user.isEmpty() ) { mapParam.put( "user_id", user ); }
418                // セッションID
419                mapParam.put( "session_id", "$session_id$" );
420                // アプリ名
421                if( appliName != null ) { mapParam.put( "report_name", appliName ); }
422                // メソッド
423                if( callMethod != null ) { mapParam.put( "method", callMethod ); }
424        }
425
426        /**
427         * loadFile 指定がある場合は、ファイルからデータを読取ります。
428         * loadFile 指定がない場合は、URLに対して応答結果を取得します。
429         *
430         * @return      JSON形式の文字列
431         * @og.rtnNotNull
432         */
433        protected String outJson() {
434                final String str;
435
436                // 読取ファイル指定無し
437                if( loadFile == null ) {
438                        if( postData == null || postData.isEmpty() ){
439                                postData = JSONScan.map2Json( mapParam );
440                        }
441                        // URLに対して応答結果を取得します。
442                        str = retResponse();
443                }
444                // 読取ファイル指定有り
445                else {
446                        final StringBuilder buf = new StringBuilder(BUFFER_MIDDLE);
447                        try {
448                                for (final String text : Files.readAllLines( Paths.get(loadFile), StandardCharsets.UTF_8 )) {
449                                        buf.append( text )
450                                                .append( CR );
451                                }
452                                str = buf.toString();
453                        }
454                        catch( final IOException ex ) {
455                                final String errMsg = "loadFile 処理中でエラーが発生しました。"        + CR
456                                                        + "\t " + ex.getMessage()                                                       + CR ;
457                                throw new HybsSystemException( errMsg, ex );
458                        }
459                }
460                return str;
461        }
462
463        /**
464         * URLに対して応答結果を取得します。
465         *
466         * @return      URL接続先のデータ
467         * @og.rtnNotNull
468         */
469        protected String retResponse() {
470                HttpConnect conn = null;
471                Writer outWriter = null;
472                String getData = null;
473                try {
474                        conn = connect();
475
476                        // URL接続先のデータを取得します。
477                        getData = conn.readData();
478                        // 実行結果のステータスコードが'200'(正常)ではないとき、例外を発生させます。
479                        if( conn.getCode() != 200 ) { throw new Throwable(); }
480
481                        if( display ) {
482                                outWriter = FileUtil.getNonFlushPrintWriter( pageContext.getOut() ) ;   // JspWriter の取得
483                        }
484                        else if( saveFile != null ) {
485                                outWriter = FileUtil.getPrintWriter( new File( saveFile ), "UTF-8" );
486                        }
487
488                        // Unicode文字列から元の文字列に変換します。
489                        getData = StringUtil.convertToOiginal( getData );
490
491                        // 出力先が存在する場合
492                        if( outWriter != null ) {
493                                outWriter.write( getData );
494                        }
495                }
496                catch( final Throwable th ) {
497                        final String errMsg = "データ処理中にエラーが発生しました。"      + CR
498                                                + " url=[" + urlStr + "]"                                                       + CR
499                                                + " message=[" + ( conn == null ? "NO_CONNECTION" : conn.getMessage() ) + "]" + CR
500                                                + " Exception=[" + th.getMessage() + "]" ;
501                        throw new HybsSystemException( errMsg, th );
502                }
503                finally {
504                        Closer.ioClose( outWriter );
505                }
506                return getData;
507        }
508
509        /**
510         * URLに対して接続を行います。
511         *
512         * @return      接続オブジェクト
513         * @og.rtnNotNull
514         * @throws      IOException     入出力エラーが発生したとき
515         */
516        protected HttpConnect connect() throws IOException {
517                // HttpConnect は、後付で引数を渡せます。
518                final HttpConnect conn = new HttpConnect( urlStr, authUserPass );
519                conn.setDebug( isDebug() );
520                conn.usePost( true );
521
522                // プロキシ
523                if( proxyHost != null ) {
524                        conn.setProxy( proxyHost,proxyPort );
525                }
526                // JSONによるフェーズ認証
527                if( authUserPass != null && authURL != null ) {
528                        final String authJson = String.format( AUTH_JSON_FMT, companyId, user, pass ) ;
529                        conn.setAuthJson( authJson , authURL );
530                }
531                // 接続タイムアウト時間
532                if( timeout >= 0 ) {
533                        conn.setTimeout( timeout );
534                }
535                // JSONコードでリクエストするパラメータを指定
536                if( postData != null ) {
537                        conn.setReqJson( postData );
538                }
539                return conn;
540        }
541
542        /**
543         * IOr の要求結果から、HTTPステータスコードを設定します。
544         *
545         * @param       strJson Json形式の文字列
546         * @return      エラーコード
547         * @og.rtnNotNull
548         */
549        protected int getStatus( final String strJson ) {
550                int errCode = ErrorMessage.OK;                                                                                  // エラーコード
551                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );                   // バッファ
552
553                // ---------------------------------------------------------------------
554                // HTTPステータスコード (先頭から"data"までの文字列)
555                // 例:{"status": 200, "message": "OK", "sessionInfo": "51b16"
556                // ---------------------------------------------------------------------
557                // キーと値をマッピングします。
558                final Map<String,String> mapStts = JSONScan.json2Map( strJson );
559                final String stts = mapStts.get( IOR_HTTP_STTS );                                               // ステータス
560
561                // ステータスが'200'(正常)である
562                if( stts.equals( String.valueOf( 200 ) ) ) {
563                        errCode = ErrorMessage.OK;                                                                                      // 正常
564                        displayMsg = " 件の" + mapStts.get( IOR_SQL_MSG );                                        // 処理メッセージ
565                        executeCount = nval( mapStts.get( IOR_SQL_CNT ), -1 );                          // 実行件数
566
567                        // 実行結果がゼロ件の場合に画面上に表示します。
568                        if( CMD_NEW.equals( command ) && executeCount == 0
569                                && notfoundMsg != null && notfoundMsg.length() > 0 ) {
570                                        buf.append( getResource().getLabel( notfoundMsg ) )
571                                                .append( BR );
572                        }
573                }
574                // ステータスが'200'(正常)ではない
575                else {
576                        errCode = ErrorMessage.NG;                                                                                              // エラーコード
577                        String msg = mapStts.get( IOR_HTTP_MSG );                                                               // エラーメッセージ
578                        // HTTPエラーではない
579                        if( "NG".equalsIgnoreCase(msg) ) { msg = mapStts.get( IOR_SQL_MSG ); }  // 処理メッセージ
580
581                        final ErrorMessage errMessage = new ErrorMessage( "iorQueryTag Error!" );
582                        errMessage.addMessage( 0, errCode, stts, msg );
583
584                        // TaglibUtil.makeHTMLErrorTable メソッドを利用します。
585                        final String err = TaglibUtil.makeHTMLErrorTable( errMessage, getResource() );
586                        if( err != null && err.length() > 0 ) {
587                                buf.append( err );
588                                setSessionAttribute( ERR_MSG_ID, errMessage );
589                        }
590                        // 以前処理のエラーメッセージを削除します。
591                        else if( CMD_NEW.equals( command ) ) {
592                                removeSessionAttribute( ERR_MSG_ID );
593                        }
594                }
595
596                final String label = buf.toString();
597                // dispErrorで表示をコントロール
598                if( dispError ) { jspPrint( label ); }
599
600                // 検索結果の件数を、"DB.COUNT" キーでリクエストにセットします。
601                setRequestAttribute( "DB.COUNT"   , String.valueOf( executeCount ) );
602                // 検索結果を、"DB.ERR_CODE" キーでリクエストにセットします。
603                setRequestAttribute( "DB.ERR_CODE", String.valueOf( errCode ) );
604                // エラーメッセージを、"DB.ERR_MSG" キーでリクエストにセットします。
605                setRequestAttribute( "DB.ERR_MSG", label );
606
607                return errCode;
608        }
609
610        /**
611         * IOr の 要求結果から、値を取り出し、DBTableModel を作成します。
612         *
613         * @param       strJson Json形式の文字列
614         * @return      テーブルモデル
615         * @og.rtnNotNull
616         */
617        private DBTableModel makeDBTable( final SplitReqJson strJson ) {
618                final DBTableModel table = DBTableModelUtil.newDBTable();
619
620                // ---------------------------------------------------------------------
621                // テーブルモデルの列 ("headers"から"rows"までの文字列)
622                // 例:"headers": [{"display_label": "品目番号", "display": "PN"}, … ]
623                // ---------------------------------------------------------------------
624                final String rtnClm = strJson.getClmJson();
625
626                // 中括弧({})で分割
627                final JSONScan scanClm = new JSONScan( rtnClm, '{', '}' );
628                final int cntClm = scanClm.countBlock();
629                table.init( cntClm );
630                int i = 0;
631
632                while( scanClm.hasNext() ) {
633                        final String clms = scanClm.next();
634
635                        // キーと値をマッピングします。
636                        final Map<String,String> mapClm = JSONScan.json2Map( clms );
637                        final String clmLbl = mapClm.get( IOR_DISP_LBL );                                       // ラベル(例:品目番号)
638                        final String clmKey = mapClm.get( IOR_DISP_KEY );                                       // キー(例:PN)
639
640                        // テーブルモデルに列を追加します。
641                        final DBColumn dbColumn = getResource().makeDBColumn( clmKey, clmLbl );
642                        table.setDBColumn( i++, dbColumn );
643                }
644
645                // ---------------------------------------------------------------------
646                // テーブルモデルの行 ("cols"から最後の文字列)
647                // 例:"rows": [{"cols": [1, "GEN", "20211130", 32.4, "kg"]}, … ]}}
648                // ---------------------------------------------------------------------
649                final String rtnRow = strJson.getRowJson();
650
651                // 大括弧([])で分割
652                final JSONScan scanRow = new JSONScan( rtnRow, '[', ']' );
653                while( scanRow.hasNext() ) {
654                        final String rows = scanRow.next();
655                        final String[] vals = JSONScan.json2Array( rows );
656                        // テーブルモデルに行の値を追加します。
657                        table.addColumnValues( vals );
658                }
659                return table;
660        }
661
662        /**
663         * 処理後のメッセージを作成します。
664         *
665         * @return      エラーコード
666         * @og.rtnNotNull
667         */
668        protected int makeMessage() {
669                int errCode = ErrorMessage.OK;                                                                                          // エラーコード
670                final ErrorMessage errMessage = new ErrorMessage( "iorQueryTag Error!" );       // エラーメッセージ
671                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );                           // バッファ
672
673                // 実行結果を画面上に表示します。
674                if( CMD_NEW.equals( command ) && executeCount > 0
675                        && displayMsg != null && displayMsg.length() > 0 ) {
676                                buf.append( executeCount )
677                                        .append( getResource().getLabel( displayMsg ) )
678                                        .append( BR );
679                }
680
681                // 「ERR0041:検索処理中に割り込みの検索要求がありました」エラーを、標準のErrorMessageに追加するようにします。
682                if( table != null && ! commitTableObject( tableId, table ) ) {
683                        // ERR0041:検索処理中に割り込みの検索要求がありました。処理されません。
684                        errCode = ErrorMessage.NG;
685                        errMessage.addMessage( 0, errCode, "ERR0041" );
686                }
687
688                // TaglibUtil.makeHTMLErrorTable メソッドを利用します。
689                final String err = TaglibUtil.makeHTMLErrorTable( errMessage, getResource() );
690                if( err != null && err.length() > 0 ) {
691                        buf.append( err );
692                        setSessionAttribute( ERR_MSG_ID, errMessage );
693                }
694                else if( CMD_NEW.equals( command ) ) {
695                        removeSessionAttribute( ERR_MSG_ID );
696                }
697                final String label = buf.toString();
698                // dispErrorで表示をコントロール
699                if( dispError ) { jspPrint( label ); }
700
701                // 検索結果を、"DB.ERR_CODE" キーでリクエストにセットします。
702                setRequestAttribute( "DB.ERR_CODE", String.valueOf( errCode ) );
703                // エラーメッセージを、"DB.ERR_MSG" キーでリクエストにセットします。
704                setRequestAttribute( "DB.ERR_MSG", label );
705
706                return errCode;
707        }
708
709        /**
710         * 【TAG】アクセスする接続先URLを指定します。
711         *
712         * @og.tag
713         * 接続するURLを指定します。(例:http:// ・・・・・・)
714         *
715         * @param       url     接続先
716         */
717        public void setUrl( final String url ) {
718                urlStr = nval( getRequestParameter( url ),urlStr );
719        }
720
721        /**
722         * 【TAG】プロキシ経由で接続する場合の、プロキシホスト名を指定します。
723         *
724         * @og.tag
725         * 接続先が、プロキシ経由の場合、プロキシのホスト名を指定します。
726         * 例:proxy.opengion.org
727         *
728         * @param       host    プロキシホスト名
729         */
730        public void setProxyHost( final String host ) {
731                proxyHost = nval( getRequestParameter( host ),proxyHost );
732        }
733
734        /**
735         * 【TAG】プロキシ経由で接続する場合の、プロキシポート番号を指定します。
736         *
737         * @og.tag
738         * 接続先が、プロキシ経由の場合、プロキシのポート番号を指定します。
739         * 例:8080
740         *
741         * @param       port    プロキシポート番号
742         */
743        public void setProxyPort( final String port ) {
744                proxyPort = nval( getRequestParameter( port ),proxyPort );
745        }
746
747        /**
748         * 【TAG】接続タイムアウト時間を(秒)で指定します
749         *        (初期値:URL_CONNECT_TIMEOUT[={@og.value SystemData#URL_CONNECT_TIMEOUT}])。
750         *
751         * @og.tag
752         * 実際には、java.net.URLConnection#setConnectTimeout(int) に 1000倍して設定されます。
753         * 0 は、無限のタイムアウト、マイナスは、設定しません。(つまりJavaの初期値のまま)
754         * (初期値:システム定数のURL_CONNECT_TIMEOUT[={@og.value SystemData#URL_CONNECT_TIMEOUT}])。
755         *
756         * @param       tout    タイムアウト時間(秒) (ゼロは、無制限)
757         * @see         org.opengion.fukurou.util.HttpConnect#setTimeout(int)
758         * @see         java.net.URLConnection#setConnectTimeout(int)
759         */
760        public void setTimeout( final String tout ) {
761                timeout = nval( getRequestParameter( tout ),timeout );
762        }
763
764        /**
765         * 【TAG】JSONコードで認証するURLを指定します。
766         *
767         * @og.tag
768         * JSONコードで認証するURLを指定します。
769         *
770         * @param       url     JSONコードで認証するURL
771         */
772        public void setAuthURL( final String url ) {
773                authURL = nval( getRequestParameter( url ), authURL );
774        }
775
776        /**
777         * 【TAG】Basic認証を使用して接続する場合のユーザー:パスワードを指定します。
778         *
779         * @og.tag
780         * 接続時のユーザーとパスワードを、USER:PASSWD 形式で指定します。
781         *
782         * @param       userPass        ユーザーとパスワード (USER:PASSWD形式)
783         */
784        public void setAuthUserPass( final String userPass ) {
785                authUserPass = nval( getRequestParameter( userPass ),authUserPass );
786        }
787
788        /**
789         * 【TAG】企業IDを指定します。
790         *
791         * @og.tag
792         * 企業IDを指定します。
793         *
794         * @param       compId  企業ID
795         */
796        public void setCompanyId( final String compId ) {
797                companyId = nval( getRequestParameter( compId ),companyId );
798        }
799
800        /**
801         * 【TAG】アプリケーションの名前を指定します。
802         *
803         * @og.tag
804         * アプリケーションの名前を指定します。
805         *
806         * @param       appName データテーブル情報
807         */
808        public void setAppliName( final String appName ) {
809                appliName = nval( getRequestParameter( appName ),appliName );
810        }
811
812        /**
813         * 【TAG】関数名を指定します。
814         *
815         * @og.tag
816         * 関数名を指定します。
817         *
818         * @param       callMh  関数名
819         */
820        public void setCallMethod( final String callMh ) {
821                callMethod = nval( getRequestParameter( callMh ),callMethod );
822        }
823
824        /**
825         * 【TAG】接続の結果を表示するかどうかを指定します(初期値:false)。
826         *
827         * @og.tag
828         * true で、接続結果を表示します。 false では、何も表示しません(初期値:false)
829         * 接続結果を表示する使い方より、admin 画面に接続して、キャッシュクリアするような
830         * 使い方が多いと考え、初期値は、false になっています。
831         * display="true" と、saveFile を併用することはできません。
832         *
833         * @param       flag    結果表示 [true:する/false:しない]
834         * @see         #setSaveFile( String )
835         */
836        public void setDisplay( final String flag ) {
837                display = nval( getRequestParameter( flag ),display );
838
839                if( display && saveFile != null ) {
840                        final String errMsg = "display=\"true\" と、saveFile を併用することはできません。";
841                        throw new HybsSystemException( errMsg );
842                }
843        }
844
845        /**
846         * 【TAG】接続の結果をファイルに保存します。
847         *
848         * @og.tag
849         * 接続先のデータを受け取って、ファイルに保存します。
850         * display="true" と、saveFile を併用することはできません。
851         * loadFile が指定されていない時のみ処理を行います。
852         *
853         * @param       file    保存先ファイル
854         * @see         #setDisplay( String )
855         */
856        public void setSaveFile( final String file ) {
857                saveFile = nval( getRequestParameter( file ),saveFile );
858                if( saveFile != null ) {
859                        saveFile = HybsSystem.url2dir( StringUtil.urlAppend( fileURL,saveFile ) );
860                        if( display ) {
861                                final String errMsg = "display=\"true\" と、saveFile を併用することはできません。";
862                                throw new HybsSystemException( errMsg );
863                        }
864                }
865        }
866
867        /**
868         * 【TAG】ファイルからURL接続結果に相当するデータを読み取ります。
869         *
870         * @og.tag
871         * 主にデバッグ用として使われます。
872         *
873         * @param       file    検索するファイル
874         */
875        public void setLoadFile( final String file ) {
876                loadFile = nval( getRequestParameter( file ),loadFile );
877                if( loadFile != null ) {
878                        loadFile = HybsSystem.url2dir( StringUtil.urlAppend( fileURL,loadFile ) );
879                }
880        }
881
882        /**
883         * 【TAG】コマンド (NEW,RENEW)をセットします。
884         *
885         * @og.tag
886         * コマンドは、HTMLから(get/post)指定されますので、
887         * CMD_xxx で設定されるフィールド定数値のいづれかを指定できます。
888         *
889         * @param       cmd     コマンド (public static final 宣言されている文字列)
890         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.QueryTag.CMD_NEW">コマンド定数</a>
891         */
892        public void setCommand( final String cmd ) {
893                final String cmd2 = getRequestParameter( cmd );
894                if( cmd2 != null && cmd2.length() >= 0 ) { command = cmd2.toUpperCase( Locale.JAPAN ); }
895        }
896
897        /**
898         * 【TAG】検索結果を画面上に表示するメッセージリソースIDを指定します
899         *        (初期値:VIEW_DISPLAY_MSG[={@og.value SystemData#VIEW_DISPLAY_MSG}])。
900         *
901         * @og.tag
902         * ここでは、検索結果の件数や登録された件数をまず出力し、
903         * その次に、ここで指定したメッセージをリソースから取得して表示します。
904         * 件数を表示させる場合は、displayMsg = "MSG0033"[ 件検索しました] をセットしてください。
905         * 表示させたくない場合は, displayMsg = "" をセットしてください。
906         * (初期値:システム定数のVIEW_DISPLAY_MSG[={@og.value SystemData#VIEW_DISPLAY_MSG}])。
907         *
908         * @param       id      表示メッセージID
909         * @see         org.opengion.hayabusa.common.SystemData#VIEW_DISPLAY_MSG
910         */
911        public void setDisplayMsg( final String id ) {
912                final String ids = getRequestParameter( id );
913                if( ids != null ) { displayMsg = ids; }
914        }
915
916        /**
917         * 【TAG】検索結果がゼロ件の場合に表示するメッセージリソースIDを指定します(初期値:MSG0077[対象データはありませんでした])。
918         *
919         * @og.tag
920         * ここでは、検索結果がゼロ件の場合のみ、特別なメッセージを表示させます。
921         * 従来は、displayMsg と兼用で、『0 件検索しました』という表示でしたが、
922         * displayMsg の初期表示は、OFF になりましたので、ゼロ件の場合のみ別に表示させます。
923         * 表示させたくない場合は, notfoundMsg = "" をセットしてください。
924         * 初期値は、MSG0077[対象データはありませんでした]です。
925         *
926         * @param       id      ゼロ件メッセージID
927         */
928        public void setNotfoundMsg( final String id ) {
929                final String ids = getRequestParameter( id );
930                if( ids != null ) { notfoundMsg = ids; }
931        }
932
933        /**
934         * 【TAG】検索結果が0件のとき処理を停止するかどうか[true/false]を指定します(初期値:false[続行する])。
935         *
936         * @og.tag
937         * 初期値は、false(続行する)です。
938         *
939         * @param       flag    0件時停止可否 [true:処理を中止する/false:続行する]
940         */
941        public void setStopZero( final String flag ) {
942                stopZero = nval( getRequestParameter( flag ),stopZero );
943        }
944
945        /**
946         * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します
947         *        (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。
948         *
949         * @og.tag
950         * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に
951         * 渡す場合に、通常は、session を利用します。その場合の登録キーです。
952         * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、
953         * この tableId 属性を利用して、メモリ空間を分けます。
954         *(初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。
955         *
956         * @param       id      テーブルID (sessionに登録する時のID)
957         */
958        public void setTableId( final String id ) {
959                tableId = nval( getRequestParameter( id ),tableId );
960        }
961
962        /**
963         * 【TAG】処理エラーの時に処理を中止するかどうか[true/false]を設定します(初期値:true)。
964         *
965         * @og.tag
966         * false(中止しない)に設定する場合、後続処理では、{&#064;DB.ERR_CODE}の値により、
967         * IOr の異常/正常終了によって分岐処理は可能となります。
968         * 初期値は、true(中止する)です。
969         *
970         * @param       flag    エラー時処理中止 [true:中止する/false:中止しない]
971         */
972        public void setStopError( final String flag ) {
973                stopError = nval( getRequestParameter( flag ),stopError );
974        }
975
976        /**
977         * 【TAG】PLSQL/SQL処理エラーの時にエラーを画面表示するか[true/false]を設定します(初期値:true)。
978         *
979         * @og.tag
980         * false(表示しない)に設定する場合、後続処理では、{&#064;DB.ERR_MSG}の値により、
981         * 本来表示されるはずだったメッセージを取得可能です。
982         * stopErrorと併用して、JSON形式でエラーを返す場合等に利用します。
983         * 初期値は、true(表示する)です。
984         * ※false指定の場合は件数や、overFlowメッセージ等も表示されなくなります。
985         *
986         * @param       flag    [true:表示する/false:表示しない]
987         */
988        public void setDispError( final String flag ) {
989                dispError = nval( getRequestParameter( flag ),dispError );
990        }
991
992        /**
993         * 【TAG】リクエスト情報の シングルクォート(') 存在チェックを実施するかどうか[true/false]を設定します
994         *        (初期値:USE_SQL_INJECTION_CHECK[={@og.value SystemData#USE_SQL_INJECTION_CHECK}])。
995         *
996         * @og.tag
997         * SQLインジェクション対策の一つとして、暫定的ではありますが、SQLのパラメータに
998         * 渡す文字列にシングルクォート(') を許さない設定にすれば、ある程度は防止できます。
999         * 数字タイプの引数には、 or 5=5 などのシングルクォートを使用しないコードを埋めても、
1000         * 数字チェックで検出可能です。文字タイプの場合は、必ず (')をはずして、
1001         * ' or 'A' like 'A のような形式になる為、(')チェックだけでも有効です。
1002         * (') が含まれていたエラーにする(true)/かノーチェックか(false)を指定します。
1003         * 初期値は、SystemData#USE_SQL_INJECTION_CHECK です。
1004         *
1005         * @param       flag    クォートチェック [true:する/それ以外:しない]
1006         */
1007        public void setQuotCheck( final String flag ) {
1008                quotCheck = nval( getRequestParameter( flag ),quotCheck );
1009        }
1010
1011        /**
1012         * 【TAG】リクエスト情報の HTMLTag開始/終了文字(&gt;&lt;) 存在チェックを実施するかどうか[true/false]を設定します
1013         *        (初期値:USE_XSS_CHECK[={@og.value SystemData#USE_XSS_CHECK}])。
1014         *
1015         * @og.tag
1016         * クロスサイトスクリプティング(XSS)対策の一環としてless/greater than signについてのチェックを行います。
1017         * (&gt;&lt;) が含まれていたエラーにする(true)/かノーチェックか(false)を指定します。
1018         * (初期値:システム定数のUSE_XSS_CHECK[={@og.value SystemData#USE_XSS_CHECK}])
1019         *
1020         * @param       flag    XSSチェック [true:する/false:しない]
1021         * @see         org.opengion.hayabusa.common.SystemData#USE_XSS_CHECK
1022         */
1023        public void setXssCheck( final String flag ) {
1024                xssCheck = nval( getRequestParameter( flag ),xssCheck );
1025        }
1026
1027        /**
1028         * 【TAG】(通常は使いません)タグで処理される処理がメインとなるトランザクション処理かどうかを指定します(初期値:true)。
1029         *
1030         * @og.tag
1031         * この値は、ファイルダウンロード処理に影響します。この値がtrueに指定された時にcommitされたDBTableModelが
1032         * ファイルダウンロードの対象の表になります。
1033         *
1034         * このパラメーターは、通常、各タグにより実装され、ユーザーが指定する必要はありません。
1035         * 但し、1つのJSP内でDBTableModelが複数生成される場合に、前に処理したDBTableModelについてファイルダウンロードをさせたい
1036         * 場合は、後ろでDBTableModelを生成するタグで、明示的にこの値をfalseに指定することで、ファイルダウンロード処理の対象から
1037         * 除外することができます。
1038         *
1039         * @param       flag    メイントランザクションかどうか [true:メイン/false:その他]
1040         */
1041        public void setMainTrans( final String flag ) {
1042                isMainTrans = nval( getRequestParameter( flag ),isMainTrans );
1043        }
1044
1045        /**
1046         * 【TAG】処理時間(queryTime)などの情報出力[true:有効/false:無効]を指定します(初期値:true)。
1047         *
1048         * @og.tag
1049         * Query で、検索する場合に、処理時間(queryTime)などの情報を出力していますが、
1050         * ViewForm で、CustomData などの 非HTML表示ビューを使用する場合、データとして、
1051         * 紛れ込んでしまうため、出力を抑制する必要があります。
1052         * true(有効)にすると、これらのHTMLが出力されます。false にすると、出力されません。
1053         * 初期値は、true(有効) です。
1054         *
1055         * @param       useTag  情報出力の有効/無効 [true:有効/false:無効]
1056         */
1057        public void setUseBeforeHtmlTag( final String useTag ) {
1058                useBeforeHtmlTag = nval( getRequestParameter( useTag ),useBeforeHtmlTag );
1059        }
1060
1061        /**
1062         * 【TAG】処理時間を表示する TimeView を表示するかどうか[true:する/false:しない]を指定します
1063         *        (初期値:VIEW_USE_TIMEBAR[={@og.value SystemData#VIEW_USE_TIMEBAR}])。
1064         *
1065         * @og.tag
1066         * true に設定すると、処理時間を表示するバーイメージが表示されます。
1067         * これは、DB検索、APサーバー処理、画面表示の各処理時間をバーイメージで
1068         * 表示させる機能です。処理時間の目安になります。
1069         * (初期値:VIEW_USE_TIMEBAR[={@og.value SystemData#VIEW_USE_TIMEBAR}])。
1070         *
1071         * @param       flag    処理時間を表示 [true:する/false:しない]
1072         */
1073        public void setUseTimeView( final String flag ) {
1074                useTimeView = nval( getRequestParameter( flag ),useTimeView );
1075        }
1076
1077        /**
1078         * IOr の応答結果を特定のキーワードで分割します。(内部クラス)
1079         *
1080         * フォーマット形式のチェック と データの切り出しを行います。
1081         * JSONフォーマットの例:{"status": … "data": {"headers": [ … ], "rows": [ {cols:[ … ]} ]}}
1082         */
1083        private static final class SplitReqJson {
1084                private final String    strJson;                                                                                // JSON形式の文字列
1085                private int                             endPos;                                                                                 // 終了位置
1086
1087                /**
1088                 * コンストラクター
1089                 *
1090                 * @param       strJson JSON形式の文字列
1091                 */
1092                public SplitReqJson( final String str ) {
1093                        strJson         = str;                                                                                                  // JSON形式の文字列
1094                        endPos          = strJson.indexOf( "\"data\"" );                                                // 終了位置
1095                }
1096
1097                /**
1098                 * HTTPステータス(先頭から "data"まで) の文字列を返します。
1099                 *
1100                 * @return      JSON形式の文字列
1101                 */
1102                public String getSttsJson() {
1103                        if( endPos >= 0 ) {
1104                                return strJson.substring( 0, endPos );
1105                        } else {
1106                                final String errMsg = "data キーが存在しません。";
1107                                throw new HybsSystemException( errMsg );
1108                        }
1109                }
1110
1111                /**
1112                 * 列データ("headers"から "rows"まで) の文字列を返します。
1113                 *
1114                 * @return      JSON形式の文字列
1115                 */
1116                public String getClmJson() {
1117                        final int startPos      = strJson.indexOf( "\"headers\"", endPos );             // 開始位置
1118                        endPos  = strJson.indexOf( "\"rows\"", startPos );                                      // 終了位置
1119                        if( startPos >= 0 && endPos >= 0) {
1120                                return strJson.substring( startPos, endPos );
1121                        } else {
1122                                final String errMsg = "headers、rows キーのいずれかが存在しません。";
1123                                throw new HybsSystemException( errMsg );
1124                        }
1125                }
1126
1127                /**
1128                 * 行データ("cols"から 最後まで) の文字列を返します。
1129                 *
1130                 * @return      JSON形式の文字列
1131                 */
1132                public String getRowJson() {
1133                        final int startPos      = strJson.indexOf( "\"cols\"", endPos );                // 開始位置
1134                        if( startPos >= 0 ) {
1135                                return strJson.substring( startPos );
1136                        } else {
1137                                final String errMsg = "cols キーが存在しません。";
1138                                throw new HybsSystemException( errMsg );
1139                        }
1140                }
1141        }
1142
1143        /**
1144         * このオブジェクトの文字列表現を返します。
1145         * 基本的にデバッグ目的に使用します。
1146         *
1147         * @return      このクラスの文字列表現
1148         * @og.rtnNotNull
1149         */
1150        @Override
1151        public String toString() {
1152                return ToString.title( this.getClass().getName() )
1153                                .println( "VERSION"                     ,VERSION                )
1154                                .println( "urlStr"                      ,urlStr                 )
1155                                .println( "timeout"                     ,timeout                )
1156                                .println( "authURL"                     ,authURL                )
1157                                .println( "authUserPass"        ,authUserPass   )
1158                                .println( "companyId"           ,companyId              )
1159                                .println( "appliName"           ,appliName              )
1160                                .println( "callMethod"          ,callMethod             )
1161                                .println( "display"                     ,display                )
1162                                .println( "postData"            ,postData               )
1163                                .println( "saveFile"            ,saveFile               )
1164                                .println( "loadFile"            ,loadFile               )
1165                                .println( "tableId"                     ,tableId                )
1166                                .println( "Other..."            ,getAttributes().getAttribute() )
1167                                .fixForm().toString() ;
1168        }
1169}