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 * ・<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 * /> 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 * <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 * /> 116 * 117 * ●使用例 118 * ・<og:fileUpdate command="{@command}" action="COPY" /> 119 * TO_PARENT または、 TO_NAME(両方指定も可)による行単位 COPY 処理 120 * fileQuery の useUpdateClm="true" を設定し、検索結果に、TO_PARENT、 TO_NAMEカラムを追加します。 121 * TO_PARENT または、 TO_NAME は、columnSet などで値をセットしておきます。 122 * 123 * ・<og:fileUpdate command="{@command}" action="MODIFY" targetDir="AAA_DIR" /> 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 * 1.FromDir は、PARENT 列の値から作成する。 996 * 2.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 * 1.FromDir は、PARENT 列の値から作成する。 1042 * 2.FromFileは、FromDir + NAME列の値から作成する。 1043 * 3.toDir は、 1044 * A.targetDir が有れば、それを使う。 1045 * B.なければ、TO_PARENT 列の値から作成する。 1046 * C.TO_PARENT 列がないか、値が未設定の場合は、FromDir をそのまま使う。 1047 * 4.toFile は、 1048 * A.toDir + TO_NAME 列の値から作成する。 1049 * B.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 をセットする(3.Cのケース)場合に、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}