    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 *     &lt;og:iorQuery
    070 *         url           = "http://･･･ "    必須
    071 *         authURL       = "http://･･･ "    必須
    072 *         authUserPass  = "admin:******"   必須
    073 *         appliName     = "ﾃﾞｰﾀﾃｰﾌﾞﾙ名"
    074 *         callMethod    = "getReportInfo"
    075 *     /&gt;
    076 *
    077 * ●body：あり(EVAL_BODY_BUFFERED:BODYを評価し、{&#064;XXXX} を解析します)
    078 *
    079 * ●Tag定義：
    080 *   &lt;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】検索結果が０件のとき処理を続行するかどうか[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開始/終了文字(&gt;&lt;) 存在ﾁｪｯｸを実施するかどうか[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 *   &gt;   ... Body ...
    119 *   &lt;/og:iorQuery&gt;
    120 *
    121 * ●使用例
    122 *     &lt;og:iorQuery
    123 *         url           = "http://･･･ "
    124 *         authURL       = "http://･･･ "
    125 *         authUserPass  = "admin:******"
    126 *         appliName     = "ﾃﾞｰﾀﾃｰﾌﾞﾙ名"
    127 *         callMethod    = "getReportInfo"
    128 *     &gt;
    129 *         &lt;og:iorQueryParam
    130 *             key  = "where"  value  = "{'PN':'{&#064;PN}%','TANI':'{&#064;TANI}'}"  /&gt;
    131 *         &lt;/og:iorQueryParam
    132 *     &lt;/og:iorQuery ･････ &gt;
    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】検索結果が０件のとき処理を停止するかどうか[true/false]を指定します(初期値:false[続行する])。
    959         *
    960         * @og.tag
    961         * 初期値は、false(続行する)です。
    962         *
    963         * @param       flag    ０件時停止可否 [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}