    001/*
    002 * Copyright (c) 2009 The openGion Project.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *     http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
    013 * either express or implied. See the License for the specific language
    014 * governing permissions and limitations under the License.
    015 */
    016package org.opengion.hayabusa.taglib;
    017
    018import org.opengion.hayabusa.common.HybsSystem;
    019import org.opengion.hayabusa.common.HybsSystemException;
    020import org.opengion.hayabusa.db.DBTableModel;
    021import org.opengion.fukurou.util.ErrorMessage;
    022import org.opengion.fukurou.util.FileUtil;
    023import org.opengion.fukurou.util.ToString;                                              // 6.1.1.0 (2015/01/17)
    024import org.opengion.fukurou.util.ArraySet;                                              // 6.4.3.4 (2016/03/11)
    025import org.opengion.fukurou.util.StringUtil;                                    // 7.2.7.0 (2020/08/07)
    026
    027import static org.opengion.fukurou.util.StringUtil.nval ;
    028import static org.opengion.fukurou.system.HybsConst.BR;                 // 6.1.0.0 (2014/12/26) refactoring
    029
    030import java.util.Locale ;
    031import java.util.Set ;
    032// import java.util.TreeSet ;
    033// import java.util.Comparator ;
    034import java.io.File ;
    035// import java.io.Serializable;
    036import java.io.IOException ;                                                                    // 7.0.5.0 (2019/09/13)
    037
    038/**
    039 * ファイル検索リストを元に、action に基づいた処理を行うタグです。
    040 * command="ENTRY" 時のみ処理を行います。
    041 *
    042 * fileQuery などで検索したファイル一覧のDBTableModel を元に、ファイルの
    043 * コピー(COPY)、移動(MOVE,MODIFY)、削除(DELETE)などの処理を行います。
    044 * 処理を行うオリジナルファイルは、PARENT,NAME というカラムでなければなりません。
    045 *   ※ 7.2.7.0 (2020/08/07) parentClm,nameClm で指定可能になりました。
    046 * このカラム名は、fileQuery の検索時には、必ず作成されるカラムです。
    047 * また、各アクションに対応するターゲットファイルは、TO_PARENT,TO_NAME という
    048 * カラムで指定するか、targetDir 属性を利用してフォルダを指定します。
    049 * TO_PARENT(先フォルダ)と、TO_NAME(先ファイル名)は、処理に応じて、必要なカラムが
    050 * あれば、自動的に処理します。
    051 * つまり、TO_PARENT のみの場合は、ファイル名はオリジナルのまま、フォルダのみ変更します。
    052 * 逆に、TO_NAME の場合は、フォルダはそのままで、ファイル名のみ指定します。
    053 * 両方同時に指定することも可能です。
    054 * targetDir 属性で指定する場合は、TO_PARENT のみに同じ値を設定した場合と同じになります。
    055 * この属性を指定すると、TO_PARENT は無視されます。(TO_NAME は有効です。)
    056 * COPY、MOVE(,MODIFY) の場合は、指定のフォルダに一括処理可能です。
    057 * COPY、MOVE(,MODIFY) などの処理で、ターゲットフォルダが存在しないときに、作成するか、エラーにするかは
    058 * createDir属性 で指定できます。初期値は、(true:作成する) です。
    059 * これは、COPY先やMOVE(,MODIFY)先が存在している前提のシステムで、不要な箇所に間違ってフォルダを
    060 * 自動作成されると困る場合に、(false:作成しない) とすれば、間違いに気づく確率が上がります。
    061 *
    062 *   ※ 7.2.7.0 (2020/08/07) PARENT,NAME,TO_PARENT,TO_NAME のｶﾗﾑ名を指定できるようにしました。
    063 *      action にMKDIRS を追加しました。これは、TO_PARENT ﾌｫﾙﾀﾞが作成できるかどうかを判定します。
    064 *
    065 * ※ このタグは、Transaction タグの対象ではありません。
    066 *
    067 * @og.formSample
    068 * ●body：なし
    069 * ●形式：
    070 *      ・&lt;og:fileUpdate
    071 *          action        = "COPY|MOVE|MODIFY|DELETE|MKDIRS" アクション属性(必須)
    072 *          command       = "[ENTRY]"                 ENTRY 時のみ実行します(初期値:ENTRY)
    073 *          targetDir     = "[指定フォルダ]"          ターゲットとなるフォルダ
    074 *          createDir     = "[true/false]"            ターゲットとなるフォルダがなければ作成する(true)かどうか(初期値:true)
    075 *          tableId       = [HybsSystem.TBL_MDL_KEY]  DBTableModel を取り出すキー
    076 *          displayMsg    = "MSG0040";                処理結果を表示します(初期値:｢　件登録しました。｣)
    077 *          selectedAll   = "[false/true]"            データを全件選択済みとして処理する(true)かどうか指定(初期値:false)
    078 *          keepTimeStamp = "[false/true]"            COPY,親違いMOVE(,MODIFY)の時にオリジナルのタイムスタンプを使用するかどうか(初期値:false)
    079 *      /&gt;
    080 *
    081 *    [action属性(必須)]
    082 *      COPY   オリジナルファイルを、ターゲット(TO_PARENT,TO_NAMEで指定)にコピーします。
    083 *      MOVE   オリジナルファイルを、ターゲットに移動(COPY+DELETE)/名称変更(RENAME)します。
    084 *      MODIFY (MOVE と同じ。エンジンの command を利用するための簡易action)
    085 *      DELETE オリジナルファイルを削除します(ターゲット(TO_PARENT,TO_NAME)は、関係しません)。
    086 *      MKDIRS ターゲット(TO_PARENTで指定)フォルダを作成します。(PARENT,NAME,TO_NAMEは、関係しません)。 7.2.7.0 (2020/08/07) 新規追加
    087 *
    088 * ●Tag定義：
    089 *   &lt;og:fileUpdate
    090 *       action           ○【TAG】アクション[COPY|MOVE|MODIFY|DELETE|MKDIRS]をセットします(必須)。
    091 *       command            【TAG】コマンド[ENTRY]をセットします(初期値:ENTRY)
    092 *       targetDir          【TAG】ターゲットとなるフォルダを指定します
    093 *       createDir          【TAG】ターゲットとなるフォルダがなければ、作成するかどうかを指定します(初期値:true)
    094 *       parentClm          【TAG】7.2.7.0 (2020/08/07) fileQuery以外の場合の元親ﾌｫﾙﾀﾞを示すｶﾗﾑ名を指定します(初期値:"PARENT")
    095 *       nameClm            【TAG】7.2.7.0 (2020/08/07) fileQuery以外の場合の元ﾌｧｲﾙ名を示すｶﾗﾑ名を指定します(初期値:"NAME")
    096 *       toParentClm        【TAG】7.2.7.0 (2020/08/07) fileQuery以外の場合の先親ﾌｫﾙﾀﾞを示すｶﾗﾑ名を指定します(初期値:"TO_PARENT")
    097 *       toNameClm          【TAG】7.2.7.0 (2020/08/07) fileQuery以外の場合の先ﾌｧｲﾙ名を示すｶﾗﾑ名を指定します(初期値:"TO_NAME")
    098 *       tableId            【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します
    099 *       scope              【TAG】キャッシュする場合のスコープ[request/page/session/application]を指定します(初期値:session)
    100 *       displayMsg         【TAG】処理結果を画面上に表示するﾒｯｾｰｼﾞﾘｿｰｽIDを指定します(初期値:MSG0040[　件登録しました])
    101 *       actErrMsg          【TAG】7.2.7.0 (2020/08/07) action実行時のｴﾗｰﾒｯｾｰｼﾞのﾒｯｾｰｼﾞﾘｿｰｽIDを指定します(初期値:ERR0050:ｱｸｼｮﾝ実行中にｴﾗｰが発生しました。ｱｸｼｮﾝ:{0} From:{1} To:{2})
    102 *       selectedAll        【TAG】データを全件選択済みとして処理するかどうか[true/false]を指定します(初期値:false)
    103 *       keepTimeStamp      【TAG】オリジナルのタイムスタンプを利用するかどうかを指定します(初期値:false)
    104 *       inPath             【TAG】6.8.0.0 (2017/06/02) 入力共通パスを指定します(PARENTフォルダの共通部分、COPY/MOVE時にtargetDirと置換されます) 。
    105 *       useTimeView        【TAG】処理時間を表示する TimeView を表示するかどうかを指定します
    106 *                                      (初期値:VIEW_USE_TIMEBAR[={@og.value SystemData#VIEW_USE_TIMEBAR}])。
    107 *       useSLabel          【TAG】7.0.7.0 (2019/12/13) ｴﾗｰﾒｯｾｰｼﾞにSLABELを利用するかどうか[true/false]を指定します(初期値:false)
    108 *       useStop            【TAG】7.2.7.0 (2020/08/07) エラー時に処理後に停止するかどうか[true/false]を指定します(初期値:true)
    109 *       caseKey            【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null)
    110 *       caseVal            【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null)
    111 *       caseNN             【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない)
    112 *       caseNull           【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない)
    113 *       caseIf             【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない)
    114 *       debug              【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false)
    115 *   /&gt;
    116 *
    117 * ●使用例
    118 *       ・&lt;og:fileUpdate command="{&#064;command}" action="COPY" /&gt;
    119 *             TO_PARENT または、 TO_NAME(両方指定も可)による行単位 COPY 処理
    120 *             fileQuery の useUpdateClm="true" を設定し、検索結果に、TO_PARENT、 TO_NAMEカラムを追加します。
    121 *             TO_PARENT または、 TO_NAME は、columnSet などで値をセットしておきます。
    122 *
    123 *       ・&lt;og:fileUpdate command="{&#064;command}" action="MODIFY" targetDir="AAA_DIR"  /&gt;
    124 *             fileQuery の検索結果を、AAA_DIR フォルダに移動します。
    125 *             ファイル名は、そのままオリジナルの値が使用されます。
    126 *
    127 * @og.rev 5.3.4.0 (2011/04/01) 新規追加
    128 * @og.group ファイル出力
    129 *
    130 * @version  4.0
    131 * @author       Kazuhiko Hasegawa
    132 * @since    JDK5.0,
    133 */
    134public class FileUpdateTag extends CommonTagSupport {
    135        /** このプログラムのVERSION文字列を設定します。   {@value} */
    136        private static final String VERSION = "7.2.9.4 (2020/11/20)" ;
    137        private static final long serialVersionUID = 729420201120L ;
    138
    139        /** command 引数に渡す事の出来る コマンド  登録{@value} */
    140        public static final String CMD_ENTRY  = "ENTRY" ;
    141        /** command 引数に渡す事の出来る コマンド リスト  */
    142        // 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。
    143        private static final Set<String> COMMAND_SET = new ArraySet<>( CMD_ENTRY );
    144
    145        /** エラーメッセージID {@value} */
    146        private static final String ERR_MSG_ID  = HybsSystem.ERR_MSG_KEY;               // 6.4.1.1 (2016/01/16) errMsgId → ERR_MSG_ID  refactoring
    147
    148        /** action 引数に渡す事の出来る アクションコマンド  COPY {@value} */
    149        public static final String ACT_COPY             = "COPY" ;
    150        /** action 引数に渡す事の出来る アクションコマンド  MOVE {@value} */
    151        public static final String ACT_MOVE             = "MOVE" ;
    152        /** action 引数に渡す事の出来る アクションコマンド  MODIFY {@value} */
    153        public static final String ACT_MODIFY   = "MODIFY" ;
    154        /** action 引数に渡す事の出来る アクションコマンド  DELETE {@value} */
    155        public static final String ACT_DELETE   = "DELETE" ;
    156        /** action 引数に渡す事の出来る アクションコマンド  MKDIRS {@value} */
    157        public static final String ACT_MKDIRS   = "MKDIRS" ;                                            // 7.2.7.0 (2020/08/07)
    158        // 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。
    159//      private static final Set<String> ACTION_SET = new ArraySet<>( ACT_COPY , ACT_MOVE , ACT_MODIFY , ACT_DELETE );
    160        private static final Set<String> ACTION_SET = new ArraySet<>( ACT_COPY , ACT_MOVE , ACT_MODIFY , ACT_DELETE ,ACT_MKDIRS );      // 7.2.7.0 (2020/08/07)
    161
    162        private String  action          ;
    163        private String  targetDir       ;                       // ターゲットとなるフォルダ
    164        private boolean createDir       = true;         // ターゲットとなるフォルダがなければ、作成するかどうか(true:作成する)
    165
    166        private String  inPath          ;                       // 6.8.0.0 (2017/06/02) 入力共通パスを指定します。
    167
    168        private String  parentClm       = "PARENT";             // 7.2.7.0 (2020/08/07) fileQuery以外の場合の元親ﾌｫﾙﾀﾞを示すｶﾗﾑ名を指定します(初期値:"PARENT")
    169        private String  nameClm         = "NAME";               // 7.2.7.0 (2020/08/07) fileQuery以外の場合の元ﾌｧｲﾙ名を示すｶﾗﾑ名を指定します(初期値:"NAME")
    170        private String  toParentClm     = "TO_PARENT";  // 7.2.7.0 (2020/08/07) fileQuery以外の場合の先親ﾌｫﾙﾀﾞを示すｶﾗﾑ名を指定します(初期値:"TO_PARENT")
    171        private String  toNameClm       = "TO_NAME";    // 7.2.7.0 (2020/08/07) fileQuery以外の場合の先ﾌｧｲﾙ名を示すｶﾗﾑ名を指定します(初期値:"TO_NAME")
    172
    173        private String  tableId         = HybsSystem.TBL_MDL_KEY;
    174        private String  command         = CMD_ENTRY;
    175//      private boolean outMessage      = true;                         // 7.2.7.0 (2020/08/07) 削除
    176        private String  displayMsg      = "MSG0040";            // 　件登録しました。
    177        private String  actErrMsg       = "ERR0050";            // 7.2.7.0 (2020/08/07) ｱｸｼｮﾝ実行中にｴﾗｰが発生しました。ｱｸｼｮﾝ:{0} From:{1} To:{2}
    178
    179        private boolean selectedAll ;
    180        private boolean keepTimeStamp;                                  // オリジナルのタイムスタンプを利用する場合、true
    181
    182        private transient DBTableModel  table           ;
    183        private transient ErrorMessage  errMessage      ;
    184        private int             executeCount    = -1;                   // 処理件数
    185        private int             errCode                 = ErrorMessage.OK;
    186        private boolean useTimeView             = HybsSystem.sysBool( "VIEW_USE_TIMEBAR" );             // 6.3.6.0 (2015/08/16)
    187        private boolean useSLabel               ;                               // 7.0.7.0 (2019/12/13) ｴﾗｰﾒｯｾｰｼﾞにSLABELを利用するかどうか[true/false]を指定します(初期値:false)
    188        private boolean useStop                 = true;                 // 7.2.7.0 (2020/08/07) エラー時に処理後に停止(true)するかどうか(useStop対応)
    189
    190        /**
    191         * デフォルトコンストラクター
    192         *
    193         * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor.
    194         */
    195        public FileUpdateTag() { super(); }             // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。
    196
    197        /**
    198         * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。
    199         *
    200         * @og.rev 6.4.4.1 (2016/03/18) 意味のない、StringBuilderだったので、廃止します。
    201         * @og.rev 6.9.9.0 (2018/08/20) ｢ERR0041:検索処理中に割り込みの検索要求がありました｣エラーを、標準のErrorMessageに追加するようにします。
    202         * @og.rev 7.0.7.0 (2019/12/13) useSLabel 属性を追加。
    203         * @og.rev 7.2.7.0 (2020/08/07) エラー時に処理後に停止(true)するかどうか(useStop対応)
    204         *
    205         * @return      後続処理の指示
    206         */
    207        @Override
    208        public int doEndTag() {
    209                debugPrint();
    210                // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応
    211                if( !useTag() ) { return EVAL_PAGE ; }
    212
    213                final long dyStart = System.currentTimeMillis();
    214
    215                table = (DBTableModel)getObject( tableId );
    216
    217                // 7.2.7.0 (2020/08/07) 出力のタイミングを、useStop の判定前に持ってきます。
    218//              String label  = "";                             // 4.0.0 (2005/11/30) 検索しなかった場合。
    219                if( table != null && table.getRowCount() > 0 && check( command, COMMAND_SET ) ) {
    220                        startQueryTransaction( tableId );
    221
    222                        execute();      // 実際の処理を実行します。
    223
    224                        setRequestAttribute( "DB.COUNT"   , String.valueOf( executeCount ) );
    225                        setRequestAttribute( "DB.ERR_CODE", String.valueOf( errCode ) );
    226
    227                        // 6.9.9.0 (2018/08/20) ｢ERR0041:検索処理中に割り込みの検索要求がありました｣エラーを、標準のErrorMessageに追加するようにします。
    228                        if( ! commitTableObject( tableId, table ) ) {
    229                                if( errMessage == null ) { errMessage = new ErrorMessage( "FileUpdateTag Query Error!" ); }
    230                                // ERR0041:検索処理中に割り込みの検索要求がありました。処理されません。
    231                                errMessage.addMessage( 0,ErrorMessage.NG,"ERR0041" );
    232                                errCode = ErrorMessage.NG;
    233                        }
    234
    235//                      final String err = TaglibUtil.makeHTMLErrorTable( errMessage,getResource() );
    236                        final String err = TaglibUtil.makeHTMLErrorTable( errMessage,getResource(),useSLabel );         // 7.0.7.0 (2019/12/13)
    237                        if( err != null && err.length() > 0 ) {
    238                                // 7.2.7.0 (2020/08/07) 出力のタイミングを、useStop の判定前に持ってきます。
    239//                              label = err ;           // 6.4.4.1 (2016/03/18)
    240                                jspPrint( err );        // 7.2.7.0 (2020/08/07)
    241                                setSessionAttribute( ERR_MSG_ID,errMessage );
    242                        }
    243
    244                        // 7.2.7.0 (2020/08/07) エラー時に処理後に停止(true)するかどうか
    245                        if( useStop && errCode >= ErrorMessage.NG ) {
    246                                return SKIP_PAGE ;
    247                        }
    248
    249//                      // 6.9.9.0 (2018/08/20) ｢ERR0041:検索処理中に割り込みの検索要求がありました｣エラーを、標準のErrorMessageに追加するようにします。
    250//                      if( table != null && ! commitTableObject( tableId, table ) ) {
    251//                              jspPrint( "FileUpdateTag Query処理が割り込まれました。DBTableModel は登録しません。" );
    252//                              return SKIP_PAGE ;
    253//                      }
    254                }
    255
    256//              jspPrint( label );                                              // 7.2.7.0 (2020/08/07)
    257
    258                // 実行件数の表示
    259                // 4.0.0 (2005/11/30) 出力順の変更。一番最初に出力します。
    260                if( displayMsg != null && displayMsg.length() > 0 ) {
    261                        final String status = executeCount + getResource().getLabel( displayMsg ) ;
    262                        jspPrint( status + BR );
    263                }
    264
    265                if( useTimeView ) {             // 6.3.6.0 (2015/08/16)
    266                        // 3.5.4.7 (2004/02/06)
    267                        final long dyTime = System.currentTimeMillis()-dyStart;
    268                        jspPrint( "<div id=\"queryTime\" value=\"" + (dyTime) + "\"></div>" );  // 3.5.6.3 (2004/07/12)
    269                }
    270                return EVAL_PAGE ;
    271        }
    272
    273        /**
    274         * タグリブオブジェクトをリリースします。
    275         * キャッシュされて再利用されるので、フィールドの初期設定を行います。
    276         *
    277         * @og.rev 6.8.0.0 (2017/06/02) 入力共通パス(inPath)を指定します。
    278         * @og.rev 7.0.7.0 (2019/12/13) useSLabel 属性を追加。
    279         * @og.rev 7.2.7.0 (2020/08/07) outMessage 削除
    280         * @og.rev 7.2.7.0 (2020/08/07) parentClm,nameClm,toParentClm,toNameClm 追加
    281         * @og.rev 7.2.7.0 (2020/08/07) エラー時に処理後に停止(true)するかどうか(useStop対応)
    282         * @og.rev 7.2.7.0 (2020/08/07) ERR0050:ｱｸｼｮﾝ実行中にｴﾗｰが発生しました。
    283         */
    284        @Override
    285        protected void release2() {
    286                super.release2();
    287                tableId         = HybsSystem.TBL_MDL_KEY;
    288                command         = CMD_ENTRY;
    289                action          = null;
    290                targetDir       = null;                 // ターゲットとなるフォルダ
    291                createDir       = true;                 // ターゲットとなるフォルダがなければ、作成するかどうか(true:作成する)
    292//              outMessage      = true;
    293                parentClm       = "PARENT";             // 7.2.7.0 (2020/08/07) fileQuery以外の場合の元親ﾌｫﾙﾀﾞを示すｶﾗﾑ名を指定します(初期値:"PARENT")
    294                nameClm         = "NAME";               // 7.2.7.0 (2020/08/07) fileQuery以外の場合の元ﾌｧｲﾙ名を示すｶﾗﾑ名を指定します(初期値:"NAME")
    295                toParentClm     = "TO_PARENT";  // 7.2.7.0 (2020/08/07) fileQuery以外の場合の先親ﾌｫﾙﾀﾞを示すｶﾗﾑ名を指定します(初期値:"TO_PARENT")
    296                toNameClm       = "TO_NAME";    // 7.2.7.0 (2020/08/07) fileQuery以外の場合の先ﾌｧｲﾙ名を示すｶﾗﾑ名を指定します(初期値:"TO_NAME")
    297                displayMsg      = "MSG0040";    // 　件登録しました。
    298                actErrMsg       = "ERR0050";    // 7.2.7.0 (2020/08/07) ｱｸｼｮﾝ実行中にｴﾗｰが発生しました。ｱｸｼｮﾝ:{0} From:{1} To:{2}
    299                selectedAll = false;
    300                keepTimeStamp = false;          // オリジナルのタイムスタンプを利用する場合、true
    301                table           = null;
    302                errMessage      = null;
    303                executeCount= -1;                       // 処理件数
    304                errCode         = ErrorMessage.OK;
    305                useTimeView     = HybsSystem.sysBool( "VIEW_USE_TIMEBAR" );     // 6.3.6.0 (2015/08/16)
    306                inPath          = null;                 // 6.8.0.0 (2017/06/02) 入力共通パスを指定します。
    307                useSLabel       = false;                // 7.0.7.0 (2019/12/13) ｴﾗｰﾒｯｾｰｼﾞにSLABELを利用するかどうか[true/false]を指定します(初期値:false)
    308                useStop         = true;                 // 7.2.7.0 (2020/08/07) エラー時に処理後に停止(true)するかどうか
    309        }
    310
    311        /**
    312         * 処理を実行します。
    313         *
    314         * @og.rev 6.8.0.0 (2017/06/02) 入力共通パス(inPath)を指定します。
    315         * @og.rev 7.2.7.0 (2020/08/07) MKDIRSｱｸｼｮﾝ 追加
    316         * @og.rev 7.2.7.0 (2020/08/07) parentClm,nameClm,toParentClm,toNameClm 追加
    317         */
    318        private void execute() {
    319                final int[] rowNo = getParameterRows();
    320                if( rowNo.length > 0 ) {
    321                        // 7.2.7.0 (2020/08/07) parentClm,nameClm,toParentClm,toNameClm 追加
    322                        final String[] clms = new String[] { parentClm,nameClm,toParentClm,toNameClm } ;
    323
    324//                      final FromToFiles fromToFiles = new FromToFiles( table , targetDir , createDir , inPath );                      // 6.8.0.0 (2017/06/02) 入力共通パス(inPath)を指定
    325                        final FromToFiles fromToFiles = new FromToFiles( table , targetDir , createDir , inPath , clms );       // 7.2.7.0 (2020/08/07)
    326
    327                        if( ACT_COPY.equalsIgnoreCase( action ) ) {
    328                                actionCOPY( rowNo,fromToFiles );
    329                        }
    330                        // ACT_MODIFY は、エンジンの command で使うため、便利
    331                        else if( ACT_MOVE.equalsIgnoreCase( action ) || ACT_MODIFY.equalsIgnoreCase( action ) ) {
    332                                actionMOVE( rowNo,fromToFiles );
    333                        }
    334                        else if( ACT_DELETE.equalsIgnoreCase( action ) ) {
    335                                actionDELETE( rowNo,fromToFiles );
    336                        }
    337                        else if( ACT_MKDIRS.equalsIgnoreCase( action ) ) {              // 7.2.7.0 (2020/08/07)
    338                                actionMKDIRS( rowNo,fromToFiles );
    339                        }
    340                }
    341        }
    342
    343        /**
    344         * COPY アクションを実行します。
    345         *
    346         * エラー発生時の引数は、ｱｸｼｮﾝ:{0} From:{1} To:{2} です。
    347         *
    348         * @og.rev 5.6.5.2 (2013/06/21) From側がファイルの場合のみ処理します。
    349         * @og.rev 7.2.7.0 (2020/08/07) ERR0050:ｱｸｼｮﾝ実行中にｴﾗｰが発生しました。
    350         *
    351         * @param       rowNo           処理を実施する行番号
    352         * @param       fromToFiles     FromFile,ToFileをまとめた補助クラス
    353         * @throws      HybsSystemException     処理中に何らかのエラーが発生した場合
    354         */
    355        private void actionCOPY( final int[] rowNo , final FromToFiles fromToFiles ) {
    356                File fromFile = null ;
    357                File toFile   = null ;
    358
    359                executeCount = 0 ;      // 開始前に初期化しておく。
    360                final int rowCount = rowNo.length ;
    361                for( int i=0; i<rowCount; i++ ) {
    362                        final File[] files = fromToFiles.makeFromToFile( rowNo[i] );    // FromFile,ToFile
    363                        fromFile = files[0];
    364                        toFile   = files[1];
    365
    366                        if( fromFile.isFile() && !FileUtil.copy( fromFile,toFile,keepTimeStamp ) ) {
    367                                if( errMessage == null ) { errMessage = new ErrorMessage( "FileUpdateTag Error" ); }
    368                                // ERR0050:ｱｸｼｮﾝ実行中にｴﾗｰが発生しました。ｱｸｼｮﾝ:{0} From:{1} To:{2}
    369                                errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,actErrMsg,action,fromFile.toString(),toFile.toString() );
    370                                errCode = ErrorMessage.NG;
    371                        }
    372
    373//                      // 5.6.5.2 (2013/06/21) From側がファイルの場合のみ処理します。
    374//                      if( fromFile.isFile() && !FileUtil.copy( fromFile,toFile,keepTimeStamp ) ) {
    375//                              final String errMsg = "アクション=[" + action + "]中にエラーが発生しました。" + CR
    376//                                                                      + "From=[" + fromFile + "],To=[" + toFile + "]" + CR;
    377//                              // 6.0.2.5 (2014/10/31) refactoring
    378//                              if( errMessage == null ) { errMessage = new ErrorMessage( "FileUpdateTag Error" ); }
    379//                              errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,"actionCOPY",errMsg );
    380//                      }
    381                        executeCount++ ;
    382                }
    383        }
    384
    385        /**
    386         * MOVE アクションを実行します。
    387         *
    388         * エラー発生時の引数は、ｱｸｼｮﾝ:{0} From:{1} To:{2} です。
    389         *
    390         * @og.rev 5.5.2.4 (2012/05/16) メソッドの戻り値の設定
    391         * @og.rev 5.6.5.2 (2013/06/21) From側がファイルの場合のみ処理します。
    392         * @og.rev 7.2.7.0 (2020/08/07) ERR0050:ｱｸｼｮﾝ実行中にｴﾗｰが発生しました。
    393         *
    394         * @param       rowNo           処理を実施する行番号
    395         * @param       fromToFiles     FromFile,ToFileをまとめた補助クラス
    396         * @throws      HybsSystemException     処理中に何らかのエラーが発生した場合
    397         */
    398        private void actionMOVE( final int[] rowNo , final FromToFiles fromToFiles ) {
    399                File fromFile = null ;
    400                File toFile   = null ;
    401
    402                executeCount = 0 ;      // 開始前に初期化しておく。
    403                final int rowCount = rowNo.length ;
    404                for( int i=0; i<rowCount; i++ ) {
    405                        final File[] files = fromToFiles.makeFromToFile( rowNo[i] );    // FromFile,ToFile
    406                        fromFile = files[0];
    407                        toFile   = files[1];
    408
    409                        if( fromToFiles.lastParentEquals() ) {  // FromDirとToDirが同じなので、RENAMEできる。
    410                                if( !fromFile.renameTo( toFile ) ) {
    411                                        if( errMessage == null ) { errMessage = new ErrorMessage( "FileUpdateTag Error" ); }
    412                                        // ERR0050:ｱｸｼｮﾝ実行中にｴﾗｰが発生しました。ｱｸｼｮﾝ:{0} From:{1} To:{2}
    413                                        errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,actErrMsg,action,fromFile.toString(),toFile.toString() );
    414                                        final String errMsg1 = "同一親フォルダのため、RENAME処理を行っています。";
    415                                        errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,action,errMsg1 );
    416                                        errCode = ErrorMessage.NG;
    417
    418//                                      final String errMsg = "アクション=[" + action + "]中にエラーが発生しました。" + CR
    419//                                                                              + "同一親フォルダのため、RENAME処理を行っています。" + CR
    420//                                                                              + "From=[" + fromFile + "],To=[" + toFile + "]" + CR;
    421//                                      // 6.0.2.5 (2014/10/31) refactoring
    422//                                      if( errMessage == null ) { errMessage = new ErrorMessage( "FileUpdateTag Error" ); }
    423//                                      errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,"actionMOVE",errMsg );
    424                                }
    425                        }
    426                        // 5.6.5.2 (2013/06/21) From側がファイルの場合のみ処理します。
    427                        else if( fromFile.isFile() ) {                  // FromDirとToDirが異なるので、COPY ＋ DELETE する。
    428                                if( !FileUtil.copy( fromFile,toFile,keepTimeStamp ) ) {
    429                                        if( errMessage == null ) { errMessage = new ErrorMessage( "FileUpdateTag Error" ); }
    430                                        // ERR0050:ｱｸｼｮﾝ実行中にｴﾗｰが発生しました。ｱｸｼｮﾝ:{0} From:{1} To:{2}
    431                                        errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,actErrMsg,action,fromFile.toString(),toFile.toString() );
    432                                        final String errMsg1 = "移動前のCOPY処理を行っていました。";
    433                                        errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,action,errMsg1 );
    434                                        errCode = ErrorMessage.NG;
    435
    436//                                      final String errMsg = "アクション=[" + action + "]中にエラーが発生しました。" + CR
    437//                                                                              + "移動前のCOPY処理を行っていました。" + CR
    438//                                                                              + "From=[" + fromFile + "],To=[" + toFile + "]" + CR;
    439//                                      // 6.0.2.5 (2014/10/31) refactoring
    440//                                      if( errMessage == null ) { errMessage = new ErrorMessage( "FileUpdateTag Error" ); }
    441//                                      errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,"actionMOVE",errMsg );
    442                                }
    443
    444                                if( !fromFile.delete() ) {
    445                                        if( errMessage == null ) { errMessage = new ErrorMessage( "FileUpdateTag Error" ); }
    446                                        // ERR0050:ｱｸｼｮﾝ実行中にｴﾗｰが発生しました。ｱｸｼｮﾝ:{0} From:{1} To:{2}
    447                                        errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,actErrMsg,action,fromFile.toString(),toFile.toString() );
    448                                        final String errMsg1 = "移動後のオリジナルファイルの削除処理を行っていました。";
    449                                        errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,action,errMsg1 );
    450                                        errCode = ErrorMessage.NG;
    451
    452//                                      String errMsg = "アクション=[" + action + "]中にエラーが発生しました。" + CR
    453//                                                                              + "移動後のオリジナルファイルの削除処理を行っていました。" + CR
    454//                                                                              + "From=[" + fromFile + "],To=[" + toFile + "]" + CR;
    455//                                      // 5.5.2.4 (2012/05/16) メソッドの戻り値の設定
    456                                        if( !toFile.delete() ) {
    457//                                              errMsg = errMsg + "toFile も削除に失敗しました。" + CR;
    458                                                final String errMsg3 = "toFile も削除に失敗しました。";
    459                                                errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,action,errMsg3 );
    460                                        }
    461
    462//                                      // 6.0.2.5 (2014/10/31) refactoring
    463//                                      if( errMessage == null ) { errMessage = new ErrorMessage( "FileUpdateTag Error" ); }
    464//                                      errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,"actionMOVE",errMsg );
    465                                }
    466                        }
    467                        executeCount++ ;
    468                }
    469        }
    470
    471        /**
    472         * DELETE アクションを実行します。
    473         *
    474         * この処理では、リストにフォルダが含まれている場合も削除します。
    475         * 通常、フォルダの削除は、その要素（内部）にファイル等が存在しない場合のみ
    476         * 行いますが、検索リストから削除する順番によっては、フォルダもファイルも
    477         * 削除対象になる場合があります。そこで、まず。ファイルだけ削除し、フォルダは、
    478         * あとで削除するように処理を行います。
    479         *
    480         * エラー発生時の引数は、ｱｸｼｮﾝ:{0} From:{1} To:"" です。
    481         *
    482         * @og.rev 5.6.5.2 (2013/06/21) フォルダも削除対象にします。
    483         * @og.rev 7.2.6.0 (2020/06/30) 削除方法を変更します。
    484         * @og.rev 7.2.7.0 (2020/08/07) ERR0050:ｱｸｼｮﾝ実行中にｴﾗｰが発生しました。
    485         *
    486         * @param       rowNo           処理を実施する行番号
    487         * @param       fromToFiles     FromFile,ToFileをまとめた補助クラス
    488         * @throws      HybsSystemException     処理中に何らかのエラーが発生した場合
    489         */
    490        private void actionDELETE( final int[] rowNo , final FromToFiles fromToFiles ) {
    491                final int rowCount = rowNo.length ;
    492                for( int i=0; i<rowCount; i++ ) {
    493                        final File fmFile = fromToFiles.makeFromOnly( rowNo[i] );       // FromFile
    494                        try {
    495                                delete( fmFile );
    496                                executeCount++ ;
    497                        }
    498                        catch( final Throwable th ) {
    499                                if( errMessage == null ) { errMessage = new ErrorMessage( "FileUpdateTag Error" ); }
    500                                // ERR0050:ｱｸｼｮﾝ実行中にｴﾗｰが発生しました。ｱｸｼｮﾝ:{0} From:{1} To:{2}
    501                                errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,actErrMsg,action,fmFile.toString(),"" );
    502                                errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,action,th.getMessage() );
    503                                errCode = ErrorMessage.NG;
    504
    505//                              final String errMsg = "アクション=[" + action + "]中にエラーが発生しました。" + CR
    506//                                                                      + "From=[" + fmFile + "]" + CR;
    507//                              // 6.0.2.5 (2014/10/31) refactoring
    508//                              if( errMessage == null ) { errMessage = new ErrorMessage( "FileUpdateTag Error" ); }
    509//                              errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,"actionDELETE",errMsg );
    510                        }
    511                }
    512        }
    513
    514        /**
    515         * フォルダやファイルがあっても、すべて再帰的に削除します。
    516         *
    517         * @og.rev 7.2.6.0 (2020/06/30) 削除方法を変更します。
    518         * @og.rev 7.2.9.4 (2020/11/20) spotbugs:null になっている可能性があるメソッドの戻り値を利用している
    519         *
    520         * @param       inFile  起点となるフォルダ
    521         */
    522        private static void delete( final File inFile ) {
    523                final File[] flist = inFile.listFiles();
    524                if( flist != null ) {                                           // 7.2.9.4 (2020/11/20)
    525                        for( final File file : flist) {
    526                                if( file.isDirectory() ) {
    527                                        delete( file );
    528                                } else {
    529//                                      file.delete();
    530                                        if( !file.delete() ) {                  // 7.3.0.0 (2021/01/06) SpotBugs 例外的戻り値を無視しているメソッド
    531                                                System.err.println( "file Delete Error! " + file );
    532                                        }
    533                                }
    534                        }
    535                }
    536//              inFile.delete();
    537                if( !inFile.delete() ) {                                        // 7.3.0.0 (2021/01/06) SpotBugs 例外的戻り値を無視しているメソッド
    538                        System.err.println( "inFile Delete Error! " + inFile );
    539                }
    540        }
    541
    542        /**
    543         * MKDIRS アクションを実行します。
    544         *
    545         * この処理では、TO_PARENT ｶﾗﾑに指定されたﾀｰｹﾞｯﾄﾌｫﾙﾀﾞを 多階層mkdirします。
    546         * 実際は、ﾌｧｲﾙ作成やｺﾋﾟｰ時には、mkdirs するので、ここでの使い方の想定は、
    547         * ﾀｰｹﾞｯﾄﾌｫﾙﾀﾞへのｱｸｾｽが可能かどうかの確認です。
    548         * 存在ﾁｪｯｸ(EXISTS)では、本当に存在しない場合も、ｱｸｾｽ出来ない場合も
    549         * false となるためです。
    550         * なお、通常の mkdirs では、ﾌｫﾙﾀﾞが新規に作成されなかった場合(すでに存在)
    551         * false となりますが、ここのｱｸｼｮﾝでは、ｱｸｾｽﾁｪｯｸも兼ねているため、
    552         * mkdirs が成功するか、すでに存在している場合は、正常と判断します。
    553         *
    554         * エラー発生時の引数は、ｱｸｼｮﾝ:{0} From:"" To:{2} です。
    555         *
    556         * @og.rev 7.2.7.0 (2020/08/07) MKDIRSｱｸｼｮﾝ 追加
    557         *
    558         * @param       rowNo           処理を実施する行番号
    559         * @param       fromToFiles     FromFile,ToFileをまとめた補助クラス
    560         * @throws      HybsSystemException     処理中に何らかのエラーが発生した場合
    561         */
    562        private void actionMKDIRS( final int[] rowNo , final FromToFiles fromToFiles ) {
    563                final int rowCount = rowNo.length ;
    564                for( int i=0; i<rowCount; i++ ) {
    565                        try {
    566                                fromToFiles.makeToParent( rowNo[i] );           // 戻り値は確認しない。
    567                        }
    568                        catch( final Throwable th ) {
    569                                if( errMessage == null ) { errMessage = new ErrorMessage( "FileUpdateTag Error" ); }
    570                                // ERR0050:ｱｸｼｮﾝ実行中にｴﾗｰが発生しました。ｱｸｼｮﾝ:{0} From:{1} To:{2}
    571                                errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,actErrMsg,action,"",fromToFiles.getLastDir() );
    572                                errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,action,th.getMessage() );
    573                                errCode = ErrorMessage.NG;
    574                        }
    575                }
    576        }
    577
    578        /**
    579         * 表示データの HybsSystem.ROW_SEL_KEY を元に、選ばれた 行を処理の対象とします。
    580         *
    581         * @return      選択行の配列
    582         * @og.rtnNotNull
    583         */
    584        @Override
    585        protected int[] getParameterRows() {
    586                final int[] rowNo ;
    587                if( selectedAll ) {
    588                        final int rowCnt = table.getRowCount();
    589                        rowNo = new int[ rowCnt ];
    590                        for( int i=0; i<rowCnt; i++ ) {
    591                                rowNo[i] = i;
    592                        }
    593                } else {
    594                        rowNo = super.getParameterRows();
    595                }
    596                return rowNo ;
    597        }
    598
    599        /**
    600         * 【TAG】アクション[COPY|MOVE|MODIFY|DELETE|MKDIRS]をセットします。
    601         *
    602         * @og.tag
    603         * アクションは、ファイルをコピー(COPY)したり、移動(MOVE,MODIFY)したり、削除(DELETE)、
    604         * ﾌｫﾙﾀﾞ作成(MKDIRS)するなどの操作を指定する必須属性です。
    605         *
    606         * <table class="plain">
    607         *   <caption>action属性(必須)のキーワード</caption>
    608         *   <tr><th>action</th><th>名称</th><th>機能</th></tr>
    609         *   <tr><td>COPY  </td><td>コピー</td><td>オリジナルファイルを、ターゲット(TO_PARENT,TO_NAMEで指定)にコピーします。</td></tr>
    610         *   <tr><td>MOVE  </td><td>移動  </td><td>オリジナルファイルを、ターゲットに移動(COPY+DELETE)/名称変更(RENAME)します。</td></tr>
    611         *   <tr><td>MODIFY</td><td>移動  </td><td>(MOVE と同じ。エンジンの command を利用するための簡易action)</td></tr>
    612         *   <tr><td>DELETE</td><td>削除  </td><td>オリジナルファイルを、削除します。(フォルダ、ファイルに関わらず)</td></tr>
    613         *   <tr><td>MKDIRS</td><td>削除  </td><td>ターゲット(TO_PARENTで指定)フォルダを作成します。 7.2.7.0 (2020/08/07)</td></tr>
    614         * </table>
    615         *
    616         * @og.rev 6.3.4.0 (2015/08/01) Arrays.toString から String.join に置き換え。
    617         * @og.rev 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。
    618         *
    619         * @param       act アクション (public static final 宣言されている文字列)
    620         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.FileUpdateTag.ACT_COPY">アクション定数</a>
    621         */
    622        public void setAction( final String act ) {
    623                action = nval( getRequestParameter( act ),action );
    624
    625                if( action != null && !check( action, ACTION_SET ) ) {
    626                        final String errMsg = "指定のアクションは実行できません。アクションエラー"       + CR
    627                                                        + "action=[" + action + "] "                                                            + CR
    628                                                        + "actionList=" + String.join( ", " , ACTION_SET ) ;
    629                        throw new HybsSystemException( errMsg );
    630                }
    631        }
    632
    633        /**
    634         * 【TAG】ターゲットとなるフォルダを指定します(初期値:null)。
    635         *
    636         * @og.tag
    637         * targetDir 属性を利用する場合は、引数のファイル、またはフォルダが指定されたことに
    638         * なります。COPY、MOVE(,MODIFY) の場合は、targetDir 属性にフォルダを指定することで一括処理可能です。
    639         * 指定先のフォルダが存在しない場合は、createDir属性の値により処理が異なります。
    640         * createDir="true"(初期値)で、ターゲットフォルダが存在しない場合は、自動作成します。
    641         *
    642         * @param  dir ターゲットとなるフォルダ
    643         * @see         #setCreateDir( String )
    644         */
    645        public void setTargetDir( final String dir ) {
    646                targetDir = nval( getRequestParameter( dir ),targetDir );
    647        }
    648
    649        /**
    650         * 【TAG】ターゲットとなるフォルダがなければ、作成するかどうかを指定します(初期値:true)。
    651         *
    652         * @og.tag
    653         * COPY,MOVE(,MODIFY) などの処理で、ターゲットフォルダが存在しないときに、作成するか、エラーにするかを
    654         * createDir属性 で指定できます。
    655         * これは、COPY先やMOVE(,MODIFY)先が存在している前提のシステムで、不要な箇所に間違ってフォルダを
    656         * 自動作成されると困る場合に、false:作成しない とすれば、間違いに気づく確率が上がります。
    657         * 初期値は true:作成する です。
    658         *
    659         * @param       flag    フォルダ作成可否 [true:作成する/false:作成しない]
    660         */
    661        public void setCreateDir( final String flag ) {
    662                createDir = nval( getRequestParameter( flag ),createDir );
    663        }
    664
    665        /**
    666         * 【TAG】fileQuery以外の場合の元親ﾌｫﾙﾀﾞを示すｶﾗﾑ名を指定します(初期値:"PARENT")。
    667         *
    668         * @og.tag
    669         * 通常、fileQueryで取得したﾌｫﾙﾀﾞとﾌｧｲﾙ名は、PARENT,NAME というｶﾗﾑに作成されます。
    670         * ここでは、ﾃﾞｰﾀﾍﾞｰｽ等で管理しているﾌｫﾙﾀﾞやﾌｧｲﾙ名を検索した場合に処理できるように
    671         * それぞれのｶﾗﾑ名を指定できるようにします。
    672         * (初期値:"PARENT")
    673         *
    674         * @og.rev 7.2.7.0 (2020/08/07) parentClm,nameClm,toParentClm,toNameClm 追加
    675         *
    676         * @param       clm 元親ﾌｫﾙﾀﾞを示すｶﾗﾑ名
    677         */
    678        public void setParentClm( final String clm ) {
    679                parentClm = nval( getRequestParameter( clm ),parentClm );
    680        }
    681
    682        /**
    683         * 【TAG】fileQuery以外の場合の元ﾌｧｲﾙ名を示すｶﾗﾑ名を指定します(初期値:"NAME")。
    684         *
    685         * @og.tag
    686         * 通常、fileQueryで取得したﾌｫﾙﾀﾞとﾌｧｲﾙ名は、PARENT,NAME というｶﾗﾑに作成されます。
    687         * ここでは、ﾃﾞｰﾀﾍﾞｰｽ等で管理しているﾌｫﾙﾀﾞやﾌｧｲﾙ名を検索した場合に処理できるように
    688         * それぞれのｶﾗﾑ名を指定できるようにします。
    689         * (初期値:"NAME")
    690         *
    691         * @og.rev 7.2.7.0 (2020/08/07) parentClm,nameClm,toParentClm,toNameClm 追加
    692         *
    693         * @param       clm 元ﾌｧｲﾙ名を示すｶﾗﾑ名
    694         */
    695        public void setNameClm( final String clm ) {
    696                nameClm = nval( getRequestParameter( clm ),nameClm );
    697        }
    698
    699        /**
    700         * 【TAG】fileQuery以外の場合の先親ﾌｫﾙﾀﾞを示すｶﾗﾑ名を指定します(初期値:"TO_PARENT")。
    701         *
    702         * @og.tag
    703         * 通常、fileQueryで取得したﾌｫﾙﾀﾞとﾌｧｲﾙ名は、PARENT,NAME というｶﾗﾑに作成されます。
    704         * ここでは、ﾃﾞｰﾀﾍﾞｰｽ等で管理しているﾌｫﾙﾀﾞやﾌｧｲﾙ名を検索した場合に処理できるように
    705         * それぞれのｶﾗﾑ名を指定できるようにします。
    706         * (初期値:"TO_PARENT")
    707         *
    708         * @og.rev 7.2.7.0 (2020/08/07) parentClm,nameClm,toParentClm,toNameClm 追加
    709         *
    710         * @param       clm 先親ﾌｫﾙﾀﾞを示すｶﾗﾑ名
    711         */
    712        public void setToParentClm( final String clm ) {
    713                toParentClm = nval( getRequestParameter( clm ),toParentClm );
    714        }
    715
    716        /**
    717         * 【TAG】fileQuery以外の場合の先ﾌｧｲﾙ名を示すｶﾗﾑ名を指定します(初期値:"TO_NAME")。
    718         *
    719         * @og.tag
    720         * 通常、fileQueryで取得したﾌｫﾙﾀﾞとﾌｧｲﾙ名は、PARENT,NAME というｶﾗﾑに作成されます。
    721         * ここでは、ﾃﾞｰﾀﾍﾞｰｽ等で管理しているﾌｫﾙﾀﾞやﾌｧｲﾙ名を検索した場合に処理できるように
    722         * それぞれのｶﾗﾑ名を指定できるようにします。
    723         * (初期値:"TO_NAME")
    724         *
    725         * @og.rev 7.2.7.0 (2020/08/07) parentClm,nameClm,toParentClm,toNameClm 追加
    726         *
    727         * @param       clm 先ﾌｧｲﾙ名を示すｶﾗﾑ名
    728         */
    729        public void setToNameClm( final String clm ) {
    730                toNameClm = nval( getRequestParameter( clm ),toNameClm );
    731        }
    732
    733        /**
    734         * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します
    735         *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。
    736         *
    737         * @og.tag
    738         * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に
    739         * 渡す場合に、通常は、session を利用します。その場合の登録キーです。
    740         * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、
    741         * この tableId 属性を利用して、メモリ空間を分けます。
    742         *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。
    743         *
    744         * @param       id テーブルID (sessionに登録する時のID)
    745         */
    746        public void setTableId( final String id ) {
    747                tableId = nval( getRequestParameter( id ),tableId );
    748        }
    749
    750        /**
    751         * 【TAG】コマンド (ENTRY)をセットします(初期値:ENTRY)。
    752         *
    753         * @og.tag
    754         * このタグは、command="ENTRY" でのみ実行されます。
    755         * コマンドは,HTMLから(get/post)指定されますので,CMD_xxx で設定される
    756         * フィールド定数値のいづれかを、指定できます。
    757         * 初期値は、ENTRY なので、何も指定しなければ、実行されます。
    758         *
    759         * @param       cmd コマンド (public static final 宣言されている文字列)
    760         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.FileUpdateTag.CMD_ENTRY">コマンド定数</a>
    761         */
    762        public void setCommand( final String cmd ) {
    763                final String cmd2 = getRequestParameter( cmd );
    764                if( cmd2 != null && cmd2.length() >= 0 ) { command = cmd2.toUpperCase(Locale.JAPAN); }
    765        }
    766
    767//      /**
    768//       * 【TAG】検索結果のメッセージを表示する/しない[true/false]を指定します(初期値:true)。
    769//       *
    770//       * @og.tag
    771//       * 初期値は、表示する：true です。
    772//       *
    773//       * @og.rev 7.2.7.0 (2020/08/07) outMessage 削除
    774//       *
    775//       * @param       flag  メッセージ表示可否 [true:表示する/それ以外:含めない]
    776//       */
    777//      public void setOutMessage( final String flag ) {
    778//              outMessage = nval( getRequestParameter( flag ),outMessage );
    779//      }
    780
    781        /**
    782         * 【TAG】処理結果を画面上に表示するメッセージリソースIDを指定します(初期値:MSG0040[　件登録しました])。
    783         *
    784         * @og.tag
    785         * ここでは、検索結果の件数や登録された件数をまず出力し、
    786         * その次に、ここで指定したメッセージをリソースから取得して表示します。
    787         * 表示させたくない場合は, displayMsg = "" をセットしてください。
    788         * displayMsg の初期値は、MSG0040[　件登録しました]です。
    789         *
    790         * @param       id 処理結果表示メッセージID
    791         */
    792        public void setDisplayMsg( final String id ) {
    793                final String ids = getRequestParameter( id );
    794                if( ids != null ) { displayMsg = ids; }
    795        }
    796
    797        /**
    798         * 【TAG】action実行時のｴﾗｰﾒｯｾｰｼﾞのﾒｯｾｰｼﾞﾘｿｰｽIDを指定します(初期値:ERR0050:ｱｸｼｮﾝ実行中にｴﾗｰが発生しました。
    799         *
    800         * @og.tag
    801         * action実行時のｴﾗｰﾒｯｾｰｼﾞは、COPY|MOVE|MODIFY|DELETE|MKDIRS などのｱｸｼｮﾝ実行時に
    802         * ｴﾗｰが発生した際に、表示するﾒｯｾｰｼﾞﾘｿｰｽのID をセットします。
    803         * ｴﾗｰﾒｯｾｰｼﾞのため、未指定にすることはできません。
    804         * actErrMsg の初期値は、ERR0050:ｱｸｼｮﾝ実行中にｴﾗｰが発生しました。ｱｸｼｮﾝ:{0} From:{1} To:{2}
    805         *
    806         * @og.rev 7.2.7.0 (2020/08/07) MKDIRSｱｸｼｮﾝ 追加
    807         *
    808         * @param       id action実行時のｴﾗｰﾒｯｾｰｼﾞのﾒｯｾｰｼﾞﾘｿｰｽID
    809         */
    810        public void setActErrMsg( final String id ) {
    811                actErrMsg = nval( getRequestParameter( id ),actErrMsg );
    812        }
    813
    814        /**
    815         * 【TAG】データを全件選択済みとして処理するかどうか[true/false]を指定します(初期値:false)。
    816         *
    817         * @og.tag
    818         * 全てのデータを選択済みデータとして扱って処理します。
    819         * 全件処理する場合に、(true/false)を指定します。
    820         * 初期値は false です。
    821         *
    822         * @param  all 全件選択済み指定 [true:全件選択済み/false:通常]
    823         */
    824        public void setSelectedAll( final String all ) {
    825                selectedAll = nval( getRequestParameter( all ),selectedAll );
    826        }
    827
    828        /**
    829         * 【TAG】オリジナルのタイムスタンプを利用するかどうかを指定します(初期値:false)。
    830         *
    831         * @og.tag
    832         * COPYや親違いMOVE(,MODIFY)の時に、オリジナルのタイムスタンプをそのままコピー先のファイルにも
    833         * 適用するかどうかを指定します。
    834         * タイムスタンプを初期化されたくない場合に、true に設定します。
    835         * 初期値は 利用しない:false です。
    836         *
    837         * @param  flag タイムスタンプ利用 [true:する/false:しない]
    838         */
    839        public void setKeepTimeStamp( final String flag ) {
    840                keepTimeStamp = nval( getRequestParameter( flag ),keepTimeStamp );
    841        }
    842
    843        /**
    844         * 【TAG】処理時間を表示する TimeView を表示するかどうか[true:する/false:しない]を指定します
    845         *              (初期値:VIEW_USE_TIMEBAR[={@og.value SystemData#VIEW_USE_TIMEBAR}])。
    846         *
    847         * @og.tag
    848         * true に設定すると、処理時間を表示するバーイメージが表示されます。
    849         * これは、DB検索、APサーバー処理、画面表示の各処理時間をバーイメージで
    850         * 表示させる機能です。処理時間の目安になります。
    851         * (初期値:VIEW_USE_TIMEBAR[={@og.value SystemData#VIEW_USE_TIMEBAR}])。
    852         *
    853         * @og.rev 6.3.6.0 (2015/08/16) useTimeView の初期値を、VIEW_USE_TIMEBAR にする。
    854         *
    855         * @param       flag    処理時間を表示 [true:する/false:しない]
    856         */
    857        public void setUseTimeView( final String flag ) {
    858                useTimeView = nval( getRequestParameter( flag ),useTimeView );
    859        }
    860
    861        /**
    862         * 【TAG】入力共通パスを指定します。
    863         *
    864         * @og.tag
    865         * 通常、fileQueryタグ等で、検索した結果は、PARENT,NAME というカラムにセットされます。
    866         * この、fileQueryのfrom属性に、検索を開始するディレクトリを指定し、multi="true"で、
    867         * 多段階展開 した場合、この、from属性に指定したパスを、inPath にセットすることで、
    868         * 以下の階層フォルダそのままに、targetDir にCOPY または、MOVE することが出来ます。
    869         * 逆に、指定しない場合は、フォルダ階層無しで、COPY,MOVE されます。
    870         *
    871         * @og.rev 6.8.0.0 (2017/06/02) 入力共通パスを指定します。
    872         * @og.rev 7.0.5.0 (2019/09/13) inPath のﾊﾟｽは、正規パス名から作成。
    873         *
    874         * @param       path    入力共通パス
    875         */
    876        public void setInPath( final String path ) {
    877                inPath = nval( getRequestParameter( path ),inPath );
    878
    879                // 7.0.5.0 (2019/09/13) inPath のﾊﾟｽは、正規パス名から作成。
    880                if( inPath != null ) {
    881                        try {
    882                                inPath = new File(inPath).getCanonicalPath();
    883                        }
    884                        catch( final IOException ex ) {
    885                                final String errMsg = "inPathの正式なファイル名の取得に失敗しました。[" + inPath + "]"
    886                                                        + CR + ex.getMessage();
    887                                throw new HybsSystemException( errMsg,ex );
    888                        }
    889                }
    890        }
    891
    892        /**
    893         * 【TAG】ｴﾗｰﾒｯｾｰｼﾞにSLABELを利用するかどうか[true/false]を指定します(初期値:false)。
    894         *
    895         * @og.tag
    896         * 通常のｴﾗｰﾒｯｾｰｼﾞは、ﾗﾍﾞﾙ（長）が使われますが、これをﾗﾍﾞﾙ（短）を使いたい場合に、true にセットします。
    897         * ここでのラベル（短）は、ﾀｸﾞ修飾なしの、ﾗﾍﾞﾙ（短）です。
    898         * 標準はfalse:利用しない=ﾗﾍﾞﾙ（長）です。
    899         * true/false以外を指定した場合はfalse扱いとします。
    900         *
    901         * ﾗﾍﾞﾙﾘｿｰｽの概要説明があれば表示しますが、useSLabel="true" 時は、概要説明を表示しません。
    902         *
    903         * @og.rev 7.0.7.0 (2019/12/13) 新規追加
    904         *
    905         * @param prm SLABEL利用 [true:利用する/false:利用しない]
    906         */
    907        public void setUseSLabel( final String prm ) {
    908                useSLabel = nval( getRequestParameter( prm ),useSLabel );
    909        }
    910
    911        /**
    912         * 【TAG】エラー時に処理後に停止するかどうか[true/false]を指定します(初期値:true)。
    913         *
    914         * @og.tag
    915         * 処理結果などに応じて、以下の処理を停止したい場合に、使用します。
    916         * false を指定すると、判定結果に無関係に、以下の処理を実行します。
    917         * 処理は継続したいが、警告表示する場合に、useStop="false" を指定します。
    918         * 初期値は、停止する ("true")です。
    919         *
    920         * @og.rev 7.2.7.0 (2020/08/07) エラー時に処理後に停止(true)するかどうか(useStop対応)
    921         *
    922         * @param   flag 処理後停止 [true:する/それ以外:しない]
    923         */
    924        public void setUseStop( final String flag ) {
    925                useStop = nval( getRequestParameter( flag ),useStop );
    926        }
    927
    928        /**
    929         * DBTableModel から、FromFile,ToFile を作成するための処理をまとめた補助クラスです。
    930         *
    931         * ここでは、オリジナルファイルやターゲットファイルを作成するための処理のみを集めています。
    932         * メソッドにすると、ローカル変数を多く管理するか、多数の引数渡しを繰り返すことになるため、
    933         * このローカルクラスに処理と、値を格納します。
    934         *
    935         * @og.rev 7.2.7.0 (2020/08/07) 相対ﾊﾟｽの場合の基準ﾌｫﾙﾀﾞ(FILE_URL) 考慮
    936         */
    937        private static final class FromToFiles {
    938                private final String fileURL = HybsSystem.sys( "FILE_URL" );            // 7.2.7.0 (2020/08/07) 相対ﾊﾟｽの場合の基準ﾌｫﾙﾀﾞ
    939
    940                private final DBTableModel      table ;
    941
    942                private final int PARENT        ;
    943                private final int NAME          ;
    944                private final int TO_PARENT     ;
    945                private final int TO_NAME       ;
    946
    947                private final File              toDir   ;
    948                private final boolean   createDir;              // ターゲットとなるフォルダがなければ、作成するかどうか(true:作成する)
    949                private final int               inPathCnt;              // 6.8.0.0 (2017/06/02) 入力共通パスの文字数
    950
    951                private boolean equalParent     ;                       // 最後に実行された処理で、親フォルダが同一の場合は、true
    952                private String  lastDir ;                               // 7.2.7.0 (2020/08/07) 一番最後にmkdirsしたﾌｫﾙﾀﾞ名(Exceptionの直前の設定値)
    953
    954                /**
    955                 *  引数指定のコンストラクター
    956                 *
    957                 * 必要なパラメータを渡して、オブジェクトを構築します。
    958                 * 入力共通パス(inPath)は、COPY/MOVE時にtargetDirと置換されます。
    959                 *
    960                 * @og.rev 6.8.0.0 (2017/06/02) 入力共通パス(inPath)を指定します。
    961                 * @og.rev 7.2.7.0 (2020/08/07) parentClm,nameClm,toParentClm,toNameClm 追加
    962                 *
    963                 * @param       table     一覧が格納されているDBTableModel
    964                 * @param       targetDir       ターゲットとなるフォルダ
    965                 * @param       createDir       フォルダ作成可否 [true:作成する/false:作成しない]
    966                 * @param       inPath          入力共通パス
    967                 * @param       clms            parentClm,nameClm,toParentClm,toNameClm の配列
    968                 */
    969//              public FromToFiles( final DBTableModel table , final String targetDir , final boolean createDir , final String inPath ) {
    970                public FromToFiles( final DBTableModel table , final String targetDir , final boolean createDir , final String inPath , final String[] clms ) {
    971
    972                        this.table              = table;
    973                        this.createDir  = createDir ;
    974                        toDir                   = mkDirs( targetDir,createDir );                        // targetDir が指定されていない場合は、null
    975                        // 7.0.5.0 (2019/09/13) inPath のﾊﾟｽの文字数も、正規パス名から作成。
    976                        inPathCnt               = inPath == null ? 0 : inPath.length() ;        // 6.8.0.0 (2017/06/02) 入力共通パスの文字数
    977
    978                        // "PARENT","NAME","TO_PARENT","TO_NAME" のカラム名のDBTableModelのカラム番号。存在しない場合は、-1
    979//                      PARENT          = table.getColumnNo( "PARENT"   , false );
    980//                      NAME            = table.getColumnNo( "NAME"             , false );
    981//                      TO_PARENT       = table.getColumnNo( "TO_PARENT", false );
    982//                      TO_NAME         = table.getColumnNo( "TO_NAME"  , false );
    983
    984                        PARENT          = table.getColumnNo( clms[0]    , false );              // 7.2.7.0 (2020/08/07) parentClm
    985                        NAME            = table.getColumnNo( clms[1]    , false );              // 7.2.7.0 (2020/08/07) nameClm
    986                        TO_PARENT       = table.getColumnNo( clms[2]    , false );              // 7.2.7.0 (2020/08/07) toParentClm
    987                        TO_NAME         = table.getColumnNo( clms[3]    , false );              // 7.2.7.0 (2020/08/07) toNameClm
    988                }
    989
    990                /**
    991                 * 行番号より、対応するオリジナルファイル(FromFile)を返します。
    992                 *
    993                 * ここでは、TO_PARENT や TO_NAME は、判定する必要がないため、makeFromToFile( int ) の
    994                 * 一部のみで処理が終了できます。
    995                 * １．FromDir は、PARENT 列の値から作成する。
    996                 * ２．FromFileは、FromDir ＋ NAME列の値から作成する。
    997                 *
    998                 * 配列返しの関係で、メソッド(および内部処理)を分けています。
    999                 *
    1000                 * @param       rowNo   カラムNo
    1001                 * @return      オリジナルファイル(FromFile)
    1002                 * @og.rtnNotNull
    1003                 * @see         #makeFromToFile( int )
    1004                 */
    1005                public File makeFromOnly( final int rowNo ) {
    1006                        final String[] value = table.getValues( rowNo );
    1007                        final File fromDir  = mkDirs( value[PARENT],createDir );
    1008
    1009                        return new File( fromDir, value[NAME] ) ;
    1010                }
    1011
    1012                /**
    1013                 * 行番号より、対応するTO_PARENT ﾌｫﾙﾀﾞのFileｵﾌﾞｼﾞｪｸﾄを返します。
    1014                 *
    1015                 * ここでは、TO_PARENT のみで処理します。
    1016                 *
    1017                 * 実質的には、MKDIRSｱｸｼｮﾝ でしか使用しないので、Fileｵﾌﾞｼﾞｪｸﾄを作成する必要すら
    1018                 * ありませんが、ﾒｿｯﾄﾞ共通化の関係で、ｵﾘｼﾞﾅﾙをそのまま使用します。
    1019                 *
    1020                 * @og.rev 7.2.7.0 (2020/08/07) MKDIRSｱｸｼｮﾝ 追加
    1021                 *
    1022                 * @param       rowNo   カラムNo
    1023                 * @return      TO_PARENT ﾌｫﾙﾀﾞのFileｵﾌﾞｼﾞｪｸﾄ(ｶﾗﾑが存在しない場合は、null)
    1024                 */
    1025                public File makeToParent( final int rowNo ) {
    1026                        final File rtnFile ;
    1027                        if( TO_PARENT >= 0 ) {
    1028                                final String[] value = table.getValues( rowNo );
    1029                                rtnFile = mkDirs( value[TO_PARENT],true );
    1030                        }
    1031                        else {
    1032                                rtnFile = null;
    1033                        }
    1034                        return rtnFile;
    1035                }
    1036
    1037                /**
    1038                 * 行番号より、対応するオリジナルファイル(FromFile)とターゲットファイル(ToFile)を配列に格納して返します。
    1039                 *
    1040                 * ここでは、TO_PARENT や TO_NAME は、存在するかどうか不明なので、以下の手順で作成します。
    1041                 * １．FromDir は、PARENT 列の値から作成する。
    1042                 * ２．FromFileは、FromDir ＋ NAME列の値から作成する。
    1043                 * ３．toDir は、
    1044                 *       Ａ．targetDir が有れば、それを使う。
    1045                 *       Ｂ．なければ、TO_PARENT 列の値から作成する。
    1046                 *       Ｃ．TO_PARENT 列がないか、値が未設定の場合は、FromDir をそのまま使う。
    1047                 * ４．toFile は、
    1048                 *       Ａ．toDir ＋ TO_NAME 列の値から作成する。
    1049                 *       Ｂ．TO_NAME 列がないか、値が未設定の場合は、toDir ＋ NAME列の値から作成する。
    1050                 * 返り値は、new File[] { formFile , toFile }; とする。
    1051                 *
    1052                 * @og.rev 6.8.0.0 (2017/06/02) 入力共通パス(inPath)を指定します。
    1053                 * @og.rev 7.2.7.0 (2020/08/07) 入力共通パス(inPath)指定時は、TO_PARENTかPARENTの桁数より小さい場合のみ処理する。
    1054                 *
    1055                 * @param       rowNo   カラムNo
    1056                 * @return      ファイル配列(0:オリジナルファイル 1:ターゲットファイル)
    1057                 * @og.rtnNotNull
    1058                 */
    1059                public File[] makeFromToFile( final int rowNo ) {
    1060                        final String[] value = table.getValues( rowNo );
    1061                        final File fromDir  = mkDirs( value[PARENT],createDir );
    1062                        final File formFile = new File( fromDir, value[NAME] );
    1063                        File tempToDir = toDir;
    1064
    1065                        equalParent = false;    // 最後に実行された処理で、親フォルダが同一かどうかのフラグをリセットする。
    1066                        if( tempToDir == null ) {
    1067                                if( TO_PARENT >= 0 && nval( value[TO_PARENT],null ) != null ) {
    1068                                        tempToDir = mkDirs( value[TO_PARENT],createDir );
    1069                                }
    1070                                else {
    1071                                        tempToDir = fromDir;
    1072                                        equalParent = true;             // 最後に実行された処理で、親フォルダが同一の場合は、true
    1073                                }
    1074                        }
    1075                        // 6.8.0.0 (2017/06/02) toDirが指定され、かつ、入力共通パスの文字数(inPathCnt)が指定された場合。
    1076                        else if( inPathCnt > 0 ) {
    1077                                if( TO_PARENT >= 0 && nval( value[TO_PARENT],null ) != null ) {
    1078                                        // 7.2.7.0 (2020/08/07) 入力共通パス(inPath)指定時は、TO_PARENTかPARENTの桁数より小さい場合のみ処理する。
    1079                                        if( value[TO_PARENT].length() > inPathCnt ) {
    1080                                                final String prntVal = toDir.getAbsolutePath() + value[TO_PARENT].substring( inPathCnt );
    1081                                                tempToDir = mkDirs( prntVal,createDir );
    1082                                        }
    1083                                }
    1084                                else {
    1085                                        // 7.2.7.0 (2020/08/07) 入力共通パス(inPath)指定時は、TO_PARENTかPARENTの桁数より小さい場合のみ処理する。
    1086                                        if( value[PARENT].length() > inPathCnt ) {
    1087                                                final String prntVal = toDir.getAbsolutePath() + value[PARENT].substring( inPathCnt );
    1088                                                tempToDir = mkDirs( prntVal,createDir );
    1089                                        }
    1090                                }
    1091                        }
    1092
    1093                        File toFile = null;
    1094                        if( TO_NAME >= 0 && nval(value[TO_NAME],null) != null  ) {
    1095                                toFile = new File( tempToDir, value[TO_NAME] );
    1096                        }
    1097                        else {
    1098                                toFile = new File( tempToDir, value[NAME] );
    1099                        }
    1100
    1101                        return new File[] { formFile , toFile };
    1102                }
    1103
    1104                /**
    1105                 * 最後に実行された処理で、親フォルダが同一かどうかを返します(同一の場合は、true)。
    1106                 *
    1107                 * makeFromToFile( int ) が処理されたときの、FromDir と toDir が同一であれば、true を、
    1108                 * 異なる場合は、false を返します。
    1109                 * ここでの結果は、厳密な同一判定ではなく、処理的に、同一かどうかを判定しています。
    1110                 * つまり、toDir に FromDir をセットする(３．Ｃのケース)場合に、true を内部変数にセットします。
    1111                 * この判定値は、ファイルの移動処理で、異なる親フォルダの場合は、COPY ＆ DELETE しなければ
    1112                 * なりませんが、同一親フォルダの場合は、RENAME で済む という処理負荷の軽減が目的です。
    1113                 * よって、結果的に、PARENT と TO_PARENT が同じとか、PARENT と targetDir が同じでも
    1114                 * ここでのフラグは、false が返されます。
    1115                 *
    1116                 * @return      最後に実行された処理で、親フォルダが同一の場合は、true
    1117                 * @see         #makeFromToFile( int )
    1118                 */
    1119                public boolean lastParentEquals() {
    1120                        return equalParent ;
    1121                }
    1122
    1123                /**
    1124                 * 一番最後にmkdirsしたﾌｫﾙﾀﾞ名(Exceptionの直前の設定値)を返します。
    1125                 *
    1126                 * mkdirs でException が発生した場合、発生元のﾌｫﾙﾀﾞ名を表示するためのﾃﾞﾊﾞｯｸﾞ用です。
    1127                 *
    1128                 * @og.rev 7.2.7.0 (2020/08/07) MKDIRSｱｸｼｮﾝ 追加
    1129                 *
    1130                 * @return      一番最後にmkdirsしたﾌｫﾙﾀﾞ名(Exceptionの直前の設定値)
    1131                 */
    1132                public String getLastDir() {
    1133                        return lastDir ;
    1134                }
    1135
    1136        //      /**
    1137        //       *  カラム名配列(String[])より、対応するカラムNo配列(int[])を作成します。
    1138        //       *
    1139        //       * ここでは、TO_PARENT や TO_NAME は、存在するかどうか不明なので、
    1140        //       * EXCEPTION にせず、配列番号に、-1 を返すようにしています。
    1141        //       *
    1142        //       * @param       table     一覧が格納されているDBTableModel
    1143        //       * @param       nameArray       カラム名配列
    1144        //       * @return      カラムNo配列(カラム名が存在しない場合は、-1)
    1145        //       */
    1146        //      private int[] getTableColumnNo( final DBTableModel table ,final String[] nameArray ) {
    1147        //              int[] clmNo = new int[ nameArray.length ];
    1148        //              for( int i=0; i<clmNo.length; i++ ) {
    1149        //                      clmNo[i] = table.getColumnNo( nameArray[i] , false );   // カラム名が存在しない場合は、-1 を返す。
    1150        //              }
    1151        //              return clmNo;
    1152        //      }
    1153
    1154                /**
    1155                 * フォルダを作成します。
    1156                 *
    1157                 * フォルダが存在しない場合は、途中階層をすべて作成します。
    1158                 *
    1159                 * @og.rev 7.0.5.0 (2019/09/13) target のﾊﾟｽも、正規パス名から作成。
    1160                 * @og.rev 7.2.7.0 (2020/08/07) 相対ﾊﾟｽの場合の基準ﾌｫﾙﾀﾞ(FILE_URL) 考慮
    1161                 *
    1162                 * @param       fname   フォルダ名
    1163                 * @param       createDir       フォルダ作成可否 [true:作成する/false:作成しない]
    1164                 * @return      フォルダを表すファイルオブジェクト。引数が null の場合は、null を返します。
    1165                 * @throws      HybsSystemException             ファイルか、存在しない場合に、createDir=false か、mkdirs() が false の場合
    1166                 */
    1167                private File mkDirs( final String fname , final boolean createDir ) {
    1168                        lastDir = fname;                                                // 7.2.7.0 (2020/08/07)
    1169                        File target = null;
    1170                        if( fname != null ) {
    1171                                // 7.0.5.0 (2019/09/13) target のﾊﾟｽも、正規パス名から作成。
    1172//                              target = new File( fname );
    1173                                try {
    1174//                                      target = new File( fname ).getCanonicalFile();
    1175                                        final String fname2 = StringUtil.urlAppend( fileURL,fname );                    // 7.2.7.0 (2020/08/07)
    1176                                        target = new File( HybsSystem.url2dir( fname2 ) ).getCanonicalFile();   // 7.2.7.0 (2020/08/07)
    1177                                        if( target.exists() ) {                 // 存在する
    1178                                                if( target.isFile() ) {
    1179                                                        final String errMsg = "ターゲットに、ファイル名は指定できません。" + CR
    1180                                                                                                + "ターゲット=[" + fname2 + "]"  + CR;
    1181                                                        throw new HybsSystemException( errMsg );
    1182                                                }
    1183                                        }
    1184                                        else {                                                  // 存在しない
    1185                                                // 存在しないのに、作成しない
    1186                                                if( !createDir ) {
    1187                                                        final String errMsg = "ターゲットが存在しません。 " + CR
    1188                                                                                                + "ターゲット=[" + fname2 + "]"  + CR;
    1189                                                        throw new HybsSystemException( errMsg );
    1190                                                }
    1191                                                // 作成できない
    1192                                                if( !target.mkdirs() ) {
    1193                                                        final String errMsg = "ターゲットを自動作成使用としましたが、作成できませんでした。" + CR
    1194                                                                                                + "ターゲット=[" + fname2 + "]"  + CR;
    1195                                                        throw new HybsSystemException( errMsg );
    1196                                                }
    1197                                        }
    1198                                }
    1199                                catch( final IOException ex ) {
    1200                                        final String errMsg = "File#getCanonicalFile() で、正式パス名を求めることができませんでした。" + CR
    1201                                                                                + ex.getMessage()
    1202                                                                                + "ターゲット=[" + fname + "]"  + CR;
    1203                                        throw new HybsSystemException( errMsg,ex );
    1204                                }
    1205                        }
    1206                        return target;
    1207                }
    1208        }
    1209
    1210        /**
    1211         * このオブジェクトの文字列表現を返します。
    1212         * 基本的にデバッグ目的に使用します。
    1213         *
    1214         * @return このクラスの文字列表現
    1215         * @og.rtnNotNull
    1216         */
    1217        @Override
    1218        public String toString() {
    1219                return ToString.title( this.getClass().getName() )
    1220                                .println( "VERSION"                     ,VERSION                )
    1221                                .println( "action"                      ,action                 )
    1222                                .println( "command"                     ,command                )
    1223                                .println( "targetDir"           ,targetDir              )
    1224                                .println( "createDir"           ,createDir              )
    1225                                .println( "tableId"                     ,tableId                )
    1226//                              .println( "outMessage"          ,outMessage     )
    1227                                .println( "displayMsg"          ,displayMsg     )
    1228                                .println( "selectedAll"         ,selectedAll    )
    1229                                .println( "keepTimeStamp"       ,keepTimeStamp  )
    1230                                .fixForm().toString() ;
    1231        }
    1232}