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 static org.opengion.fukurou.util.StringUtil.*; 019 020import java.io.File; 021import java.io.IOException; 022import java.io.ObjectInputStream; 023import java.io.ObjectOutputStream; 024import java.io.Serializable; 025import java.util.Comparator ; 026import java.util.Locale ; 027import java.util.Set ; 028import java.util.TreeSet ; 029 030import org.opengion.fukurou.util.ErrorMessage; 031import org.opengion.fukurou.util.FileUtil; 032import org.opengion.fukurou.util.StringUtil ; 033import org.opengion.hayabusa.common.HybsSystem; 034import org.opengion.hayabusa.common.HybsSystemException; 035import org.opengion.hayabusa.db.DBTableModel; 036import org.opengion.hayabusa.io.HybsFileOperationFactory; 037 038/** 039 * ファイル検索リストを元に、action に基づいた処理を行うタグです。 040 * command="ENTRY" 時のみ処理を行います。 041 * 042 * fileQuery などで検索したファイル一覧のDBTableModel を元に、ファイルの 043 * コピー(COPY)、移動(MOVE,MODIFY)、削除(DELETE)などの処理を行います。 044 * 処理を行うオリジナルファイルは、PARENT,NAME というカラムでなければなりません。 045 * このカラム名は、fileQuery の検索時には、必ず作成されるカラムです。 046 * また、各アクションに対応するターゲットファイルは、TO_PARENT,TO_NAME という 047 * カラムで指定するか、targetDir 属性を利用してフォルダを指定します。 048 * TO_PARENT(先フォルダ)と、TO_NAME(先ファイル名)は、処理に応じて、必要なカラムが 049 * あれば、自動的に処理します。 050 * つまり、TO_PARENT のみの場合は、ファイル名はオリジナルのまま、フォルダのみ変更します。 051 * 逆に、TO_NAME の場合は、フォルダはそのままで、ファイル名のみ指定します。 052 * 両方同時に指定することも可能です。 053 * targetDir 属性で指定する場合は、TO_PARENT のみに同じ値を設定した場合と同じになります。 054 * この属性を指定すると、TO_PARENT は無視されます。(TO_NAME は有効です。) 055 * COPY、MOVE(,MODIFY) の場合は、指定のフォルダに一括処理可能です。 056 * COPY、MOVE(,MODIFY) などの処理で、ターゲットフォルダが存在しないときに、作成するか、エラーにするかは 057 * createDir属性 で指定できます。初期値は、(true:作成する) です。 058 * これは、COPY先やMOVE(,MODIFY)先が存在している前提のシステムで、不要な箇所に間違ってフォルダを 059 * 自動作成されると困る場合に、(false:作成しない) とすれば、間違いに気づく確率が上がります。 060 * 061 * ※ このタグは、Transaction タグの対象ではありません。 062 * 063 * @og.formSample 064 * ●body:なし 065 * ●形式: 066 * ・<og:fileUpdate 067 * action = "COPY|MOVE|MODIFY|DELETE" アクション属性(必須) 068 * command = "[ENTRY]" ENTRY 時のみ実行します(初期値:ENTRY) 069 * targetDir = "[指定フォルダ]" ターゲットとなるフォルダ 070 * createDir = "[true/false]" ターゲットとなるフォルダがなければ作成する(true)かどうか(初期値:true) 071 * tableId = [HybsSystem.TBL_MDL_KEY] DBTableModel を取り出すキー 072 * outMessage = "[true/false]" 検索結果のメッセージを表示する(true)かどうかを指定(初期値:true) 073 * displayMsg = "MSG0040"; 処理結果を表示します(初期値:「 件登録しました。」) 074 * selectedAll = "[false/true]" データを全件選択済みとして処理する(true)かどうか指定(初期値:false) 075 * keepTimeStamp = "[false/true]" COPY,親違いMOVE(,MODIFY)の時にオリジナルのタイムスタンプを使用するかどうか(初期値:false) 076 * /> 077 * 078 * [action属性(必須)] 079 * COPY オリジナルファイルを、ターゲット(TO_PARENT,TO_NAMEで指定)にコピーします。 080 * MOVE オリジナルファイルを、ターゲットに移動(COPY+DELETE)/名称変更(RENAME)します。 081 * MODIFY (MOVE と同じ。エンジンの command を利用するための簡易action) 082 * DELETE オリジナルファイルを削除します(ターゲット(TO_PARENT,TO_NAME)は、関係しません)。 083 * 084 * ●Tag定義: 085 * <og:fileUpdate 086 * action ○【TAG】アクション[COPY|MOVE|MODIFY|DELETE]をセットします(必須)。 087 * command 【TAG】コマンド[ENTRY]をセットします 088 * targetDir 【TAG】ターゲットとなるフォルダを指定します 089 * createDir 【TAG】ターゲットとなるフォルダがなければ、作成するかどうかを指定します(初期値:true) 090 * tableId 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します 091 * outMessage 【TAG】検索結果のメッセージを表示する/しない[true/false]を指定します(初期値:true) 092 * displayMsg 【TAG】処理結果を画面上に表示するメッセージリソースIDを指定します(初期値:MSG0040[ 件登録しました]) 093 * selectedAll 【TAG】データを全件選択済みとして処理するかどうか[true/false]を指定します(初期値:false) 094 * keepTimeStamp 【TAG】オリジナルのタイムスタンプを利用するかどうかを指定します(初期値:false) 095 * caseKey 【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null) 096 * caseVal 【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null) 097 * scope 【TAG】キャッシュする場合のスコープ[request/page/session/applicaton]を指定します(初期値:session) 098 * fromStorageType 【TAG】ターゲットの読み込み元のストレージタイプを指定します(初期値:CLOUD_TARGET) 099 * fromBucketName 【TAG】ターゲットの読み込み元のバケット名を指定します(初期値:CLOUD_BUCKET) 100 * toStorageType 【TAG】ターゲットの保存先のストレージタイプを指定します(初期値:CLOUD_TARGET) 101 * toBucketName 【TAG】ターゲットの保存先のバケット名を指定します(初期値:CLOUD_BUCKET) 102 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 103 * /> 104 * 105 * ●使用例 106 * ・<og:fileUpdate command="{@command}" action="COPY" /> 107 * TO_PARENT または、 TO_NAME(両方指定も可)による行単位 COPY 処理 108 * fileQuery の useUpdateClm="true" を設定し、検索結果に、TO_PARENT、 TO_NAMEカラムを追加します。 109 * TO_PARENT または、 TO_NAME は、columnSet などで値をセットしておきます。 110 * 111 * ・<og:fileUpdate command="{@command}" action="MODIFY" targetDir="AAA_DIR" /> 112 * fileQuery の検索結果を、AAA_DIR フォルダに移動します。 113 * ファイル名は、そのままオリジナルの値が使用されます。 114 * 115 * @og.rev 5.3.4.0 (2011/04/01) 新規追加 116 * @og.rev 5.10.9.0 (2019/03/01) oota クラウドストレージ対応を追加。(Fileクラスを拡張) 117 * 118 * @og.group ファイル出力 119 * 120 * @version 4.0 121 * @author Kazuhiko Hasegawa 122 * @since JDK5.0, 123 */ 124public class FileUpdateTag extends CommonTagSupport { 125 //* このプログラムのVERSION文字列を設定します。 {@value} */ 126 private static final String VERSION = "5.6.5.2 (2013/06/21)" ; 127 128 private static final long serialVersionUID = 565220130621L ; 129 130 /** command 引数に渡す事の出来る コマンド 登録{@value} */ 131 public static final String CMD_ENTRY = "ENTRY" ; 132 /** command 引数に渡す事の出来る コマンド リスト */ 133 private static final String COMMAND_LIST = CMD_ENTRY; 134 135 /** エラーメッセージID {@value} */ 136 private static final String errMsgId = HybsSystem.ERR_MSG_KEY; 137 138 /** action 引数に渡す事の出来る アクションコマンド COPY {@value} */ 139 public static final String ACT_COPY = "COPY" ; 140 /** action 引数に渡す事の出来る アクションコマンド MOVE {@value} */ 141 public static final String ACT_MOVE = "MOVE" ; 142 /** action 引数に渡す事の出来る アクションコマンド MODIFY {@value} */ 143 public static final String ACT_MODIFY = "MODIFY" ; 144 /** action 引数に渡す事の出来る アクションコマンド DELETE {@value} */ 145 public static final String ACT_DELETE = "DELETE" ; 146 147 private static final String[] ACTION_LIST = new String[] { ACT_COPY , ACT_MOVE , ACT_MODIFY , ACT_DELETE }; 148 149 private String action = null; 150 private String targetDir = null; // ターゲットとなるフォルダ 151 private boolean createDir = true; // ターゲットとなるフォルダがなければ、作成するかどうか(true:作成する) 152 153 private String tableId = HybsSystem.TBL_MDL_KEY; 154 private String command = CMD_ENTRY; 155 private boolean outMessage = true; 156 private String displayMsg = "MSG0040"; // 件登録しました。 157 private boolean selectedAll = false; 158 private boolean keepTimeStamp = false; // オリジナルのタイムスタンプを利用する場合、true 159 160 private transient DBTableModel table = null; 161 private transient ErrorMessage errMessage = null; 162 private int executeCount = -1; // 処理件数 163 private int errCode = ErrorMessage.OK; 164 private long dyStart = 0; 165 166 private String fromStorageType = null; // 5.10.9.0 (2019/03/01) ADD 167 private String fromBucketName = null; // 5.10.9.0 (2019/03/01) ADD 168 private String toStorageType = null; // 5.10.9.0 (2019/03/01) ADD 169 private String toBucketName = null; // 5.10.9.0 (2019/03/01) ADD 170 171 /** 172 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 173 * 174 * @og.rev 5.10.2.2 (2018/08/24) 一部のエラーをjspPrintから標準のErrorMessageに変更 175 * 176 * @return 後続処理の指示 177 */ 178 @Override 179 public int doEndTag() { 180 debugPrint(); 181 // 5.2.2.0 (2010/11/01) caseKey 、caseVal 属性対応 182 if( !useTag() ) { return(EVAL_PAGE); } 183 184 dyStart = System.currentTimeMillis(); 185 186 table = (DBTableModel)getObject( tableId ); 187 188 String label = ""; // 4.0.0 (2005/11/30) 検索しなかった場合。 189 if( table != null && table.getRowCount() > 0 && check( command, COMMAND_LIST ) ) { 190 startQueryTransaction( tableId ); 191 192 execute(); // 実際の処理を実行します。 193 194 StringBuilder buf = new StringBuilder( HybsSystem.BUFFER_SMALL ); 195 196 setRequestAttribute( "DB.COUNT" , String.valueOf( executeCount ) ); 197 setRequestAttribute( "DB.ERR_CODE", String.valueOf( errCode ) ); 198 199 // 5.10.2.2 (2018/08/24) 6.9.9.0 「ERR0041:検索処理中に割り込みの検索要求がありました」エラーを、標準のErrorMessageに追加するようにします。 200 if( ! commitTableObject( tableId, table ) ) { 201 if( errMessage == null ) { errMessage = new ErrorMessage( "FileUpdateTag Query Error!" ); } 202 // ERR0041:検索処理中に割り込みの検索要求がありました。処理されません。 203 errMessage.addMessage( 0,ErrorMessage.NG,"ERR0041" ); 204 errCode = ErrorMessage.NG; 205 } 206 207 String err = TaglibUtil.makeHTMLErrorTable( errMessage,getResource() ); 208 if( err != null && err.length() > 0 ) { 209 buf.append( err ); 210 setSessionAttribute( errMsgId,errMessage ); 211 } 212 label = buf.toString(); 213 214// // 5.10.2.2 (2018/08/24) 6.9.9.0 215// if( table != null && ! commitTableObject( tableId, table ) ) { 216// jspPrint( "FileUpdateTag Query処理が割り込まれました。DBTableModel は登録しません。" ); 217// return (SKIP_PAGE); 218// } 219 } 220 221 jspPrint( label ); 222 223 // 実行件数の表示 224 // 4.0.0 (2005/11/30) 出力順の変更。一番最初に出力します。 225 if( displayMsg != null && displayMsg.length() > 0 ) { 226 String status = executeCount + getResource().getLabel( displayMsg ) ; 227 jspPrint( status + HybsSystem.BR ); 228 } 229 230 // 3.5.4.7 (2004/02/06) 231 long dyTime = System.currentTimeMillis()-dyStart; 232 jspPrint( "<div id=\"queryTime\" value=\"" + (dyTime) + "\"></div>" ); // 3.5.6.3 (2004/07/12) 233 234 return( EVAL_PAGE ); 235 } 236 237 /** 238 * タグリブオブジェクトをリリースします。 239 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 240 * 241 * @og.rev 5.10.9.0 (2019/03/01) 属性にfromStorageType,fromBucketName,toStorageType,toBucketNameを追加。 242 */ 243 @Override 244 protected void release2() { 245 super.release2(); 246 tableId = HybsSystem.TBL_MDL_KEY; 247 command = CMD_ENTRY; 248 action = null; 249 targetDir = null; // ターゲットとなるフォルダ 250 createDir = true; // ターゲットとなるフォルダがなければ、作成するかどうか(true:作成する) 251 outMessage = true; 252 displayMsg = "MSG0040"; // 件登録しました。 253 selectedAll = false; 254 keepTimeStamp = false; // オリジナルのタイムスタンプを利用する場合、true 255 table = null; 256 errMessage = null; 257 executeCount= -1; // 処理件数 258 errCode = ErrorMessage.OK; 259 dyStart = 0; // 処理時間 260 fromStorageType = null; // 5.10.9.0 (2019/03/01) ADD 261 fromBucketName = null; // 5.10.9.0 (2019/03/01) ADD 262 toStorageType = null; // 5.10.9.0 (2019/03/01) ADD 263 toBucketName = null; // 5.10.9.0 (2019/03/01) ADD 264 } 265 266 /** 267 * 処理を実行します。 268 * 269 * @og.rev 5.10.9.0 (2019/03/01) クラウドストレージ対応を追加。 270 */ 271 private void execute() { 272 int[] rowNo = getParameterRows(); 273 if( rowNo.length > 0 ) { 274 275 // 5.10.9.0 (2019/03/01) MODIFY 276// FromToFiles fromToFiles = new FromToFiles( table , targetDir , createDir ); 277 FromToFiles fromToFiles = new FromToFiles( table, targetDir, createDir, toStorageType, toBucketName); 278 279 if( ACT_COPY.equalsIgnoreCase( action ) ) { 280 actionCOPY( rowNo,fromToFiles ); 281 } 282 // ACT_MODIFY は、エンジンの command で使うため、便利 283 else if( ACT_MOVE.equalsIgnoreCase( action ) || ACT_MODIFY.equalsIgnoreCase( action ) ) { 284 actionMOVE( rowNo,fromToFiles ); 285 } 286 else if( ACT_DELETE.equalsIgnoreCase( action ) ) { 287 actionDELETE( rowNo,fromToFiles ); 288 } 289 } 290 } 291 292 /** 293 * COPY アクションを実行します。 294 * 295 * @og.rev 5.6.5.2 (2013/06/21) From側がファイルの場合のみ処理します。 296 * @og.rev 5.10.9.0 (2019/03/01) クラウドストレージ対応を追加。 297 * 298 * @param rowNo 処理を実施する行番号 299 * @param fromToFiles FromFile,ToFile をまとめた補助クラス 300 * @throws HybsSystemException 処理中に何らかのエラーが発生した場合 301 */ 302 private void actionCOPY( final int[] rowNo , final FromToFiles fromToFiles ) { 303 File fromFile = null ; 304 File toFile = null ; 305 306 executeCount = 0 ; // 開始前に初期化しておく。 307 int rowCount = rowNo.length ; 308 for( int i=0; i<rowCount; i++ ) { 309 // 5.10.9.0 (2019/03/01) MODIFY 310// File[] files = fromToFiles.makeFromToFile( rowNo[i] ); // FromFile,ToFile 311 File[] files = fromToFiles.makeFromToFile( rowNo[i], fromStorageType, fromBucketName, toStorageType, toBucketName); 312 fromFile = files[0]; 313 toFile = files[1]; 314 315 // 5.6.5.2 (2013/06/21) From側がファイルの場合のみ処理します。 316// if( !FileUtil.copy( fromFile,toFile,keepTimeStamp ) ) { 317 if( fromFile.isFile() && !FileUtil.copy( fromFile,toFile,keepTimeStamp )) { 318 String errMsg = "アクション=[" + action + "]中にエラーが発生しました。" + HybsSystem.CR 319 + "From=[" + fromFile + "],To=[" + toFile + "]" + HybsSystem.CR; 320 throw new HybsSystemException( errMsg ); 321 } 322 executeCount++ ; 323 } 324 } 325 326 /** 327 * MOVE アクションを実行します。 328 * 329 * @og.rev 5.5.2.4 (2012/05/16) メソッドの戻り値の設定 330 * @og.rev 5.6.5.2 (2013/06/21) From側がファイルの場合のみ処理します。 331 * @og.rev 5.10.9.0 (2019/03/01) クラウドストレージの対応を追加。 332 * 333 * @param rowNo 処理を実施する行番号 334 * @param fromToFiles FromFile,ToFile をまとめた補助クラス 335 * @throws HybsSystemException 処理中に何らかのエラーが発生した場合 336 */ 337 private void actionMOVE( final int[] rowNo , final FromToFiles fromToFiles ) { 338 File fromFile = null ; 339 File toFile = null ; 340 341 executeCount = 0 ; // 開始前に初期化しておく。 342 int rowCount = rowNo.length ; 343 for( int i=0; i<rowCount; i++ ) { 344 // 5.10.9.0 (2019/03/01) MODIFY 345 // File[] files = fromToFiles.makeFromToFile( rowNo[i] ); // FromFile,ToFile 346 File[] files = fromToFiles.makeFromToFile( rowNo[i], fromStorageType, fromBucketName, toStorageType, toBucketName); 347 fromFile = files[0]; 348 toFile = files[1]; 349 350 if( fromToFiles.lastParentEquals() ) { // FromDirとToDirが同じなので、RENAMEできる。 351 if( !fromFile.renameTo( toFile ) ) { 352 String errMsg = "アクション=[" + action + "]中にエラーが発生しました。" + HybsSystem.CR 353 + "同一親フォルダのため、RENAME処理を行っています。" + HybsSystem.CR 354 + "From=[" + fromFile + "],To=[" + toFile + "]" + HybsSystem.CR; 355 throw new HybsSystemException( errMsg ); 356 } 357 } 358 // 5.6.5.2 (2013/06/21) From側がファイルの場合のみ処理します。 359// else { // FromDirとToDirが異なるので、COPY + DELETE する。 360 else if( fromFile.isFile() ) { // FromDirとToDirが異なるので、COPY + DELETE する。 361 if( !FileUtil.copy( fromFile,toFile,keepTimeStamp ) ) { 362 String errMsg = "アクション=[" + action + "]中にエラーが発生しました。" + HybsSystem.CR 363 + "移動前のCOPY処理を行っていました。" + HybsSystem.CR 364 + "From=[" + fromFile + "],To=[" + toFile + "]" + HybsSystem.CR; 365 throw new HybsSystemException( errMsg ); 366 } 367 368 if( !fromFile.delete() ) { 369// toFile.delete(); // 移動の際の COPY は正常なので、まずは、そのファイルを削除しておく。 370 String errMsg = "アクション=[" + action + "]中にエラーが発生しました。" + HybsSystem.CR 371 + "移動後のオリジナルファイルの削除処理を行っていました。" + HybsSystem.CR 372 + "From=[" + fromFile + "],To=[" + toFile + "]" + HybsSystem.CR; 373 // 5.5.2.4 (2012/05/16) メソッドの戻り値の設定 374 if(! toFile.delete() ) { 375 errMsg = errMsg + "toFile も削除に失敗しました。" + HybsSystem.CR; 376 } 377 378 throw new HybsSystemException( errMsg ); 379 } 380 } 381 executeCount++ ; 382 } 383 } 384 385 /** 386 * DELETE アクションを実行します。 387 * 388 * この処理では、リストにフォルダが含まれている場合も削除します。 389 * 通常、フォルダの削除は、その要素(内部)にファイル等が存在しない場合のみ 390 * 行いますが、検索リストから削除する順番によっては、フォルダもファイルも 391 * 削除対象になる場合があります。そこで、まず。ファイルだけ削除し、フォルダは、 392 * あとで削除するように処理を行います。 393 * 394 * @og.rev 5.6.5.2 (2013/06/21) フォルダも削除対象にします。 395 * @og.rev 5.10.9.0 (2019/03/01) クラウドストレージの対応を追加。 396 * 397 * @param rowNo 処理を実施する行番号 398 * @param fromToFiles FromFile,ToFile をまとめた補助クラス 399 * @throws HybsSystemException 処理中に何らかのエラーが発生した場合 400 */ 401 private void actionDELETE( final int[] rowNo , final FromToFiles fromToFiles ) { 402 File fromFile = null; 403 404 // 5.6.5.2 (2013/06/21) フォルダを削除する為の、退避 405 Set<File> dirSet = new TreeSet<File>( new FileNameLengthComparator() ); // ファイルの文字数順に並べたSet 406 407 executeCount = 0 ; // 開始前に初期化しておく。 408 int rowCount = rowNo.length ; 409 for( int i=0; i<rowCount; i++ ) { 410 // 5.10.9.0 (2019/03/01) MODIFY 411// fromFile = fromToFiles.makeFromOnly( rowNo[i] ); // FromFile 412 fromFile = fromToFiles.makeFromOnly(rowNo[i], fromStorageType, fromBucketName); 413 414 // 5.6.5.2 (2013/06/21) まず、ファイルを削除します。 415// if( !fromFile.delete() ) 416 if( fromFile.isFile() ) { 417 if( !fromFile.delete() ) { 418 String errMsg = "アクション=[" + action + "]中にエラーが発生しました。" + HybsSystem.CR 419 + "From=[" + fromFile + "]" + HybsSystem.CR; 420 throw new HybsSystemException( errMsg ); 421 } 422 } 423 else { 424 // 5.6.5.2 (2013/06/21) フォルダの場合は、アドレスの桁数をキーにソートしておきます。 425 int len = fromFile.getAbsolutePath().length(); 426 dirSet.add( fromFile ); 427 } 428 executeCount++ ; 429 } 430 431 // 5.6.5.2 (2013/06/21) フォルダの削除は、アドレスの桁数の大きい順(階層の深い順)に削除します。 432 for( File file : dirSet ) { 433 if( !file.delete() ) { 434 String errMsg = "アクション=[" + action + "]中にエラーが発生しました。" + HybsSystem.CR 435 + "From(Dir)=[" + file + "]" + HybsSystem.CR; 436 throw new HybsSystemException( errMsg ); 437 } 438 } 439 } 440 441 /** 442 * ファイルの名称の長さ順(長い順)に比較する、Comparator インターフェースの実装クラス 443 * 444 * ここでの大小比較は、ファイル名の文字数が、大きい方が、小さいとみなされます。 445 * つまり階層が深いので、先に処理する必要があるという事を意味します。 446 * 処理としては、f1 != null && f2 != null で、len1 = f1.getAbsolutePath().length() と len2 = f2.getAbsolutePath().length() を比較し 447 * len1 > len2 ⇒ 負 , len1 < len2 ⇒ 正 , len1 == len2 ⇒ 0 を返します。 448 * 具体的には、return ( len2 - len1 ); です。 449 * 450 * 注: このコンパレータは equals と一貫性のない順序付けを課します。 451 * 452 * @og.rev 5.6.5.2 (2013/06/21) 新規追加 453 * 454 */ 455 private static final class FileNameLengthComparator implements Comparator<File> , Serializable { 456 private static final long serialVersionUID = 5652 ; // 5.6.5.2 (2013/06/21) 457 /** 458 * 順序付けのために 2 つの引数を比較します。 459 * 460 * ここでの大小比較は、ファイル名の文字数が、大きい方が、小さいとみなされます。 461 * 具体的には、return ( len2 - len1 ); です。 462 * 463 * @param 比較対象の最初のオブジェクト 464 * @param 比較対象の 2 番目のオブジェクト 465 * @return 最初の引数が 2 番目の引数より小さい場合は負の整数、両方が等しい場合は 0、最初の引数が 2 番目の引数より大きい場合は正の整数 466 */ 467 public int compare( final File f1 , final File f2 ) { 468 if( f1 == null || f2 == null ) { 469 String errMsg = "引数のFileにnullが含まれています。file1=[" + f1 + "] , file2=[" + f2 + "]" ; 470 throw new IllegalArgumentException( errMsg ); 471 } 472 473 int len1 = f1.getAbsolutePath().length(); 474 int len2 = f2.getAbsolutePath().length(); 475 476 return ( len2 - len1 ); 477 } 478 } 479 480 /** 481 * 表示データの HybsSystem.ROW_SEL_KEY を元に、選ばれた 行を処理の対象とします。 482 * 483 * @return 選択行の配列 484 */ 485 @Override 486 protected int[] getParameterRows() { 487 final int[] rowNo ; 488 if( selectedAll ) { 489 int rowCnt = table.getRowCount(); 490 rowNo = new int[ rowCnt ]; 491 for( int i=0; i<rowCnt; i++ ) { 492 rowNo[i] = i; 493 } 494 } else { 495 rowNo = super.getParameterRows(); 496 } 497 return rowNo ; 498 } 499 500 /** 501 * 【TAG】アクション[COPY|MOVE|MODIFY|DELETE]をセットします(必須)。 502 * 503 * @og.tag 504 * アクションは、ファイルをコピー(COPY)したり、移動(MOVE,MODIFY)したり、削除(DELETE)する 505 * などの操作を指定する必須属性です。 506 * 507 * <table border="1" frame="box" rules="all" > 508 * <caption>action属性(必須)のキーワード</caption> 509 * <tr><th>action</th><th>名称</th><th>機能</th></tr> 510 * <tr><td>COPY </td><td>コピー</td><td>オリジナルファイルを、ターゲット(TO_PARENT,TO_NAMEで指定)にコピーします。</td></tr> 511 * <tr><td>MOVE </td><td>移動 </td><td>オリジナルファイルを、ターゲットに移動(COPY+DELETE)/名称変更(RENAME)します。</td></tr> 512 * <tr><td>MODIFY</td><td>移動 </td><td>(MOVE と同じ。エンジンの command を利用するための簡易action)</td></tr> 513 * <tr><td>DELETE</td><td>削除 </td><td>オリジナルファイルを、削除します。(フォルダ、ファイルに関わらず)</td></tr> 514 * </table> 515 * 516 * @param act アクション(public static final 宣言されている文字列) 517 * @see <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.FileUpdateTag.ACT_COPY">アクション定数</a> 518 */ 519 public void setAction( final String act ) { 520 action = nval( getRequestParameter( act ),action ); 521 522 if( action != null && !check( action, ACTION_LIST ) ) { 523 String errMsg = "指定のアクションは実行できません。アクションエラー" + HybsSystem.CR 524 + "action=[" + action + "] " + HybsSystem.CR 525 + StringUtil.array2csv( ACTION_LIST ) ; 526 throw new HybsSystemException( errMsg ); 527 } 528 } 529 530 /** 531 * 【TAG】ターゲットとなるフォルダを指定します。 532 * 533 * @og.tag 534 * targetDir 属性を利用する場合は、引数のファイル、またはフォルダが指定されたことに 535 * なります。COPY、MOVE(,MODIFY) の場合は、targetDir 属性にフォルダを指定することで一括処理可能です。 536 * 指定先のフォルダが存在しない場合は、createDir属性の値により処理が異なります。 537 * createDir="true"(初期値)で、ターゲットフォルダが存在しない場合は、自動作成します。 538 * 539 * @param dir ターゲットとなるフォルダ 540 * @see #setCreateDir( String ) 541 */ 542 public void setTargetDir( final String dir ) { 543 targetDir = nval( getRequestParameter( dir ),targetDir ); 544 } 545 546 /** 547 * 【TAG】ターゲットとなるフォルダがなければ、作成するかどうかを指定します(初期値:true)。 548 * 549 * @og.tag 550 * COPY,MOVE(,MODIFY) などの処理で、ターゲットフォルダが存在しないときに、作成するか、エラーにするかを 551 * createDir属性 で指定できます。 552 * これは、COPY先やMOVE(,MODIFY)先が存在している前提のシステムで、不要な箇所に間違ってフォルダを 553 * 自動作成されると困る場合に、false:作成しない とすれば、間違いに気づく確率が上がります。 554 * 初期値は true:作成する です。 555 * 556 * @param flag ターゲットとなるフォルダを自動作成する(true)か、しない(false) 初期値は、true:作成する 557 */ 558 public void setCreateDir( final String flag ) { 559 createDir = nval( getRequestParameter( flag ),createDir ); 560 } 561 562 /** 563 * 【TAG】(通常は使いません)結果のDBTableModelを、sessionに登録するときのキーを指定します 564 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY}])。 565 * 566 * @og.tag 567 * 検索結果より、DBTableModelオブジェクトを作成します。これを、下流のviewタグ等に 568 * 渡す場合に、通常は、session を利用します。その場合の登録キーです。 569 * query タグを同時に実行して、結果を求める場合、同一メモリに配置される為、 570 * この tableId 属性を利用して、メモリ空間を分けます。 571 * (初期値:HybsSystem#TBL_MDL_KEY[={@og.value org.opengion.hayabusa.common.HybsSystem#TBL_MDL_KEY}])。 572 * 573 * @param id sessionに登録する時の ID 574 */ 575 public void setTableId( final String id ) { 576 tableId = nval( getRequestParameter( id ),tableId ); 577 } 578 579 /** 580 * 【TAG】コマンド(ENTRY)をセットします。 581 * 582 * @og.tag 583 * このタグは、command="ENTRY" でのみ実行されます。 584 * コマンドは,HTMLから(get/post)指定されますので,CMD_xxx で設定される 585 * フィールド定数値のいづれかを、指定できます。 586 * 初期値は、ENTRY なので、何も指定しなければ、実行されます。 587 * 588 * @param cmd コマンド(public static final 宣言されている文字列) 589 * @see <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.FileUpdateTag.CMD_ENTRY">コマンド定数</a> 590 */ 591 public void setCommand( final String cmd ) { 592 String cmd2 = getRequestParameter( cmd ); 593 if( cmd2 != null && cmd2.length() >= 0 ) { command = cmd2.toUpperCase(Locale.JAPAN); } 594 } 595 596 /** 597 * 【TAG】検索結果のメッセージを表示する/しない[true/false]を指定します(初期値:true)。 598 * 599 * @og.tag 600 * 初期値は、表示する:true です。 601 * 602 * @param flag [true:表示する/それ以外:含めない] 603 */ 604 public void setOutMessage( final String flag ) { 605 outMessage = nval( getRequestParameter( flag ),outMessage ); 606 } 607 608 /** 609 * 【TAG】処理結果を画面上に表示するメッセージリソースIDを指定します(初期値:MSG0040[ 件登録しました])。 610 * 611 * @og.tag 612 * ここでは、検索結果の件数や登録された件数をまず出力し、 613 * その次に、ここで指定したメッセージをリソースから取得して表示します。 614 * 表示させたくない場合は, displayMsg = "" をセットしてください。 615 * displayMsg の初期値は、MSG0040[ 件登録しました]です。 616 * 617 * @param id ディスプレイに表示させるメッセージ ID 618 */ 619 public void setDisplayMsg( final String id ) { 620 String ids = getRequestParameter( id ); 621 if( ids != null ) { displayMsg = ids; } 622 } 623 624 /** 625 * 【TAG】データを全件選択済みとして処理するかどうか[true/false]を指定します(初期値:false)。 626 * 627 * @og.tag 628 * 全てのデータを選択済みデータとして扱って処理します。 629 * 全件処理する場合に、(true/false)を指定します。 630 * 初期値は false です。 631 * 632 * @param all データを全件選択済み [true:全件選択済み/false:通常] 633 */ 634 public void setSelectedAll( final String all ) { 635 selectedAll = nval( getRequestParameter( all ),selectedAll ); 636 } 637 638 /** 639 * 【TAG】オリジナルのタイムスタンプを利用するかどうかを指定します(初期値:false)。 640 * 641 * @og.tag 642 * COPYや親違いMOVE(,MODIFY)の時に、オリジナルのタイムスタンプをそのままコピー先のファイルにも 643 * 適用するかどうかを指定します。 644 * タイムスタンプを初期化されたくない場合に、true に設定します。 645 * 初期値は 利用しない:false です。 646 * 647 * @param flag タイムスタンプを利用するかどう(初期値:利用しない)。 648 */ 649 public void setKeepTimeStamp( final String flag ) { 650 keepTimeStamp = nval( getRequestParameter( flag ),keepTimeStamp ); 651 } 652 653 /** 654 * 【TAG】読み取り元ストレージタイプを設定します。 655 * 656 * @og.tag 657 * ファイルを読み取り元の、ストレージタイプを設定します。 658 * 未設定の場合は、システムリソースの「CLOUD_TARGET」が参照されます。 659 * 自身のサーバを指定する場合は、「default」を設定してください。 660 * 661 * @og.rev 5.10.9.0 (2019/03/01) 新規追加 662 * 663 * @param fromStorage 読み取り元ストレージタイプ 664 */ 665 public void setFromStorageType( final String fromStorage ) { 666 fromStorageType = nval( getRequestParameter( fromStorage ), fromStorageType ); 667 } 668 669 /** 670 * 【TAG】読み取り元バケット名を設定します。 671 * 672 * @og.tag 673 * ファイルを読み取り元の、バケット名を指定します。 674 * クラウドストレージ利用時のみ有効です。 675 * 未設定の場合は、システムリソースの「CLOUD_BUKET」が参照されます。 676 * 677 * @og.rev 5.10.9.0 (2019/03/01) 新規追加 678 * 679 * @param fromBucket 読み取り元バケット名 680 */ 681 public void setFromBucketName( final String fromBucket ) { 682 fromBucketName = nval( getRequestParameter( fromBucket ), fromBucketName ); 683 } 684 685 /** 686 * 【TAG】保存先ストレージタイプを設定します。 687 * 688 * @og.tag 689 * ファイルを保存先の、ストレージタイプを設定します。 690 * 未設定の場合は、システムリソースの「CLOUD_TARGET」が参照されます。 691 * 自身のサーバを指定する場合は、「default」を設定してください。 692 * 693 * @og.rev 5.10.9.0 (2019/03/01) 新規追加 694 * 695 * @param toStorage 保存先ストレージタイプ 696 */ 697 public void setToStorageType( final String toStorage ) { 698 toStorageType = nval( getRequestParameter( toStorage ), toStorageType ); 699 } 700 701 /** 702 * 【TAG】保存先バケット名を設定します。 703 * 704 * @og.tag 705 * ファイルを読み取り元の、バケット名を指定します。 706 * クラウドストレージ利用時のみ有効です。 707 * 未設定の場合は、システムリソースの「CLOUD_BUKET」が参照されます。 708 * 709 * @og.rev 5.10.9.0 (2019/03/01) 新規追加 710 * 711 * @param toBucket 保存先バケット名 712 */ 713 public void setToBucketName( final String toBucket ) { 714 toBucketName = nval( getRequestParameter( toBucket ), toBucketName ); 715 } 716 717 /** 718 * DBTableModel から、FromFile,ToFile を作成するための処理をまとめた補助クラスです。 719 * 720 * ここでは、オリジナルファイルやターゲットファイルを作成するための処理のみを集めています。 721 * メソッドにすると、ローカル変数を多く管理するか、多数の引数渡しを繰り返すことになるため、 722 * このローカルクラスに処理と、値を格納します。 723 * 724 */ 725 private static final class FromToFiles { 726// private static final String[] CLMS_LIST = new String[] { "PARENT","NAME","TO_PARENT","TO_NAME" }; 727 728 private final DBTableModel table ; 729 730 private final int PARENT ; 731 private final int NAME ; 732 private final int TO_PARENT ; 733 private final int TO_NAME ; 734 735 private final File toDir ; 736 private final boolean createDir; // ターゲットとなるフォルダがなければ、作成するかどうか(true:作成する) 737 738 private boolean equalParent = false; // 最後に実行された処理で、親フォルダが同一の場合は、true 739 740 /** 741 * 引数指定のコンストラクター 742 * 743 * 必要なパラメータを渡して、オブジェクトを構築します。 744 * 745 * @param table DBTableModel 一覧が格納されているDBTableModel 746 * @param targetDir ターゲットとなるフォルダ 747 * @param createDir ターゲットとなるフォルダがなければ、作成するかどうか(true:作成する) 748 * @param targetStorageType ターゲットのストレージタイプ 749 * @param targetBucketName ターゲットのバケット名 750 */ 751 752 // public FromToFiles( final DBTableModel table , final String targetDir , final boolean createDir ) { 753 public FromToFiles( final DBTableModel table , final String targetDir , final boolean createDir, 754 final String targetStorageType, final String targetBucketName) { 755 this.table = table; 756 this.createDir = createDir ; 757 758 // 5.10.9.0 (2019/03/01) MODIFY 759 // toDir = mkDirs( targetDir,createDir ); // targetDir が指定されていない場合は、null 760 toDir = mkDirs( targetDir,createDir,targetStorageType,targetBucketName ); 761 762 // "PARENT","NAME","TO_PARENT","TO_NAME" のカラム名のDBTableModelのカラム番号。存在しない場合は、-1 763 PARENT = table.getColumnNo( "PARENT" , false ); 764 NAME = table.getColumnNo( "NAME" , false ); 765 TO_PARENT = table.getColumnNo( "TO_PARENT", false ); 766 TO_NAME = table.getColumnNo( "TO_NAME" , false ); 767 } 768 769 /** 770 * 行番号より、対応するオリジナルファイル(FromFile)を返します。 771 * 772 * ここでは、TO_PARENT や TO_NAME は、判定する必要がないため、makeFromToFile( int ) の 773 * 一部のみで処理が終了できます。 774 * 1.FromDir は、PARENT 列の値から作成する。 775 * 2.FromFileは、FromDir + NAME列の値から作成する。 776 * 777 * 配列返しの関係で、メソッド(および内部処理)を分けています。 778 * 779 * @og.rev 5.10.9.0 (2019/03/01) クラウドストレージ対応を追加。 780 * 781 * @param rowNo カラムNo 782 * @param fromStorageType オリジナルファイルのストレージタイプ 783 * @param fromBucketName オリジナルファイルのバケット名 784 * @return File オリジナルファイル(FromFile) 785 * @see #makeFromToFile( int ) 786 */ 787 // 5.10.9.0 (2019/03/01) MODIFY 788 // public File makeFromOnly( final int rowNo ) { 789 public File makeFromOnly( final int rowNo, final String fromStorageType, final String fromBucketName ) { 790 String[] value = table.getValues( rowNo ); 791 792 // 5.10.9.0 (2019/03/01) MODIFY 793// File fromDir = mkDirs( value[PARENT],createDir); 794 File fromDir = mkDirs( value[PARENT],createDir,fromStorageType,fromBucketName ); 795 796 // 5.10.9.0 (2019/03/01) MODIFY 797// return new File( fromDir, value[NAME] ) ; 798 return HybsFileOperationFactory.create( fromStorageType, fromBucketName, fromDir, value[NAME] ); 799 } 800 801 /** 802 * 行番号より、対応するオリジナルファイル(FromFile)とターゲットファイル(ToFile)を配列に格納して返します。 803 * 804 * ここでは、TO_PARENT や TO_NAME は、存在するかどうか不明なので、以下の手順で作成します。 805 * 1.FromDir は、PARENT 列の値から作成する。 806 * 2.FromFileは、FromDir + NAME列の値から作成する。 807 * 3.toDir は、 808 * A.targetDir が有れば、それを使う。 809 * B.なければ、TO_PARENT 列の値から作成する。 810 * C.TO_PARENT 列がないか、値が未設定の場合は、FromDir をそのまま使う。 811 * 4.toFile は、 812 * A.toDir + TO_NAME 列の値から作成する。 813 * B.TO_NAME 列がないか、値が未設定の場合は、toDir + NAME列の値から作成する。 814 * 返り値は、new File[] { formFile , toFile }; とする。 815 * 816 * @og.rev 5.10.9.0 (2019/03/01) クラウドストレージ対応を追加。 817 * 818 * @param rowNo カラムNo 819 * @param fromStorageType オリジナルファイルのストレージタイプ 820 * @param fromBucketName オリジナルファイルのバケット名 821 * @param toStorageType ターゲットファイルのストレージタイプ 822 * @param toBucketName ターゲットファイルのバケット名 823 * 824 * @return File[] ファイル配列(0:オリジナルファイル 1:ターゲットファイル) 825 */ 826 // 5.10.9.0 (2019/03/01) MODIFY 827 // public File[] makeFromToFile( final int rowNo ) { 828 public File[] makeFromToFile( final int rowNo, final String fromStorageType, final String fromBucketName, 829 final String toStorageType, final String toBucketName) { 830 831 String[] value = table.getValues( rowNo ); 832 // 5.10.9.0 (2019/03/01) MODIFY 833 // File fromDir = mkDirs( value[PARENT],createDir ); 834 File fromDir = mkDirs( value[PARENT],createDir,fromStorageType,fromBucketName ); 835 // 5.10.9.0 (2019/03/01) MODIFY 836// File formFile = new File( fromDir, value[NAME] ) 837 File fromFile = HybsFileOperationFactory.create(fromStorageType, fromBucketName, fromDir, value[NAME]); 838 File tempToDir = toDir; 839 840 equalParent = false; // 最後に実行された処理で、親フォルダが同一かどうかのフラグをリセットする。 841 if( tempToDir == null ) { 842 if( TO_PARENT >= 0 && nval(value[TO_PARENT],null) != null ) { 843 // 5.10.9.0 (2019/03/01) MODIFY 844// tempToDir = mkDirs( value[TO_PARENT],createDir ); 845 tempToDir = mkDirs( value[TO_PARENT],createDir,toStorageType,toBucketName ); 846 } 847 else { 848 tempToDir = fromDir; 849 equalParent = true; // 最後に実行された処理で、親フォルダが同一の場合は、true 850 } 851 } 852 File toFile = null; 853 if( TO_NAME >= 0 && nval(value[TO_NAME],null) != null ) { 854 // 5.10.9.0 (2019/03/01) MODIFY 855// toFile = new File( tempToDir, value[TO_NAME] ); 856 toFile = HybsFileOperationFactory.create(toStorageType, toBucketName, tempToDir, value[TO_NAME] ); 857 } 858 else { 859 // 5.10.9.0 (2019/03/01) MODIFY 860// toFile = new File( tempToDir, value[NAME] ); 861 toFile = HybsFileOperationFactory.create(toStorageType, toBucketName, tempToDir, value[NAME]); 862 863 } 864 865 return new File[] { fromFile , toFile }; 866 } 867 868 /** 869 * 最後に実行された処理で、親フォルダが同一かどうかを返します(同一の場合は、true)。 870 * 871 * makeFromToFile( int ) が処理されたときの、FromDir と toDir が同一であれば、true を、 872 * 異なる場合は、false を返します。 873 * ここでの結果は、厳密な同一判定ではなく、処理的に、同一かどうかを判定しています。 874 * つまり、toDir に FromDir をセットする(3.Cのケース)場合に、true を内部変数にセットします。 875 * この判定値は、ファイルの移動処理で、異なる親フォルダの場合は、COPY & DELETE しなければ 876 * なりませんが、同一親フォルダの場合は、RENAME で済む という処理負荷の軽減が目的です。 877 * よって、結果的に、PARENT と TO_PARENT が同じとか、PARENT と targetDir が同じでも 878 * ここでのフラグは、false が返されます。 879 * 880 * @return 最後に実行された処理で、親フォルダが同一の場合は、true 881 * @see #makeFromToFile( int ) 882 */ 883 public boolean lastParentEquals() { 884 return equalParent ; 885 } 886 887 /** 888 * カラム名配列(String[])より、対応するカラムNo配列(int[])を作成します。 889 * 890 * ここでは、TO_PARENT や TO_NAME は、存在するかどうか不明なので、 891 * EXCEPTION にせず、配列番号に、-1 を返すようにしています。 892 * 893 * @param table DBTableModel 一覧が格納されているDBTableModel 894 * @param nameArray カラム名配列 895 * @return カラムNo配列(カラム名が存在しない場合は、-1) 896 */ 897 // private int[] getTableColumnNo( final DBTableModel table ,final String[] nameArray ) { 898 // int[] clmNo = new int[ nameArray.length ]; 899 // for( int i=0; i<clmNo.length; i++ ) { 900 // clmNo[i] = table.getColumnNo( nameArray[i] , false ); // カラム名が存在しない場合は、-1 を返す。 901 // } 902 // return clmNo; 903 // } 904 905 906 /** 907 * フォルダを作成します。 908 * 909 * フォルダが存在しない場合は、途中階層をすべて作成します。 910 * 911 * @og.rev 5.10.9.0 (2019/03/01) クラウドストレージ対応を追加。 912 * 913 * @param fname フォルダ名 914 * @param createDir ターゲットとなるフォルダがなければ、作成するかどうか(true:作成する) 915 * @param storageType ターゲットとなるストレージタイプ 916 * @param bucketName ターゲットとなるバケット名 917 * 918 * @return File フォルダを表すファイルオブジェクト。引数が null の場合は、null を返します。 919 * @throws HybsSystemException ファイルか、存在しない場合に、createDir=false か、mkdirs() が false の場合 920 */ 921 private File mkDirs( final String fname , final boolean createDir, final String storageType, final String bucketName ) { 922 File target = null; 923 if( fname != null ) { 924 // 5.10.9.0 (2019/03/01) MODIFY FileをFileOperateInterfaceに置き換え 925// target = new File( fname ); 926 target = HybsFileOperationFactory.create(storageType, bucketName, fname); 927 if( target.exists() ) { // 存在する 928 if( target.isFile() ) { 929 String errMsg = "ターゲットに、ファイル名は指定できません。" + HybsSystem.CR 930 + "ターゲット=[" + fname + "]" + HybsSystem.CR; 931 throw new HybsSystemException( errMsg ); 932 } 933 } 934 else { // 存在しない 935 // 存在しないのに、作成しない 936 if( !createDir ) { 937 String errMsg = "ターゲットが存在しません。 " + HybsSystem.CR 938 + "ターゲット=[" + fname + "]" + HybsSystem.CR; 939 throw new HybsSystemException( errMsg ); 940 } 941 // 作成できない 942 if( !target.mkdirs() ) { 943 String errMsg = "ターゲットを自動作成使用としましたが、作成できませんでした。" + HybsSystem.CR 944 + "ターゲット=[" + fname + "]" + HybsSystem.CR; 945 throw new HybsSystemException( errMsg ); 946 } 947 } 948 } 949 return target; 950 } 951 } 952 953 /** 954 * シリアライズ用のカスタムシリアライズ書き込みメソッド 955 * 956 * @og.rev 4.0.0.0 (2006/09/31) 新規追加 957 * @serialData 一部のオブジェクトは、シリアライズされません。 958 * 959 * @param strm ObjectOutputStreamオブジェクト 960 * @throws IOException シリアライズに関する入出力エラーが発生した場合 961 */ 962 private void writeObject( final ObjectOutputStream strm ) throws IOException { 963 strm.defaultWriteObject(); 964 } 965 966 /** 967 * シリアライズ用のカスタムシリアライズ読み込みメソッド 968 * 969 * ここでは、transient 宣言された内部変数の内、初期化が必要なフィールドのみ設定します。 970 * 971 * @og.rev 4.0.0.0 (2006/09/31) 新規追加 972 * @serialData 一部のオブジェクトは、シリアライズされません。 973 * 974 * @param strm ObjectInputStreamオブジェクト 975 * @see #release2() 976 * @throws IOException シリアライズに関する入出力エラーが発生した場合 977 * @throws ClassNotFoundException クラスを見つけることができなかった場合 978 */ 979 private void readObject( final ObjectInputStream strm ) throws IOException , ClassNotFoundException { 980 strm.defaultReadObject(); 981 } 982 983 984 /** 985 * このオブジェクトの文字列表現を返します。 986 * 基本的にデバッグ目的に使用します。 987 * 988 * @og.rev 5.10.9.0 (2019/03/01) fromStorageType,fromBucketName,toStorageType,toBucketNameを追加。 989 * 990 * @return このクラスの文字列表現 991 */ 992 @Override 993 public String toString() { 994 return org.opengion.fukurou.util.ToString.title( this.getClass().getName() ) 995 .println( "VERSION" ,VERSION ) 996 .println( "action" ,action ) 997 .println( "command" ,command ) 998 .println( "targetDir" ,targetDir ) 999 .println( "createDir" ,createDir ) 1000 .println( "tableId" ,tableId ) 1001 .println( "outMessage" ,outMessage ) 1002 .println( "displayMsg" ,displayMsg ) 1003 .println( "selectedAll" ,selectedAll ) 1004 .println( "keepTimeStamp" ,keepTimeStamp ) 1005 .println( "fromStorageType" ,fromStorageType ) 1006 .println( "fromBucketName" ,fromBucketName ) 1007 .println( "toStorageType" ,toStorageType ) 1008 .println( "toBucketName" ,toBucketName ) 1009 .fixForm().toString() ; 1010 } 1011}