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