    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                                }
    531                        }
    532                }
    533                inFile.delete();
    534        }
    535
    536        /**
    537         * MKDIRS アクションを実行します。
    538         *
    539         * この処理では、TO_PARENT ｶﾗﾑに指定されたﾀｰｹﾞｯﾄﾌｫﾙﾀﾞを 多階層mkdirします。
    540         * 実際は、ﾌｧｲﾙ作成やｺﾋﾟｰ時には、mkdirs するので、ここでの使い方の想定は、
    541         * ﾀｰｹﾞｯﾄﾌｫﾙﾀﾞへのｱｸｾｽが可能かどうかの確認です。
    542         * 存在ﾁｪｯｸ(EXISTS)では、本当に存在しない場合も、ｱｸｾｽ出来ない場合も
    543         * false となるためです。
    544         * なお、通常の mkdirs では、ﾌｫﾙﾀﾞが新規に作成されなかった場合(すでに存在)
    545         * false となりますが、ここのｱｸｼｮﾝでは、ｱｸｾｽﾁｪｯｸも兼ねているため、
    546         * mkdirs が成功するか、すでに存在している場合は、正常と判断します。
    547         *
    548         * エラー発生時の引数は、ｱｸｼｮﾝ:{0} From:"" To:{2} です。
    549         *
    550         * @og.rev 7.2.7.0 (2020/08/07) MKDIRSｱｸｼｮﾝ 追加
    551         *
    552         * @param       rowNo           処理を実施する行番号
    553         * @param       fromToFiles     FromFile,ToFileをまとめた補助クラス
    554         * @throws      HybsSystemException     処理中に何らかのエラーが発生した場合
    555         */
    556        private void actionMKDIRS( final int[] rowNo , final FromToFiles fromToFiles ) {
    557                final int rowCount = rowNo.length ;
    558                for( int i=0; i<rowCount; i++ ) {
    559                        try {
    560                                fromToFiles.makeToParent( rowNo[i] );           // 戻り値は確認しない。
    561                        }
    562                        catch( final Throwable th ) {
    563                                if( errMessage == null ) { errMessage = new ErrorMessage( "FileUpdateTag Error" ); }
    564                                // ERR0050:ｱｸｼｮﾝ実行中にｴﾗｰが発生しました。ｱｸｼｮﾝ:{0} From:{1} To:{2}
    565                                errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,actErrMsg,action,"",fromToFiles.getLastDir() );
    566                                errMessage.addMessage( rowNo[i]+1,ErrorMessage.NG,action,th.getMessage() );
    567                                errCode = ErrorMessage.NG;
    568                        }
    569                }
    570        }
    571
    572        /**
    573         * 表示データの HybsSystem.ROW_SEL_KEY を元に、選ばれた 行を処理の対象とします。
    574         *
    575         * @return      選択行の配列
    576         * @og.rtnNotNull
    577         */
    578        @Override
    579        protected int[] getParameterRows() {
    580                final int[] rowNo ;
    581                if( selectedAll ) {
    582                        final int rowCnt = table.getRowCount();
    583                        rowNo = new int[ rowCnt ];
    584                        for( int i=0; i<rowCnt; i++ ) {
    585                                rowNo[i] = i;
    586                        }
    587                } else {
    588                        rowNo = super.getParameterRows();
    589                }
    590                return rowNo ;
    591        }
    592
    593        /**
    594         * 【TAG】アクション[COPY|MOVE|MODIFY|DELETE|MKDIRS]をセットします。
    595         *
    596         * @og.tag
    597         * アクションは、ファイルをコピー(COPY)したり、移動(MOVE,MODIFY)したり、削除(DELETE)、
    598         * ﾌｫﾙﾀﾞ作成(MKDIRS)するなどの操作を指定する必須属性です。
    599         *
    600         * <table class="plain">
    601         *   <caption>action属性(必須)のキーワード</caption>
    602         *   <tr><th>action</th><th>名称</th><th>機能</th></tr>
    603         *   <tr><td>COPY  </td><td>コピー</td><td>オリジナルファイルを、ターゲット(TO_PARENT,TO_NAMEで指定)にコピーします。</td></tr>
    604         *   <tr><td>MOVE  </td><td>移動  </td><td>オリジナルファイルを、ターゲットに移動(COPY+DELETE)/名称変更(RENAME)します。</td></tr>
    605         *   <tr><td>MODIFY</td><td>移動  </td><td>(MOVE と同じ。エンジンの command を利用するための簡易action)</td></tr>
    606         *   <tr><td>DELETE</td><td>削除  </td><td>オリジナルファイルを、削除します。(フォルダ、ファイルに関わらず)</td></tr>
    607         *   <tr><td>MKDIRS</td><td>削除  </td><td>ターゲット(TO_PARENTで指定)フォルダを作成します。 7.2.7.0 (2020/08/07)</td></tr>
    608         * </table>
    609         *
    610         * @og.rev 6.3.4.0 (2015/08/01) Arrays.toString から String.join に置き換え。
    611         * @og.rev 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。
    612         *
    613         * @param       act アクション (public static final 宣言されている文字列)
    614         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.FileUpdateTag.ACT_COPY">アクション定数</a>
    615         */
    616        public void setAction( final String act ) {
    617                action = nval( getRequestParameter( act ),action );
    618
    619                if( action != null && !check( action, ACTION_SET ) ) {
    620                        final String errMsg = "指定のアクションは実行できません。アクションエラー"       + CR
    621                                                        + "action=[" + action + "] "                                                            + CR
    622                                                        + "actionList=" + String.join( ", " , ACTION_SET ) ;
    623                        throw new HybsSystemException( errMsg );
    624                }
    625        }
    626
    627        /**
    628         * 【TAG】ターゲットとなるフォルダを指定します(初期値:null)。
    629         *
    630         * @og.tag
    631         * targetDir 属性を利用する場合は、引数のファイル、またはフォルダが指定されたことに
    632         * なります。COPY、MOVE(,MODIFY) の場合は、targetDir 属性にフォルダを指定することで一括処理可能です。
    633         * 指定先のフォルダが存在しない場合は、createDir属性の値により処理が異なります。
    634         * createDir="true"(初期値)で、ターゲットフォルダが存在しない場合は、自動作成します。
    635         *
    636         * @param  dir ターゲットとなるフォルダ
    637         * @see         #setCreateDir( String )
    638         */
    639        public void setTargetDir( final String dir ) {
    640                targetDir = nval( getRequestParameter( dir ),targetDir );
    641        }
    642
    643        /**
    644         * 【TAG】ターゲットとなるフォルダがなければ、作成するかどうかを指定します(初期値:true)。
    645         *
    646         * @og.tag
    647         * COPY,MOVE(,MODIFY) などの処理で、ターゲットフォルダが存在しないときに、作成するか、エラーにするかを
    648         * createDir属性 で指定できます。
    649         * これは、COPY先やMOVE(,MODIFY)先が存在している前提のシステムで、不要な箇所に間違ってフォルダを
    650         * 自動作成されると困る場合に、false:作成しない とすれば、間違いに気づく確率が上がります。
    651         * 初期値は true:作成する です。
    652         *
    653         * @param       flag    フォルダ作成可否 [true:作成する/false:作成しない]
    654         */
    655        public void setCreateDir( final String flag ) {
    656                createDir = nval( getRequestParameter( flag ),createDir );
    657        }
    658
    659        /**
    660         * 【TAG】fileQuery以外の場合の元親ﾌｫﾙﾀﾞを示すｶﾗﾑ名を指定します(初期値:"PARENT")。
    661         *
    662         * @og.tag
    663         * 通常、fileQueryで取得したﾌｫﾙﾀﾞとﾌｧｲﾙ名は、PARENT,NAME というｶﾗﾑに作成されます。
    664         * ここでは、ﾃﾞｰﾀﾍﾞｰｽ等で管理しているﾌｫﾙﾀﾞやﾌｧｲﾙ名を検索した場合に処理できるように
    665         * それぞれのｶﾗﾑ名を指定できるようにします。
    666         * (初期値:"PARENT")
    667         *
    668         * @og.rev 7.2.7.0 (2020/08/07) parentClm,nameClm,toParentClm,toNameClm 追加
    669         *
    670         * @param       clm 元親ﾌｫﾙﾀﾞを示すｶﾗﾑ名
    671         */
    672        public void setParentClm( final String clm ) {
    673                parentClm = nval( getRequestParameter( clm ),parentClm );
    674        }
    675
    676        /**
    677         * 【TAG】fileQuery以外の場合の元ﾌｧｲﾙ名を示すｶﾗﾑ名を指定します(初期値:"NAME")。
    678         *
    679         * @og.tag
    680         * 通常、fileQueryで取得したﾌｫﾙﾀﾞとﾌｧｲﾙ名は、PARENT,NAME というｶﾗﾑに作成されます。
    681         * ここでは、ﾃﾞｰﾀﾍﾞｰｽ等で管理しているﾌｫﾙﾀﾞやﾌｧｲﾙ名を検索した場合に処理できるように
    682         * それぞれのｶﾗﾑ名を指定できるようにします。
    683         * (初期値:"NAME")
    684         *
    685         * @og.rev 7.2.7.0 (2020/08/07) parentClm,nameClm,toParentClm,toNameClm 追加
    686         *
    687         * @param       clm 元ﾌｧｲﾙ名を示すｶﾗﾑ名
    688         */
    689        public void setNameClm( final String clm ) {
    690                nameClm = nval( getRequestParameter( clm ),nameClm );
    691        }
    692
    693        /**
    694         * 【TAG】fileQuery以外の場合の先親ﾌｫﾙﾀﾞを示すｶﾗﾑ名を指定します(初期値:"TO_PARENT")。
    695         *
    696         * @og.tag
    697         * 通常、fileQueryで取得したﾌｫﾙﾀﾞとﾌｧｲﾙ名は、PARENT,NAME というｶﾗﾑに作成されます。
    698         * ここでは、ﾃﾞｰﾀﾍﾞｰｽ等で管理しているﾌｫﾙﾀﾞやﾌｧｲﾙ名を検索した場合に処理できるように
    699         * それぞれのｶﾗﾑ名を指定できるようにします。
    700         * (初期値:"TO_PARENT")
    701         *
    702         * @og.rev 7.2.7.0 (2020/08/07) parentClm,nameClm,toParentClm,toNameClm 追加
    703         *
    704         * @param       clm 先親ﾌｫﾙﾀﾞを示すｶﾗﾑ名
    705         */
    706        public void setToParentClm( final String clm ) {
    707                toParentClm = nval( getRequestParameter( clm ),toParentClm );
    708        }
    709
    710        /**
    711         * 【TAG】fileQuery以外の場合の先ﾌｧｲﾙ名を示すｶﾗﾑ名を指定します(初期値:"TO_NAME")。
    712         *
    713         * @og.tag
    714         * 通常、fileQueryで取得したﾌｫﾙﾀﾞとﾌｧｲﾙ名は、PARENT,NAME というｶﾗﾑに作成されます。
    715         * ここでは、ﾃﾞｰﾀﾍﾞｰｽ等で管理しているﾌｫﾙﾀﾞやﾌｧｲﾙ名を検索した場合に処理できるように
    716         * それぞれのｶﾗﾑ名を指定できるようにします。
    717         * (初期値:"TO_NAME")
    718         *
    719         * @og.rev 7.2.7.0 (2020/08/07) parentClm,nameClm,toParentClm,toNameClm 追加
    720         *
    721         * @param       clm 先ﾌｧｲﾙ名を示すｶﾗﾑ名
    722         */
    723        public void setToNameClm( final String clm ) {
    724                toNameClm = nval( getRequestParameter( clm ),toNameClm );
    725        }
    726
    727        /**
    728         * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します
    729         *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。
    730         *
    731         * @og.tag
    732         * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に
    733         * 渡す場合に、通常は、session を利用します。その場合の登録キーです。
    734         * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、
    735         * この tableId 属性を利用して、メモリ空間を分けます。
    736         *              (初期値:HybsSystem#TBL_MDL_KEY[={@og.value HybsSystem#TBL_MDL_KEY}])。
    737         *
    738         * @param       id テーブルID (sessionに登録する時のID)
    739         */
    740        public void setTableId( final String id ) {
    741                tableId = nval( getRequestParameter( id ),tableId );
    742        }
    743
    744        /**
    745         * 【TAG】コマンド (ENTRY)をセットします(初期値:ENTRY)。
    746         *
    747         * @og.tag
    748         * このタグは、command="ENTRY" でのみ実行されます。
    749         * コマンドは,HTMLから(get/post)指定されますので,CMD_xxx で設定される
    750         * フィールド定数値のいづれかを、指定できます。
    751         * 初期値は、ENTRY なので、何も指定しなければ、実行されます。
    752         *
    753         * @param       cmd コマンド (public static final 宣言されている文字列)
    754         * @see         <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.FileUpdateTag.CMD_ENTRY">コマンド定数</a>
    755         */
    756        public void setCommand( final String cmd ) {
    757                final String cmd2 = getRequestParameter( cmd );
    758                if( cmd2 != null && cmd2.length() >= 0 ) { command = cmd2.toUpperCase(Locale.JAPAN); }
    759        }
    760
    761//      /**
    762//       * 【TAG】検索結果のメッセージを表示する/しない[true/false]を指定します(初期値:true)。
    763//       *
    764//       * @og.tag
    765//       * 初期値は、表示する：true です。
    766//       *
    767//       * @og.rev 7.2.7.0 (2020/08/07) outMessage 削除
    768//       *
    769//       * @param       flag  メッセージ表示可否 [true:表示する/それ以外:含めない]
    770//       */
    771//      public void setOutMessage( final String flag ) {
    772//              outMessage = nval( getRequestParameter( flag ),outMessage );
    773//      }
    774
    775        /**
    776         * 【TAG】処理結果を画面上に表示するメッセージリソースIDを指定します(初期値:MSG0040[　件登録しました])。
    777         *
    778         * @og.tag
    779         * ここでは、検索結果の件数や登録された件数をまず出力し、
    780         * その次に、ここで指定したメッセージをリソースから取得して表示します。
    781         * 表示させたくない場合は, displayMsg = "" をセットしてください。
    782         * displayMsg の初期値は、MSG0040[　件登録しました]です。
    783         *
    784         * @param       id 処理結果表示メッセージID
    785         */
    786        public void setDisplayMsg( final String id ) {
    787                final String ids = getRequestParameter( id );
    788                if( ids != null ) { displayMsg = ids; }
    789        }
    790
    791        /**
    792         * 【TAG】action実行時のｴﾗｰﾒｯｾｰｼﾞのﾒｯｾｰｼﾞﾘｿｰｽIDを指定します(初期値:ERR0050:ｱｸｼｮﾝ実行中にｴﾗｰが発生しました。
    793         *
    794         * @og.tag
    795         * action実行時のｴﾗｰﾒｯｾｰｼﾞは、COPY|MOVE|MODIFY|DELETE|MKDIRS などのｱｸｼｮﾝ実行時に
    796         * ｴﾗｰが発生した際に、表示するﾒｯｾｰｼﾞﾘｿｰｽのID をセットします。
    797         * ｴﾗｰﾒｯｾｰｼﾞのため、未指定にすることはできません。
    798         * actErrMsg の初期値は、ERR0050:ｱｸｼｮﾝ実行中にｴﾗｰが発生しました。ｱｸｼｮﾝ:{0} From:{1} To:{2}
    799         *
    800         * @og.rev 7.2.7.0 (2020/08/07) MKDIRSｱｸｼｮﾝ 追加
    801         *
    802         * @param       id action実行時のｴﾗｰﾒｯｾｰｼﾞのﾒｯｾｰｼﾞﾘｿｰｽID
    803         */
    804        public void setActErrMsg( final String id ) {
    805                actErrMsg = nval( getRequestParameter( id ),actErrMsg );
    806        }
    807
    808        /**
    809         * 【TAG】データを全件選択済みとして処理するかどうか[true/false]を指定します(初期値:false)。
    810         *
    811         * @og.tag
    812         * 全てのデータを選択済みデータとして扱って処理します。
    813         * 全件処理する場合に、(true/false)を指定します。
    814         * 初期値は false です。
    815         *
    816         * @param  all 全件選択済み指定 [true:全件選択済み/false:通常]
    817         */
    818        public void setSelectedAll( final String all ) {
    819                selectedAll = nval( getRequestParameter( all ),selectedAll );
    820        }
    821
    822        /**
    823         * 【TAG】オリジナルのタイムスタンプを利用するかどうかを指定します(初期値:false)。
    824         *
    825         * @og.tag
    826         * COPYや親違いMOVE(,MODIFY)の時に、オリジナルのタイムスタンプをそのままコピー先のファイルにも
    827         * 適用するかどうかを指定します。
    828         * タイムスタンプを初期化されたくない場合に、true に設定します。
    829         * 初期値は 利用しない:false です。
    830         *
    831         * @param  flag タイムスタンプ利用 [true:する/false:しない]
    832         */
    833        public void setKeepTimeStamp( final String flag ) {
    834                keepTimeStamp = nval( getRequestParameter( flag ),keepTimeStamp );
    835        }
    836
    837        /**
    838         * 【TAG】処理時間を表示する TimeView を表示するかどうか[true:する/false:しない]を指定します
    839         *              (初期値:VIEW_USE_TIMEBAR[={@og.value SystemData#VIEW_USE_TIMEBAR}])。
    840         *
    841         * @og.tag
    842         * true に設定すると、処理時間を表示するバーイメージが表示されます。
    843         * これは、DB検索、APサーバー処理、画面表示の各処理時間をバーイメージで
    844         * 表示させる機能です。処理時間の目安になります。
    845         * (初期値:VIEW_USE_TIMEBAR[={@og.value SystemData#VIEW_USE_TIMEBAR}])。
    846         *
    847         * @og.rev 6.3.6.0 (2015/08/16) useTimeView の初期値を、VIEW_USE_TIMEBAR にする。
    848         *
    849         * @param       flag    処理時間を表示 [true:する/false:しない]
    850         */
    851        public void setUseTimeView( final String flag ) {
    852                useTimeView = nval( getRequestParameter( flag ),useTimeView );
    853        }
    854
    855        /**
    856         * 【TAG】入力共通パスを指定します。
    857         *
    858         * @og.tag
    859         * 通常、fileQueryタグ等で、検索した結果は、PARENT,NAME というカラムにセットされます。
    860         * この、fileQueryのfrom属性に、検索を開始するディレクトリを指定し、multi="true"で、
    861         * 多段階展開 した場合、この、from属性に指定したパスを、inPath にセットすることで、
    862         * 以下の階層フォルダそのままに、targetDir にCOPY または、MOVE することが出来ます。
    863         * 逆に、指定しない場合は、フォルダ階層無しで、COPY,MOVE されます。
    864         *
    865         * @og.rev 6.8.0.0 (2017/06/02) 入力共通パスを指定します。
    866         * @og.rev 7.0.5.0 (2019/09/13) inPath のﾊﾟｽは、正規パス名から作成。
    867         *
    868         * @param       path    入力共通パス
    869         */
    870        public void setInPath( final String path ) {
    871                inPath = nval( getRequestParameter( path ),inPath );
    872
    873                // 7.0.5.0 (2019/09/13) inPath のﾊﾟｽは、正規パス名から作成。
    874                if( inPath != null ) {
    875                        try {
    876                                inPath = new File(inPath).getCanonicalPath();
    877                        }
    878                        catch( final IOException ex ) {
    879                                final String errMsg = "inPathの正式なファイル名の取得に失敗しました。[" + inPath + "]"
    880                                                        + CR + ex.getMessage();
    881                                throw new HybsSystemException( errMsg,ex );
    882                        }
    883                }
    884        }
    885
    886        /**
    887         * 【TAG】ｴﾗｰﾒｯｾｰｼﾞにSLABELを利用するかどうか[true/false]を指定します(初期値:false)。
    888         *
    889         * @og.tag
    890         * 通常のｴﾗｰﾒｯｾｰｼﾞは、ﾗﾍﾞﾙ（長）が使われますが、これをﾗﾍﾞﾙ（短）を使いたい場合に、true にセットします。
    891         * ここでのラベル（短）は、ﾀｸﾞ修飾なしの、ﾗﾍﾞﾙ（短）です。
    892         * 標準はfalse:利用しない=ﾗﾍﾞﾙ（長）です。
    893         * true/false以外を指定した場合はfalse扱いとします。
    894         *
    895         * ﾗﾍﾞﾙﾘｿｰｽの概要説明があれば表示しますが、useSLabel="true" 時は、概要説明を表示しません。
    896         *
    897         * @og.rev 7.0.7.0 (2019/12/13) 新規追加
    898         *
    899         * @param prm SLABEL利用 [true:利用する/false:利用しない]
    900         */
    901        public void setUseSLabel( final String prm ) {
    902                useSLabel = nval( getRequestParameter( prm ),useSLabel );
    903        }
    904
    905        /**
    906         * 【TAG】エラー時に処理後に停止するかどうか[true/false]を指定します(初期値:true)。
    907         *
    908         * @og.tag
    909         * 処理結果などに応じて、以下の処理を停止したい場合に、使用します。
    910         * false を指定すると、判定結果に無関係に、以下の処理を実行します。
    911         * 処理は継続したいが、警告表示する場合に、useStop="false" を指定します。
    912         * 初期値は、停止する ("true")です。
    913         *
    914         * @og.rev 7.2.7.0 (2020/08/07) エラー時に処理後に停止(true)するかどうか(useStop対応)
    915         *
    916         * @param   flag 処理後停止 [true:する/それ以外:しない]
    917         */
    918        public void setUseStop( final String flag ) {
    919                useStop = nval( getRequestParameter( flag ),useStop );
    920        }
    921
    922        /**
    923         * DBTableModel から、FromFile,ToFile を作成するための処理をまとめた補助クラスです。
    924         *
    925         * ここでは、オリジナルファイルやターゲットファイルを作成するための処理のみを集めています。
    926         * メソッドにすると、ローカル変数を多く管理するか、多数の引数渡しを繰り返すことになるため、
    927         * このローカルクラスに処理と、値を格納します。
    928         *
    929         * @og.rev 7.2.7.0 (2020/08/07) 相対ﾊﾟｽの場合の基準ﾌｫﾙﾀﾞ(FILE_URL) 考慮
    930         */
    931        private static final class FromToFiles {
    932                private final String fileURL = HybsSystem.sys( "FILE_URL" );            // 7.2.7.0 (2020/08/07) 相対ﾊﾟｽの場合の基準ﾌｫﾙﾀﾞ
    933
    934                private final DBTableModel      table ;
    935
    936                private final int PARENT        ;
    937                private final int NAME          ;
    938                private final int TO_PARENT     ;
    939                private final int TO_NAME       ;
    940
    941                private final File              toDir   ;
    942                private final boolean   createDir;              // ターゲットとなるフォルダがなければ、作成するかどうか(true:作成する)
    943                private final int               inPathCnt;              // 6.8.0.0 (2017/06/02) 入力共通パスの文字数
    944
    945                private boolean equalParent     ;                       // 最後に実行された処理で、親フォルダが同一の場合は、true
    946                private String  lastDir ;                               // 7.2.7.0 (2020/08/07) 一番最後にmkdirsしたﾌｫﾙﾀﾞ名(Exceptionの直前の設定値)
    947
    948                /**
    949                 *  引数指定のコンストラクター
    950                 *
    951                 * 必要なパラメータを渡して、オブジェクトを構築します。
    952                 * 入力共通パス(inPath)は、COPY/MOVE時にtargetDirと置換されます。
    953                 *
    954                 * @og.rev 6.8.0.0 (2017/06/02) 入力共通パス(inPath)を指定します。
    955                 * @og.rev 7.2.7.0 (2020/08/07) parentClm,nameClm,toParentClm,toNameClm 追加
    956                 *
    957                 * @param       table     一覧が格納されているDBTableModel
    958                 * @param       targetDir       ターゲットとなるフォルダ
    959                 * @param       createDir       フォルダ作成可否 [true:作成する/false:作成しない]
    960                 * @param       inPath          入力共通パス
    961                 * @param       clms            parentClm,nameClm,toParentClm,toNameClm の配列
    962                 */
    963//              public FromToFiles( final DBTableModel table , final String targetDir , final boolean createDir , final String inPath ) {
    964                public FromToFiles( final DBTableModel table , final String targetDir , final boolean createDir , final String inPath , final String[] clms ) {
    965
    966                        this.table              = table;
    967                        this.createDir  = createDir ;
    968                        toDir                   = mkDirs( targetDir,createDir );                        // targetDir が指定されていない場合は、null
    969                        // 7.0.5.0 (2019/09/13) inPath のﾊﾟｽの文字数も、正規パス名から作成。
    970                        inPathCnt               = inPath == null ? 0 : inPath.length() ;        // 6.8.0.0 (2017/06/02) 入力共通パスの文字数
    971
    972                        // "PARENT","NAME","TO_PARENT","TO_NAME" のカラム名のDBTableModelのカラム番号。存在しない場合は、-1
    973//                      PARENT          = table.getColumnNo( "PARENT"   , false );
    974//                      NAME            = table.getColumnNo( "NAME"             , false );
    975//                      TO_PARENT       = table.getColumnNo( "TO_PARENT", false );
    976//                      TO_NAME         = table.getColumnNo( "TO_NAME"  , false );
    977
    978                        PARENT          = table.getColumnNo( clms[0]    , false );              // 7.2.7.0 (2020/08/07) parentClm
    979                        NAME            = table.getColumnNo( clms[1]    , false );              // 7.2.7.0 (2020/08/07) nameClm
    980                        TO_PARENT       = table.getColumnNo( clms[2]    , false );              // 7.2.7.0 (2020/08/07) toParentClm
    981                        TO_NAME         = table.getColumnNo( clms[3]    , false );              // 7.2.7.0 (2020/08/07) toNameClm
    982                }
    983
    984                /**
    985                 * 行番号より、対応するオリジナルファイル(FromFile)を返します。
    986                 *
    987                 * ここでは、TO_PARENT や TO_NAME は、判定する必要がないため、makeFromToFile( int ) の
    988                 * 一部のみで処理が終了できます。
    989                 * １．FromDir は、PARENT 列の値から作成する。
    990                 * ２．FromFileは、FromDir ＋ NAME列の値から作成する。
    991                 *
    992                 * 配列返しの関係で、メソッド(および内部処理)を分けています。
    993                 *
    994                 * @param       rowNo   カラムNo
    995                 * @return      オリジナルファイル(FromFile)
    996                 * @og.rtnNotNull
    997                 * @see         #makeFromToFile( int )
    998                 */
    999                public File makeFromOnly( final int rowNo ) {
    1000                        final String[] value = table.getValues( rowNo );
    1001                        final File fromDir  = mkDirs( value[PARENT],createDir );
    1002
    1003                        return new File( fromDir, value[NAME] ) ;
    1004                }
    1005
    1006                /**
    1007                 * 行番号より、対応するTO_PARENT ﾌｫﾙﾀﾞのFileｵﾌﾞｼﾞｪｸﾄを返します。
    1008                 *
    1009                 * ここでは、TO_PARENT のみで処理します。
    1010                 *
    1011                 * 実質的には、MKDIRSｱｸｼｮﾝ でしか使用しないので、Fileｵﾌﾞｼﾞｪｸﾄを作成する必要すら
    1012                 * ありませんが、ﾒｿｯﾄﾞ共通化の関係で、ｵﾘｼﾞﾅﾙをそのまま使用します。
    1013                 *
    1014                 * @og.rev 7.2.7.0 (2020/08/07) MKDIRSｱｸｼｮﾝ 追加
    1015                 *
    1016                 * @param       rowNo   カラムNo
    1017                 * @return      TO_PARENT ﾌｫﾙﾀﾞのFileｵﾌﾞｼﾞｪｸﾄ(ｶﾗﾑが存在しない場合は、null)
    1018                 */
    1019                public File makeToParent( final int rowNo ) {
    1020                        final File rtnFile ;
    1021                        if( TO_PARENT >= 0 ) {
    1022                                final String[] value = table.getValues( rowNo );
    1023                                rtnFile = mkDirs( value[TO_PARENT],true );
    1024                        }
    1025                        else {
    1026                                rtnFile = null;
    1027                        }
    1028                        return rtnFile;
    1029                }
    1030
    1031                /**
    1032                 * 行番号より、対応するオリジナルファイル(FromFile)とターゲットファイル(ToFile)を配列に格納して返します。
    1033                 *
    1034                 * ここでは、TO_PARENT や TO_NAME は、存在するかどうか不明なので、以下の手順で作成します。
    1035                 * １．FromDir は、PARENT 列の値から作成する。
    1036                 * ２．FromFileは、FromDir ＋ NAME列の値から作成する。
    1037                 * ３．toDir は、
    1038                 *       Ａ．targetDir が有れば、それを使う。
    1039                 *       Ｂ．なければ、TO_PARENT 列の値から作成する。
    1040                 *       Ｃ．TO_PARENT 列がないか、値が未設定の場合は、FromDir をそのまま使う。
    1041                 * ４．toFile は、
    1042                 *       Ａ．toDir ＋ TO_NAME 列の値から作成する。
    1043                 *       Ｂ．TO_NAME 列がないか、値が未設定の場合は、toDir ＋ NAME列の値から作成する。
    1044                 * 返り値は、new File[] { formFile , toFile }; とする。
    1045                 *
    1046                 * @og.rev 6.8.0.0 (2017/06/02) 入力共通パス(inPath)を指定します。
    1047                 * @og.rev 7.2.7.0 (2020/08/07) 入力共通パス(inPath)指定時は、TO_PARENTかPARENTの桁数より小さい場合のみ処理する。
    1048                 *
    1049                 * @param       rowNo   カラムNo
    1050                 * @return      ファイル配列(0:オリジナルファイル 1:ターゲットファイル)
    1051                 * @og.rtnNotNull
    1052                 */
    1053                public File[] makeFromToFile( final int rowNo ) {
    1054                        final String[] value = table.getValues( rowNo );
    1055                        final File fromDir  = mkDirs( value[PARENT],createDir );
    1056                        final File formFile = new File( fromDir, value[NAME] );
    1057                        File tempToDir = toDir;
    1058
    1059                        equalParent = false;    // 最後に実行された処理で、親フォルダが同一かどうかのフラグをリセットする。
    1060                        if( tempToDir == null ) {
    1061                                if( TO_PARENT >= 0 && nval( value[TO_PARENT],null ) != null ) {
    1062                                        tempToDir = mkDirs( value[TO_PARENT],createDir );
    1063                                }
    1064                                else {
    1065                                        tempToDir = fromDir;
    1066                                        equalParent = true;             // 最後に実行された処理で、親フォルダが同一の場合は、true
    1067                                }
    1068                        }
    1069                        // 6.8.0.0 (2017/06/02) toDirが指定され、かつ、入力共通パスの文字数(inPathCnt)が指定された場合。
    1070                        else if( inPathCnt > 0 ) {
    1071                                if( TO_PARENT >= 0 && nval( value[TO_PARENT],null ) != null ) {
    1072                                        // 7.2.7.0 (2020/08/07) 入力共通パス(inPath)指定時は、TO_PARENTかPARENTの桁数より小さい場合のみ処理する。
    1073                                        if( value[TO_PARENT].length() > inPathCnt ) {
    1074                                                final String prntVal = toDir.getAbsolutePath() + value[TO_PARENT].substring( inPathCnt );
    1075                                                tempToDir = mkDirs( prntVal,createDir );
    1076                                        }
    1077                                }
    1078                                else {
    1079                                        // 7.2.7.0 (2020/08/07) 入力共通パス(inPath)指定時は、TO_PARENTかPARENTの桁数より小さい場合のみ処理する。
    1080                                        if( value[PARENT].length() > inPathCnt ) {
    1081                                                final String prntVal = toDir.getAbsolutePath() + value[PARENT].substring( inPathCnt );
    1082                                                tempToDir = mkDirs( prntVal,createDir );
    1083                                        }
    1084                                }
    1085                        }
    1086
    1087                        File toFile = null;
    1088                        if( TO_NAME >= 0 && nval(value[TO_NAME],null) != null  ) {
    1089                                toFile = new File( tempToDir, value[TO_NAME] );
    1090                        }
    1091                        else {
    1092                                toFile = new File( tempToDir, value[NAME] );
    1093                        }
    1094
    1095                        return new File[] { formFile , toFile };
    1096                }
    1097
    1098                /**
    1099                 * 最後に実行された処理で、親フォルダが同一かどうかを返します(同一の場合は、true)。
    1100                 *
    1101                 * makeFromToFile( int ) が処理されたときの、FromDir と toDir が同一であれば、true を、
    1102                 * 異なる場合は、false を返します。
    1103                 * ここでの結果は、厳密な同一判定ではなく、処理的に、同一かどうかを判定しています。
    1104                 * つまり、toDir に FromDir をセットする(３．Ｃのケース)場合に、true を内部変数にセットします。
    1105                 * この判定値は、ファイルの移動処理で、異なる親フォルダの場合は、COPY ＆ DELETE しなければ
    1106                 * なりませんが、同一親フォルダの場合は、RENAME で済む という処理負荷の軽減が目的です。
    1107                 * よって、結果的に、PARENT と TO_PARENT が同じとか、PARENT と targetDir が同じでも
    1108                 * ここでのフラグは、false が返されます。
    1109                 *
    1110                 * @return      最後に実行された処理で、親フォルダが同一の場合は、true
    1111                 * @see         #makeFromToFile( int )
    1112                 */
    1113                public boolean lastParentEquals() {
    1114                        return equalParent ;
    1115                }
    1116
    1117                /**
    1118                 * 一番最後にmkdirsしたﾌｫﾙﾀﾞ名(Exceptionの直前の設定値)を返します。
    1119                 *
    1120                 * mkdirs でException が発生した場合、発生元のﾌｫﾙﾀﾞ名を表示するためのﾃﾞﾊﾞｯｸﾞ用です。
    1121                 *
    1122                 * @og.rev 7.2.7.0 (2020/08/07) MKDIRSｱｸｼｮﾝ 追加
    1123                 *
    1124                 * @return      一番最後にmkdirsしたﾌｫﾙﾀﾞ名(Exceptionの直前の設定値)
    1125                 */
    1126                public String getLastDir() {
    1127                        return lastDir ;
    1128                }
    1129
    1130        //      /**
    1131        //       *  カラム名配列(String[])より、対応するカラムNo配列(int[])を作成します。
    1132        //       *
    1133        //       * ここでは、TO_PARENT や TO_NAME は、存在するかどうか不明なので、
    1134        //       * EXCEPTION にせず、配列番号に、-1 を返すようにしています。
    1135        //       *
    1136        //       * @param       table     一覧が格納されているDBTableModel
    1137        //       * @param       nameArray       カラム名配列
    1138        //       * @return      カラムNo配列(カラム名が存在しない場合は、-1)
    1139        //       */
    1140        //      private int[] getTableColumnNo( final DBTableModel table ,final String[] nameArray ) {
    1141        //              int[] clmNo = new int[ nameArray.length ];
    1142        //              for( int i=0; i<clmNo.length; i++ ) {
    1143        //                      clmNo[i] = table.getColumnNo( nameArray[i] , false );   // カラム名が存在しない場合は、-1 を返す。
    1144        //              }
    1145        //              return clmNo;
    1146        //      }
    1147
    1148                /**
    1149                 * フォルダを作成します。
    1150                 *
    1151                 * フォルダが存在しない場合は、途中階層をすべて作成します。
    1152                 *
    1153                 * @og.rev 7.0.5.0 (2019/09/13) target のﾊﾟｽも、正規パス名から作成。
    1154                 * @og.rev 7.2.7.0 (2020/08/07) 相対ﾊﾟｽの場合の基準ﾌｫﾙﾀﾞ(FILE_URL) 考慮
    1155                 *
    1156                 * @param       fname   フォルダ名
    1157                 * @param       createDir       フォルダ作成可否 [true:作成する/false:作成しない]
    1158                 * @return      フォルダを表すファイルオブジェクト。引数が null の場合は、null を返します。
    1159                 * @throws      HybsSystemException             ファイルか、存在しない場合に、createDir=false か、mkdirs() が false の場合
    1160                 */
    1161                private File mkDirs( final String fname , final boolean createDir ) {
    1162                        lastDir = fname;                                                // 7.2.7.0 (2020/08/07)
    1163                        File target = null;
    1164                        if( fname != null ) {
    1165                                // 7.0.5.0 (2019/09/13) target のﾊﾟｽも、正規パス名から作成。
    1166//                              target = new File( fname );
    1167                                try {
    1168//                                      target = new File( fname ).getCanonicalFile();
    1169                                        final String fname2 = StringUtil.urlAppend( fileURL,fname );                    // 7.2.7.0 (2020/08/07)
    1170                                        target = new File( HybsSystem.url2dir( fname2 ) ).getCanonicalFile();   // 7.2.7.0 (2020/08/07)
    1171                                        if( target.exists() ) {                 // 存在する
    1172                                                if( target.isFile() ) {
    1173                                                        final String errMsg = "ターゲットに、ファイル名は指定できません。" + CR
    1174                                                                                                + "ターゲット=[" + fname2 + "]"  + CR;
    1175                                                        throw new HybsSystemException( errMsg );
    1176                                                }
    1177                                        }
    1178                                        else {                                                  // 存在しない
    1179                                                // 存在しないのに、作成しない
    1180                                                if( !createDir ) {
    1181                                                        final String errMsg = "ターゲットが存在しません。 " + CR
    1182                                                                                                + "ターゲット=[" + fname2 + "]"  + CR;
    1183                                                        throw new HybsSystemException( errMsg );
    1184                                                }
    1185                                                // 作成できない
    1186                                                if( !target.mkdirs() ) {
    1187                                                        final String errMsg = "ターゲットを自動作成使用としましたが、作成できませんでした。" + CR
    1188                                                                                                + "ターゲット=[" + fname2 + "]"  + CR;
    1189                                                        throw new HybsSystemException( errMsg );
    1190                                                }
    1191                                        }
    1192                                }
    1193                                catch( final IOException ex ) {
    1194                                        final String errMsg = "File#getCanonicalFile() で、正式パス名を求めることができませんでした。" + CR
    1195                                                                                + ex.getMessage()
    1196                                                                                + "ターゲット=[" + fname + "]"  + CR;
    1197                                        throw new HybsSystemException( errMsg,ex );
    1198                                }
    1199                        }
    1200                        return target;
    1201                }
    1202        }
    1203
    1204        /**
    1205         * このオブジェクトの文字列表現を返します。
    1206         * 基本的にデバッグ目的に使用します。
    1207         *
    1208         * @return このクラスの文字列表現
    1209         * @og.rtnNotNull
    1210         */
    1211        @Override
    1212        public String toString() {
    1213                return ToString.title( this.getClass().getName() )
    1214                                .println( "VERSION"                     ,VERSION                )
    1215                                .println( "action"                      ,action                 )
    1216                                .println( "command"                     ,command                )
    1217                                .println( "targetDir"           ,targetDir              )
    1218                                .println( "createDir"           ,createDir              )
    1219                                .println( "tableId"                     ,tableId                )
    1220//                              .println( "outMessage"          ,outMessage     )
    1221                                .println( "displayMsg"          ,displayMsg     )
    1222                                .println( "selectedAll"         ,selectedAll    )
    1223                                .println( "keepTimeStamp"       ,keepTimeStamp  )
    1224                                .fixForm().toString() ;
    1225        }
    1226}