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