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.fukurou.system.OgRuntimeException ; // 6.4.2.0 (2016/01/29) 019import org.opengion.hayabusa.common.HybsSystem; 020import org.opengion.hayabusa.common.HybsSystemException; 021import org.opengion.fukurou.util.FileUtil; 022import org.opengion.fukurou.util.StringUtil ; 023import org.opengion.fukurou.util.ToString; // 6.1.1.0 (2015/01/17) 024import org.opengion.fukurou.util.ZipArchive; // 5.9.2.2 (2015/11/12) 025import org.opengion.fukurou.util.ArraySet; // 6.4.3.4 (2016/03/11) 026import org.opengion.fukurou.model.POIUtil; // 6.2.3.0 (2015/05/01) 027 028import org.opengion.hayabusa.io.HybsFileOperationFactory; // 8.0.0.1 (2021/10/08) 029import org.opengion.fukurou.model.FileOperation; // 8.0.0.1 (2021/10/08) 030 031import static org.opengion.fukurou.util.StringUtil.nval ; 032 033import java.io.File; 034import java.io.IOException; 035import java.util.List; // 6.2.3.0 (2015/05/01) 036import java.util.Set; // 6.4.3.4 (2016/03/11) 037import java.util.ArrayList; // 6.2.3.0 (2015/05/01) 038import java.util.Locale ; 039 040import jakarta.servlet.ServletContext; // 6.3.6.1 (2015/08/28) 041 042/** 043 * 各種アクションを指定して、ファイル関連の操作をおこなうタグです。 044 * 045 * 各種アクション に応じた振る舞いを行います。 046 * 結果については、false の場合は、body 要素を表示して、終了します。 047 * これは、BODYにエラーメッセージを書いておくことを想定した作りになっています。 048 049 * 判定結果を反転したい場合は、notEquals 属性を使用してください。また、 050 * 結果に応じて、処理を止めたくない場合は、useStop 属性を false に指定することで、 051 * 後続処理を実行できます。 052 * 053 * [各種アクション] 054 * canRead 読み込めるかどうかを判定。 055 * canWrite 変更できるかどうか判定。 056 * createNewFile 空の新しいファイルを不可分 (atomic) に生成。(そのファイルがまだ存在しない場合だけ) 057 * delete ファイルまたはディレクトリを削除(ディレクトリ階層をすべて削除)。 058 * renameTo ファイルまたはディレクトリ名を変更。 059 * exists ファイルが存在するかどうか判定。 060 * isDirectory ファイルがディレクトリであるかどうか判定。 061 * isFile ファイルが普通のファイルかどうか判定。 062 * isHidden ファイルが隠しファイルかどうか判定。 063 * mkdir ディレクトリを生成。 064 * mkdirs ディレクトリを複数生成。 065 * read ファイルを読み込んで、パラメータにセットします(6.2.3.0 (2015/05/01))。 066 * existsLength ファイルサイズが0Byte以上のファイルが存在するかどうか判定。 067 * copy ファイルまたはディレクトリをコピー(file1 ⇒ file2 にコピー)。 068 * copyST ストリームファイルをコピー(file1(アドレス) ⇒ file2 にコピー)。 069 * list ファイルリストをListオブジェクトにコピーして、パラメータにセットします(6.2.3.0 (2015/05/01))。 070 * zip ファイルまたはディレクトリをZIPファイルに圧縮します。(file1⇒file2) 071 * timeStamp ファイルのタイムスタンプを現在時刻に変更します。(file1のみ) 072 * 073 * @og.formSample 074 * ●形式:<og:file action="…" fileURL="…" >・・・</og:file> 075 * ●body:あり(EVAL_BODY_INCLUDE:BODYをインクルードし、{@XXXX} は解析しません) 076 * 077 * ●Tag定義: 078 * <og:file 079 * action ○【TAG】アクション(canRead,canWrite,createNewFile,delete,renameTo,exists,isDirectory,isFile,isHidden,mkdir,mkdirs,read,existsLength,copy,copyST,list,zip,timeStamp)を指定します(必須)。 080 * fileURL 【TAG】操作するファイルのディレクトリを指定します (初期値:FILE_URL[=filetemp/]) 081 * file1 【TAG】基準となるファイル名を指定します(コマンドの左辺のファイル名です) 082 * file2 【TAG】処理結果となるファイル名を指定します(コマンドの右辺のファイル名です) 083 * notEquals 【TAG】判定結果を反転させるかどうか[true/false]を指定します(初期値:false) 084 * useStop 【TAG】エラー時BODYを処理後に停止するかどうか[true/false]を指定します(初期値:true) 085 * encode 【TAG】ファイルを読み込む(action="read")際のエンコードを指定します(初期値:OS依存文字コード) 086 * × fromStorage 【廃止】テンプレートファイルの読み込み元ストレージタイプを指定します。8.0.0.1 (2021/10/08) 087 * × fromBucket 【廃止】テンプレートファイルの読み込み元バケット名を指定します。8.0.0.1 (2021/10/08) 088 * fromLocal 【TAG】強制的にローカルファイルを使用する場合、true にセットします。。8.0.1.0 (2021/10/29) 089 * toStorage 【廃止】生成したファイルの出力先ストレージタイプを指定します。8.0.0.1 (2021/10/08) 090 * × toBucket 【廃止】生成したファイルの出力先バケット名を指定します。8.0.0.1 (2021/10/08) 091 * × toLocal 【TAG】強制的にローカルファイルを使用する場合、true にセットします。。8.0.0.1 (2021/10/08) 092 * useLocal 【TAG】システム定数でクラウド設定されていても、クラウド環境を使用しない場合、trueを指定します(初期値:false) 8.0.1.0 (2021/10/29) 093 * caseKey 【TAG】このタグ自体を利用するかどうかの条件キーを指定します(初期値:null) 5.7.7.2 (2014/06/20) 094 * caseVal 【TAG】このタグ自体を利用するかどうかの条件値を指定します(初期値:null) 5.7.7.2 (2014/06/20) 095 * caseNN 【TAG】指定の値が、null/ゼロ文字列 でない場合(Not Null=NN)は、このタグは使用されます(初期値:判定しない) 5.7.7.2 (2014/06/20) 096 * caseNull 【TAG】指定の値が、null/ゼロ文字列 の場合は、このタグは使用されます(初期値:判定しない) 5.7.7.2 (2014/06/20) 097 * caseIf 【TAG】指定の値が、true/TRUE文字列の場合は、このタグは使用されます(初期値:判定しない) 098 * debug 【TAG】デバッグ情報を出力するかどうか[true/false]を指定します(初期値:false) 099 * > ... Body ... 100 * </og:file> 101 * 102 * ●使用例 103 * ・ファイルの存在チェック→存在しなければエラーメッセージを表示。 104 * <og:file action="exists" fileURL="N:/CIR/" file1="{@USER.LKISB}/{@USER.LDNO1KAI}.cir/001.sht"> 105 * <og:message lbl="RKE_0157" comment="回路図が存在しません。" /> 106 * </og:file> 107 * 108 * ・N:/Filetemp/にユーザーディレクトリが存在しなければ作成。→失敗した場合エラーメッセージを表示。 109 * <og:file action="mkdir" fileURL="N:/Filetemp/{@USER.ID}" > 110 * <og:message comment="エラーが発生しました。システム管理者に連絡してください。" /> 111 * </og:file> 112 * 113 * ・N:/Filetemp/test.txt ファイルの削除。ファイルが存在しなくても処理を続ける。 114 * <og:file action="delete" fileURL="N:/Filetemp/" file1="test.txt" useStop="false" > 115 * <og:message comment="ファイルは存在しませんでした。" /> 116 * </og:file> 117 * 118 * @og.group その他部品 119 * 120 * @version 4.0 121 * @author Kazuhiko Hasegawa 122 * @since JDK5.0, 123 */ 124public class FileTag extends CommonTagSupport { 125 /** このプログラムのVERSION文字列を設定します。 {@value} */ 126 private static final String VERSION = "8.0.1.0 (2021/10/29)" ; 127 private static final long serialVersionUID = 801020211029L ; 128 129 /** action 引数に渡す事の出来る アクションコマンド 読み込めるかどうか {@value} */ 130 public static final String ACT_CANREAD = "canRead" ; 131 /** action 引数に渡す事の出来る アクションコマンド 変更できるかどうか {@value} */ 132 public static final String ACT_CANWRITE = "canWrite" ; 133 /** action 引数に渡す事の出来る アクションコマンド 空の新しいファイルを不可分 (atomic) に生成します (そのファイルがまだ存在しない場合だけ {@value} */ 134 public static final String ACT_CREATENEWFILE = "createNewFile" ; 135 /** action 引数に渡す事の出来る アクションコマンド ファイルまたはディレクトリを削除{@value} */ 136 public static final String ACT_DELETE = "delete" ; 137 /** action 引数に渡す事の出来る アクションコマンド ファイルが存在するかどうか {@value} */ 138 public static final String ACT_EXISTS = "exists" ; 139 /** action 引数に渡す事の出来る アクションコマンド ファイルがディレクトリであるかどうか{@value} */ 140 public static final String ACT_ISDIRECTORY = "isDirectory" ; 141 /** action 引数に渡す事の出来る アクションコマンド ファイルが普通のファイルかどうか{@value} */ 142 public static final String ACT_ISFILE = "isFile" ; 143 /** action 引数に渡す事の出来る アクションコマンド ファイルが隠しファイルかどうか {@value} */ 144 public static final String ACT_ISHIDDEN = "isHidden" ; 145 /** action 引数に渡す事の出来る アクションコマンド ディレクトリを生成します。 {@value} */ 146 public static final String ACT_MKDIR = "mkdir" ; 147 /** action 引数に渡す事の出来る アクションコマンド ディレクトリを生成します。 {@value} */ 148 public static final String ACT_MKDIRS = "mkdirs" ; 149 /** action 引数に渡す事の出来る アクションコマンド ファイル名を変更します。 {@value} */ 150 public static final String ACT_RENAMETO = "renameTo" ; // 3.5.6.5 (2004/08/09) 151 /** action 引数に渡す事の出来る アクションコマンド ファイルを読み込んで表示します。 {@value} */ 152 public static final String ACT_READ = "read" ; // 3.6.0.0 (2004/09/25) 153 /** action 引数に渡す事の出来る アクションコマンド ファイルサイズが0Byte以上のファイルが存在するかどうか判定。 {@value} */ 154 public static final String ACT_EXISTSLENGTH = "existsLength" ; // 3.8.5.2 (2006/05/31) 155 /** action 引数に渡す事の出来る アクションコマンド ファイルまたはディレクトリをコピーします。 {@value} */ 156 public static final String ACT_COPY = "copy" ; // 5.3.6.0 (2011/06/01) 157 /** action 引数に渡す事の出来る アクションコマンド ストリームファイルをコピーします。 {@value} */ 158 public static final String ACT_COPYST = "copyST" ; // 6.3.6.1 (2015/08/28) 159 /** action 引数に渡す事の出来る アクションコマンド ディレクトリのファイルリストをListオブジェクトにコピーします。 {@value} */ 160 public static final String ACT_LIST = "list" ; // 6.2.3.0 (2015/05/01) 161 /** action 引数に渡す事の出来る アクションコマンド ZIP圧縮します。 {@value} */ 162 public static final String ACT_ZIP = "zip" ; // 5.9.2.2 (2015/11/20) 163 /** action 引数に渡す事の出来る アクションコマンド タイムスタンプを現在時刻に変更します。 {@value} */ 164 public static final String ACT_TIMESTAMP = "timeStamp" ; // 6.7.0.0 (2016/12/28) 165 166 // 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。 167 private static final Set<String> ACTION_SET = new ArraySet<>( 168 ACT_CANREAD , ACT_CANWRITE , ACT_CREATENEWFILE , ACT_DELETE , ACT_EXISTS , ACT_ISDIRECTORY , 169 ACT_ISFILE , ACT_ISHIDDEN , ACT_MKDIR , ACT_MKDIRS , ACT_RENAMETO , ACT_READ , 170 ACT_EXISTSLENGTH , ACT_COPY , ACT_COPYST , ACT_LIST , ACT_ZIP , ACT_TIMESTAMP ); 171 172 private String fileURL = HybsSystem.sys( "FILE_URL" ); 173 private String file1 = ""; 174 private String file2 ; 175 private String action ; 176 private boolean rtnCode ; 177 178 private boolean notEquals ; // 3.8.5.2 (2006/05/31) 判定結果を反転させて処理します。 179 private boolean useStop = true; // 3.8.5.2 (2006/05/31) エラー時BODYを処理後に停止(true)するかどうか 180 181 private String encode ; // 5.1.9.0 (2010/08/01) READ時のエンコード指定 182 183// private String fromStorage ; // 5.10.9.0 (2019/03/01) 8.0.0.1 (2021/10/08) 184// private String fromBucket ; // 5.10.9.0 (2019/03/01) 8.0.0.1 (2021/10/08) 185 private boolean fromLocal ; // 8.0.1.0 (2021/10/29) クラウド設定を使用しない場合は、true 186// private String toStorage ; // 5.10.9.0 (2019/03/01) 8.0.0.1 (2021/10/08) 187// private String toBucket ; // 5.10.9.0 (2019/03/01) 8.0.0.1 (2021/10/08) 188 private boolean toLocal ; // 8.0.1.0 (2021/10/29) クラウド設定を使用しない場合は、true 189 private boolean useLocal ; // 8.0.1.0 (2021/10/29) クラウド設定を使用しない場合は、true 190 191 /** 192 * デフォルトコンストラクター 193 * 194 * @og.rev 6.4.2.0 (2016/01/29) PMD refactoring. Each class should declare at least one constructor. 195 */ 196 public FileTag() { super(); } // これも、自動的に呼ばれるが、空のメソッドを作成すると警告されるので、明示的にしておきます。 197 198 /** 199 * Taglibの開始タグが見つかったときに処理する doStartTag() を オーバーライドします。 200 * 201 * @og.rev 3.6.0.0 (2004/09/25) file オブジェクトの作成を actionExec 移動 202 * @og.rev 3.8.5.2 (2006/05/31) notEquals追加。 判定結果を反転させて処理します。 203 * @og.rev 5.7.7.2 (2014/06/20) caseKey,caseVal,caseNN,caseNull 属性を追加 204 * 205 * @return 後続処理の指示 206 */ 207 @Override 208 public int doStartTag() { 209 // 5.7.7.2 (2014/06/20) caseKey,caseVal,caseNN,caseNull 属性を追加 210 if( useTag() ) { 211 if( useLocal ) { // 8.0.1.0 (2021/10/29) クラウド設定を使用しない場合は、true 212// fromBucket = FileOperation.LOCAL ; 213// toBucket = FileOperation.LOCAL ; 214 fromLocal = true ; 215 toLocal = true ; 216 } 217 218 try { 219 rtnCode = notEquals ^ actionExec( action ); // 3.8.5.2 (2006/05/31) 排他的論理和(XOR) 220 } 221 catch( final IOException ex ) { 222 final String errMsg = "指定のアクションは実行できません。アクションエラー" + CR 223 + "\t action=[" + action + "]" + CR 224 + "\t fileURL=[" + fileURL + "]" + CR 225 + "\t file1=[" + file1 + "]" + CR 226 + "\t file2=[" + file2 + "]" + CR ; 227 throw new HybsSystemException( errMsg,ex ); // 3.5.5.4 (2004/04/15) 引数の並び順変更 228 } 229 230 if( rtnCode ) { return SKIP_BODY ; } // Body を評価しない 231 else { return EVAL_BODY_INCLUDE ; } // Body インクルード( extends TagSupport 時) 232 } 233 234 return SKIP_BODY ; 235 } 236 237 /** 238 * Taglibの終了タグが見つかったときに処理する doEndTag() を オーバーライドします。 239 * 240 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。 241 * @og.rev 3.8.5.2 (2006/05/31) useStop 追加。 エラー時BODYを処理後に停止(true)するかどうか 242 * @og.rev 5.7.7.2 (2014/06/20) caseKey,caseVal,caseNN,caseNull 属性を追加 243 * 244 * @return 後続処理の指示 245 */ 246 @Override 247 public int doEndTag() { 248 debugPrint(); // 4.0.0 (2005/02/28) 249 250 // 6.4.1.1 (2016/01/16) PMD refactoring. A method should have only one exit point, and that should be the last statement in the method 251 return useTag() && useStop && !rtnCode ? SKIP_PAGE : EVAL_PAGE ; 252 } 253 254 /** 255 * タグリブオブジェクトをリリースします。 256 * キャッシュされて再利用されるので、フィールドの初期設定を行います。 257 * 258 * @og.rev 2.0.0.4 (2002/09/27) カスタムタグの release() メソッドを、追加 259 * @og.rev 3.1.1.2 (2003/04/04) Tomcat4.1 対応。release2() を doEndTag()で呼ぶ。 260 * @og.rev 3.6.0.0 (2004/09/24) columns 、tableId 、file 削除 261 * @og.rev 3.8.5.2 (2006/05/31) notEquals 、useStop 追加 262 * @og.rev 5.1.9.0 (2010/08/01) READ時のエンコード指定 263 * @og.rev 8.0.0.1 (2021/10/08) fromStorage,fromBucket,toStorage,toBucket 追加 264 * @og.rev 8.0.1.0 (2021/10/29) useLocal 属性を追加。 265 */ 266 @Override 267 protected void release2() { 268 super.release2(); 269 fileURL = HybsSystem.sys( "FILE_URL" ); 270 file1 = ""; 271 file2 = null; 272 action = null; 273 rtnCode = false; 274 notEquals = false; // 3.8.5.2 (2006/05/31) 判定結果を反転させて処理します。 275 useStop = true; // 3.8.5.2 (2006/05/31) エラー時BODYを処理後に停止(true)するかどうか 276 encode = null; // 5.1.9.0 (2010/08/01) READ時のエンコード指定 277// fromStorage = null; // 5.10.9.0 (2019/03/01) 8.0.0.1 (2021/10/08) 278// fromBucket = null; // 5.10.9.0 (2019/03/01) 8.0.0.1 (2021/10/08) 279 fromLocal = false; // 8.0.1.0 (2021/10/29) クラウド設定を使用しない場合は、true 280// toStorage = null; // 5.10.9.0 (2019/03/01) 8.0.0.1 (2021/10/08) 281// toBucket = null; // 5.10.9.0 (2019/03/01) 8.0.0.1 (2021/10/08) 282 useLocal = false; // 8.0.1.0 (2021/10/29) クラウド設定を使用しない場合は、true 283 toLocal = false; // 8.0.1.0 (2021/10/29) クラウド設定を使用しない場合は、true 284 } 285 286 /** 287 * アクションを実行します。 288 * アクションは,指定のアクションコマンドに対応する処理を入力データに 289 * 対して行います。 290 * 291 * @og.rev 3.0.0.0 (2002/12/25) ACTION_LIST のチェックを削除 292 * @og.rev 3.6.0.0 (2004/09/25) ACT_read を追加 , file オブジェクトを移動 293 * @og.rev 3.8.5.2 (2006/05/31) existsLength 追加 294 * @og.rev 4.0.0.0 (2007/11/28) メソッドの戻り値をチェックします。 295 * @og.rev 5.1.9.0 (2010/08/01) READ時のエンコード指定 296 * @og.rev 5.3.6.0 (2011/06/01) ACT_COPY 対応 297 * @og.rev 5.7.1.1 (2013/12/13) copy元(file1)のファイルが存在しなければ、エラーにします。 298 * @og.rev 6.2.3.0 (2015/05/01) list アクション追加、delete 処理は、フォルダ階層を丸ごと削除します。 299 * @og.rev 6.3.6.1 (2015/08/28) ACT_COPYST 対応( copyST アクション時に、copy元に、アドレス指定できるようにする)。 300 * @og.rev 5.9.2.2 (2015/11/12) ACT_ZIP追加 301 * @og.rev 6.7.0.0 (2016/12/28) ACT_TIMESTAMP追加 302 * @og.rev 6.8.0.0 (2017/06/02) zipFile の親ディレクトリを作成します。 303 * @og.rev 6.9.8.0 (2018/05/28) FindBugs:例外的戻り値を無視しているメソッド(mkdirs) 304 * @og.rev 7.2.6.3 (2020/08/07) mkdirs は、先に存在チェックを入れて、存在していればtrueにする。 305 * @og.rev 8.0.0.1 (2021/10/08) fromStorage,fromBucket,toStorage,toBucket 追加 306 * @og.rev 8.0.0.2 (2021/10/15) ローカルファイルとクラウドファイル間の移動 307 * 308 * @param action アクション (public static final 宣言されている文字列) 309 * 310 * @return 実行後のデータ 311 */ 312 private boolean actionExec( final String action ) throws IOException { 313 // 6.4.1.1 (2016/01/16) PMD refactoring. Avoid if (x != y) ..; else ..; 314 if( action == null ) { 315 final String errMsg = "アクションが指定されていません。アクション NULL エラー" + CR 316 + "\t file=[" + file1 + "]" + CR 317 + "\t matches=[" + file2 + "]" + CR ; 318 throw new HybsSystemException( errMsg ); 319 } 320 321 final String directory = HybsSystem.url2dir( fileURL ); 322 // 8.0.0.1 (2021/10/08) fromStorage,fromBucket,toStorage,toBucket 追加 323 // 8.0.1.0 (2021/10/29) storageType , bucketName 削除 324// final File file = new File( StringUtil.urlAppend( directory,file1 ) ); 325// final File file = HybsFileOperationFactory.create(fromStorage, fromBucket, StringUtil.urlAppend(directory, file1)); 326 final File file = HybsFileOperationFactory.create(fromLocal, StringUtil.urlAppend(directory, file1)); 327 328 boolean rtnVal = false; 329 if( ACT_CANREAD.equalsIgnoreCase( action ) ) { rtnVal = file.canRead(); } 330 else if( ACT_CANWRITE.equalsIgnoreCase( action ) ) { rtnVal = file.canWrite(); } 331 else if( ACT_CREATENEWFILE.equalsIgnoreCase( action ) ) { rtnVal = file.createNewFile(); } 332 else if( ACT_DELETE.equalsIgnoreCase( action ) ) { rtnVal = FileUtil.deleteFiles( file ); } 333 else if( ACT_EXISTS.equalsIgnoreCase( action ) ) { rtnVal = file.exists(); } 334 else if( ACT_ISDIRECTORY.equalsIgnoreCase( action ) ) { rtnVal = file.isDirectory(); } 335 else if( ACT_ISFILE.equalsIgnoreCase( action ) ) { rtnVal = file.isFile(); } 336 else if( ACT_ISHIDDEN.equalsIgnoreCase( action ) ) { rtnVal = file.isHidden(); } 337 else if( ACT_MKDIR.equalsIgnoreCase( action ) ) { 338 if( file.isDirectory() ) { rtnVal = true; } 339 else { rtnVal = file.mkdir(); } 340 } 341 // 7.2.6.3 (2020/08/07) mkdirs は、先に存在チェックを入れて、存在していればtrueにする。 342// else if( ACT_MKDIRS.equalsIgnoreCase( action ) ) { rtnVal = file.mkdirs(); } 343 else if( ACT_MKDIRS.equalsIgnoreCase( action ) ) { // 7.2.6.3 (2020/08/07) 344 if( file.isDirectory() ) { rtnVal = true; } 345 else { rtnVal = file.mkdirs(); } 346 } 347 else if( ACT_RENAMETO.equalsIgnoreCase( action ) ) { 348 if( file2 != null ) { 349 // 8.0.0.1 (2021/10/08) fromStorage,fromBucket,toStorage,toBucket 追加 350 // 8.0.1.0 (2021/10/29) storageType , bucketName 削除 351// final File newFile = new File( StringUtil.urlAppend( directory,file2 ) ); 352// final File newFile = HybsFileOperationFactory.create(fromStorage, fromBucket, StringUtil.urlAppend(directory, file2)); 353 final File newFile = HybsFileOperationFactory.create(fromLocal, StringUtil.urlAppend(directory, file2)); 354 if( newFile.exists() && !newFile.delete() ) { 355 final String errMsg = "所定のファイルを削除できませんでした。[" + newFile + "]" ; 356 throw new OgRuntimeException( errMsg ); 357 } 358 rtnVal = file.renameTo( newFile ); 359 } 360 } 361 // 3.6.0.0 (2004/09/25) ACT_read を追加 362 else if( ACT_READ.equalsIgnoreCase( action ) ) { 363 if( file.isFile() ) { 364 // 6.2.3.0 (2015/05/01) 365 String text ; 366 if( POIUtil.isPOI( file ) ) { 367 text = POIUtil.extractor( file ); 368 } 369 else { 370 final String enc = encode == null ? "UTF-8" : encode ; 371 text = POIUtil.extractor( file,enc ); 372 } 373 374 rtnVal = true; 375 setRequestAttribute( "read",text ); 376 } 377 else { 378 final String errMsg = "ファイルが存在しないか、ファイルではありません。" + CR 379 + "\t action=[" + action + "]" + CR 380 + "\t fileURL=[" + fileURL + "]" + CR 381 + "\t directory=[" + directory + "]" + CR 382 + "\t file1=[" + file1 + "]" + CR ; 383 throw new HybsSystemException( errMsg ); 384 } 385 } 386 // 3.8.5.2 (2006/05/31) ファイルサイズが0Byte以上のファイルが存在するかどうか判定。 387 else if( ACT_EXISTSLENGTH.equalsIgnoreCase( action ) ) { 388 rtnVal = file.exists() && file.length() > 0L ; 389 } 390 // 5.3.6.0 (2011/06/01) ファイルコピー対応 391 // 6.0.0.1 (2014/04/25) These nested if statements could be combined 392 // 6.3.6.1 (2015/08/28) フォルダとファイルの自動判定(FileUtil.copy側で判断する) 393 else if( ACT_COPY.equalsIgnoreCase( action ) && file2 != null ) { 394 // 8.0.0.1 (2021/10/08) fromStorage,fromBucket,toStorage,toBucket 追加 395 // 8.0.1.0 (2021/10/29) storageType , bucketName 削除 396// final File newFile = new File( StringUtil.urlAppend( directory,file2 ) ); 397// final File newFile = HybsFileOperationFactory.create(toStorage, toBucket, StringUtil.urlAppend(directory, file2)); 398 final File newFile = HybsFileOperationFactory.create(toLocal, StringUtil.urlAppend(directory, file2)); 399 400 if( file.exists() ) { 401 // FileUtil.copy 側で、toFile のフォルダを作成します。 402 // 6.3.6.1 (2015/08/28) で、fromFile がディレクトリでも処理できるように変更。 403 rtnVal = FileUtil.copy( file, newFile ); 404 } 405 else { 406 final String errMsg = "copy元(file1)のファイルが存在しません。" + CR 407 + "\t action=[" + action + "]" + CR 408 + "\t fileURL=[" + fileURL + "]" + CR 409 + "\t directory=[" + directory + "]" + CR 410 + "\t file1=[" + file1 + "]" + CR 411 + "\t file2=[" + file2 + "]" + CR ; 412 throw new HybsSystemException( errMsg ); 413 } 414 } 415 // 6.3.6.1 (2015/08/28) copyST アクション時に、copy元に、アドレス指定できるようにする。 416 else if( ACT_COPYST.equalsIgnoreCase( action ) && file2 != null ) { 417 // 8.0.0.1 (2021/10/08) fromStorage,fromBucket,toStorage,toBucket 追加 418 final String toFile = StringUtil.urlAppend( directory,file2 ); 419// final File newFile = new File( StringUtil.urlAppend( directory,file2 ) ); 420 final File newFile = new File( toFile ); 421 422 // ※ getResourceAsStream は、/gf/jsp/・・・ ではなく、/jsp/・・・ でのアドレス指定で取得します。 423 final ServletContext application = pageContext.getServletContext(); 424 rtnVal = FileUtil.copy( application.getResourceAsStream( file1 ), newFile ); 425 426 if( !rtnVal ) { 427 final String errMsg = action + " アクションが実行できませんでした。" + CR 428 + "\t action=[" + action + "]" + CR 429 + "\t fileURL=[" + fileURL + "]" + CR 430 + "\t directory=[" + directory + "]" + CR 431 + "\t file1=[" + file1 + "]" + CR 432 + "\t file2=[" + file2 + "]" + CR ; 433 throw new HybsSystemException( errMsg ); 434 } 435 436 // 8.0.0.1 (2021/10/08) ストリームからクラウドファイルへのコピーが上手くいかない。 437 // 一旦、ローカルに出力したファイルをクラウドへコピーしています。 438 // 8.0.0.2 (2021/10/15) ローカルファイルとクラウドファイル間の移動。 toStorage, toBucket 有りなので、他と方法が異なる。 439 // 8.0.1.0 (2021/10/29) storageType , bucketName 削除 440// final FileOperation cloudFile = HybsFileOperationFactory.create( toStorage, toBucket, toFile ); 441 final FileOperation cloudFile = HybsFileOperationFactory.create( toLocal, toFile ); 442// if(!cloudFile.isLocal()){ 443 if( cloudFile.isCloud() ){ 444 FileUtil.copy( newFile,cloudFile ); 445 newFile.delete(); 446 } 447 } 448 // 6.2.3.0 (2015/05/01) 449 else if( ACT_LIST.equalsIgnoreCase( action ) ) { 450 final String[] files = file.isDirectory() ? file.list() : new String[] { file.getName() }; 451 final List<String> list = new ArrayList<>(); 452 453 // 6.3.9.0 (2015/11/06) null になっている可能性がある(findbugs) 454 if( files != null ) { 455 final boolean use = file2 == null || file2.isEmpty(); 456 for( final String nm : files ) { 457 if( use || nm.matches( file2 ) ) { 458 list.add( nm ); 459 } 460 } 461 } 462 463 setRequestAttribute( "list",list ); 464 rtnVal = true; 465 } 466 // 5.9.2.2 (2015/11/20) zip追加 467 else if( ACT_ZIP.equalsIgnoreCase( action ) && file2 != null ) { 468 //あるかないかだけ見る 469 // 6.4.1.1 (2016/01/16) PMD refactoring. When doing a String.toLowerCase()/toUpperCase() call, use a Locale 470 if( file2.toLowerCase(Locale.JAPAN).indexOf( ".zip" ) < 0 ){ 471 file2 = file2 + ".zip"; 472 } 473 final File zipFile = new File( StringUtil.urlAppend( directory,file2 ) ); 474 // 6.9.8.0 (2018/05/28) FindBugs:例外的戻り値を無視しているメソッド 475// zipFile.getParentFile().mkdirs(); // 6.8.0.0 (2017/06/02) zipFile の親ディレクトリを作成します。 476 final File parent = zipFile.getParentFile(); // 親フォルダを取得。nullもありえる 477 if( parent == null || !parent.exists() && !parent.mkdirs() ) { 478 final String errMsg = "zipFileファイルの親フォルダを作成できませんでした。" + CR 479 + " zipFile=[" + zipFile + "]" + CR ; 480 throw new HybsSystemException( errMsg ); 481 } 482 483 final List<File> ziplist = ZipArchive.compress( file , zipFile ); // 6.7.0.0 (2016/12/28) 返り値で、正誤判定します。 484 rtnVal = !ziplist.isEmpty(); // 6.7.0.0 (2016/12/28) true/false の判定を入れます。 485 } 486 // 6.7.0.0 (2016/12/28) timeStamp追加。タイムスタンプを現在時刻に変更します。 487 else if( ACT_TIMESTAMP.equalsIgnoreCase( action ) ) { 488 rtnVal = file.setLastModified( System.currentTimeMillis() ); 489 } 490 491 return rtnVal; 492 } 493 494 /** 495 * 【TAG】アクション(canRead,canWrite,createNewFile,delete,renameTo,exists,isDirectory,isFile,isHidden,mkdir,mkdirs,read,existsLength,copy,copyST,list,zip,timeStamp)を指定します。 496 * 497 * @og.tag 498 * アクションは,HTMLから(get/post)指定されますので,ACT_xxx で設定される 499 * フィールド定数値のいづれかを、指定できます。 500 * 処理の結果が、false の場合は、body 要素を表示して終了します。 501 * useStop 属性と、notEquals 属性によって、上記の振る舞いをけることが可能です。 502 * 503 * canRead 読み込めるかどうかを判定。 504 * canWrite 変更できるかどうか判定。 505 * createNewFile 空の新しいファイルを不可分 (atomic) に生成。(そのファイルがまだ存在しない場合だけ) 506 * delete ファイルまたはディレクトリを削除(ディレクトリ階層をすべて削除)。 507 * renameTo ファイルまたはディレクトリ名を変更。 508 * exists ファイルが存在するかどうか判定。 509 * isDirectory ファイルがディレクトリであるかどうか判定。 510 * isFile ファイルが普通のファイルかどうか判定。 511 * isHidden ファイルが隠しファイルかどうか判定。 512 * mkdir ディレクトリを生成。 513 * mkdirs ディレクトリを複数生成。 514 * read ファイルを読み込んで、パラメータにセットします(6.2.3.0 (2015/05/01))。 515 * existsLength ファイルサイズが0Byte以上のファイルが存在するかどうか判定。 516 * copy ファイルまたはディレクトリをコピー(file1 ⇒ file2 にコピー)。 517 * copyST ストリームファイルをコピー(file1(アドレス) ⇒ file2 にコピー)。 518 * list ファイルリストをListオブジェクトにコピーして、パラメータにセットします(6.2.3.0 (2015/05/01))。 519 * zip ファイルまたはディレクトリをZIPファイルに圧縮します。(file1⇒file2) 520 * timeStamp ファイルのタイムスタンプを現在時刻に変更します。(file1のみ) 521 * 522 * ※1 copyST の file1 は、getResourceAsStream を使用の為、/gf/jsp/・・・ ではなく、/jsp/・・・ でのアドレス指定で取得します。 523 * 524 * @og.rev 3.0.0.0 (2002/12/25) ACTION_LIST のチェックを導入 525 * @og.rev 3.5.6.2 (2004/07/05) 文字列の連結にStringBuilderを使用します。 526 * @og.rev 6.3.4.0 (2015/08/01) エラーメッセージを、変更。 527 * @og.rev 6.3.6.1 (2015/08/28) copyST アクション追加 528 * @og.rev 6.4.3.4 (2016/03/11) String配列 から、Setに置き換えます。 529 * 530 * @param cmd アクション文字列 531 * @see <a href="../../../../constant-values.html#org.opengion.hayabusa.taglib.FileTag.ACT_canRead">アクション定数</a> 532 */ 533 public void setAction( final String cmd ) { 534 action = getRequestParameter( cmd ); 535 536 if( ! check( action, ACTION_SET ) ) { 537 final String errMsg = "指定のアクションは実行できません。アクションエラー" + CR 538 + "\t action=[" + action + "]" + CR 539 + "\t actionList=" + String.join( ", " , ACTION_SET ) ; 540 throw new HybsSystemException( errMsg ); 541 } 542 } 543 544 /** 545 * 【TAG】操作するファイルのディレクトリを指定します 546 * (初期値:FILE_URL[={@og.value SystemData#FILE_URL}])。 547 * 548 * @og.tag 549 * この属性で指定されるディレクトリのファイルを操作します。 550 * 指定方法は、通常の fileURL 属性と同様に、先頭が、'/' (UNIX) または、2文字目が、 551 * ":" (Windows)の場合は、指定のURLそのままのディレクトリに、そうでない場合は、 552 * (初期値:システム定数のFILE_URL[={@og.value SystemData#FILE_URL}])。 553 * 554 * @og.rev 4.0.0.0 (2005/01/31) urlAppend メソッドの利用 555 * @og.rev 4.0.0.0 (2007/11/20) 指定されたディレクトリ名の最後が"\"or"/"で終わっていない場合に、"/"を付加する。 556 * @og.rev 6.4.2.1 (2016/02/05) URLの最後に、"/" を追加する処理を廃止。 557 * 558 * @param url ファイルURL 559 * @see org.opengion.hayabusa.common.SystemData#FILE_URL 560 */ 561 public void setFileURL( final String url ) { 562 final String furl = nval( getRequestParameter( url ),null ); 563 if( furl != null ) { 564 fileURL = StringUtil.urlAppend( fileURL,furl ); 565 } 566 } 567 568 /** 569 * 【TAG】基準となるファイル名を指定します(コマンドの左辺のファイル名です)。 570 * 571 * @og.tag 572 * コマンドの左辺のファイル名です。 573 * 574 * ※ 6.3.6.1 (2015/08/28) 575 * copyST アクション時に、copy元に、アドレス指定できるようにする。 576 * 577 * @param fname ファイル名1 578 */ 579 public void setFile1( final String fname ) { 580 file1 = nval( getRequestParameter( fname ),file1 ); 581 } 582 583 /** 584 * 【TAG】処理結果となるファイル名を指定します(コマンドの右辺のファイル名です)。 585 * 586 * @og.tag 587 * コマンドの右辺のファイル名です。 588 * ただし、action="list" の時は、file2 を、フィルターとして使用します。 589 * 590 * @param fname ファイル名2 591 */ 592 public void setFile2( final String fname ) { 593 file2 = nval( getRequestParameter( fname ),file2 ); 594 } 595 596 /** 597 * 【TAG】判定結果を反転させるかどうか[true/false]を指定します(初期値:false)。 598 * 599 * @og.tag 600 * 通常の判定結果において、不成立(false)の場合に、BODY を実行します。 601 * 通常の処理結果の正反対の処理を行います。 602 * 初期値は、通常 (true 以外)です。 603 * 604 * @og.rev 3.8.5.2 (2006/05/31) 新規追加 605 * 606 * @param flag 判定結果反転 [true:反転する/それ以外:通常] 607 */ 608 public void setNotEquals( final String flag ) { 609 notEquals = nval( getRequestParameter( flag ),notEquals ); 610 } 611 612 /** 613 * 【TAG】エラー時BODYを処理後に停止するかどうか[true/false]を指定します(初期値:true)。 614 * 615 * @og.tag 616 * 処理結果などに応じて、以下の処理を停止したい場合に、使用します。 617 * 通常は、条件を判定後、false の場合に、BODY部を出力(処理)した後に、 618 * 処理を停止します。(useStop="true") 619 * false を指定すると、判定結果に無関係に、以下の処理を実行します。 620 * 処理は継続したいが、警告表示する場合に、useStop="false" を指定します。 621 * 初期値は、停止する ("true")です。 622 * 623 * @og.rev 3.8.5.2 (2006/05/31) 新規追加 624 * 625 * @param flag 処理後停止 [true:する/それ以外:しない] 626 */ 627 public void setUseStop( final String flag ) { 628 useStop = nval( getRequestParameter( flag ),useStop ); 629 } 630 631 /** 632 * 【TAG】ファイルを読み込む(action="read")際のエンコードを指定します(初期値:OS依存文字コード)。 633 * 634 * @og.tag 635 * ファイルを読み込む(action="read")際のエンコードを指定します。 636 * action="read"以外場合には、この属性値は利用されません。 637 * 指定しない場合は、OS依存文字コードで読み込まれます。 638 * 639 * @og.rev 5.1.9.0 (2010/08/01) 新規作成 640 * 641 * @param enc ファイル読み込みのエンコード 642 */ 643 public void setEncode( final String enc ) { 644 encode = nval( getRequestParameter( enc ),encode ); 645 } 646 647// /** 648// * 【TAG】テンプレートファイルの読み込み元ストレージタイプを指定します。 649// * 650// * @og.tag 651// * フクラウド読み込み時の、from に当たるストレージタイプを指定します。 652// * 初期値は、システム定数の『CLOUD_TARGET』です。(例:AWS) 653// * 強制的に、ローカルファイルを指定する場合は、空文字列ではなく、"LOCAL" を指定します。 654// * 655// * @og.rev 8.0.1.0 (2021/10/29) 新規作成 656// * @og.rev 8.0.1.0 (2021/10/29) useLocal 属性を追加。storageType , bucketName 削除 657// * 658// * @param fromType 元ストレージタイプ 659// */ 660// public void setFromStorage( final String fromType ) { 661// fromStorage = nval( getRequestParameter( fromType ),fromStorage ); 662// } 663 664// /** 665// * 【TAG】テンプレートファイルの読み込み元バケット名を指定します。 666// * 667// * @og.tag 668// * フクラウド読み込み時の、from に当たるバケット名を指定します。 669// * 初期値は、システム定数の『CLOUD_BUCKET』です。 670// * 強制的に、ローカルファイルを指定する場合は、空文字列ではなく、"LOCAL" を指定します。 671// * 672// * @og.rev 8.0.1.0 (2021/10/29) 新規作成 673// * @og.rev 8.0.1.0 (2021/10/29) useLocal 属性を追加。storageType , bucketName 削除 674// * 675// * @param fromBkt 元バケット名 676// */ 677// public void setFromBucket( final String fromBkt ) { 678// fromBucket = nval( getRequestParameter( fromBkt ),fromBucket ); 679// } 680 681// /** 682// * 【TAG】生成したファイルの出力先ストレージタイプを指定します。 683// * 684// * @og.tag 685// * フクラウド書き込み時の、to に当たるストレージタイプを指定します。 686// * 初期値は、システム定数の『CLOUD_TARGET』です。 687// * 強制的に、ローカルファイルを指定する場合は、空文字列ではなく、"LOCAL" を指定します。 688// * 689// * @og.rev 8.0.1.0 (2021/10/29) 新規作成 690// * @og.rev 8.0.1.0 (2021/10/29) useLocal 属性を追加。storageType , bucketName 削除 691// * 692// * @param toType 出力先ストレージタイプ 693// */ 694// public void setToStorage( final String toType ) { 695// toStorage = nval( getRequestParameter( toType ),toStorage ); 696// } 697 698// /** 699// * 【TAG】生成したファイルの出力先バケット名を指定します。 700// * 701// * @og.tag 702// * フクラウド書き込み時の、to に当たるバケット名を指定します。 703// * 初期値は、システム定数の『CLOUD_TARGET』です。 704// * 強制的に、ローカルファイルを指定する場合は、空文字列ではなく、"LOCAL" を指定します。 705// * 706// * @og.rev 8.0.1.0 (2021/10/29) 新規作成 707// * @og.rev 8.0.1.0 (2021/10/29) useLocal 属性を追加。storageType , bucketName 削除 708// * 709// * @param toBkt 出力先バケット名 710// */ 711// public void setToBucket( final String toBkt ) { 712// toBucket = nval( getRequestParameter( toBkt ),toBucket ); 713// } 714 715 /** 716 * 【TAG】システム定数でクラウド設定されていても、クラウド環境を使用しない場合、trueを指定します(初期値:false)。 717 * 718 * @og.tag 719 * クラウド設定は、システム定数の『CLOUD_TARGET』と『CLOUD_BUCKET』の設定で自動的に使用しますが、 720 * どうしてもローカルでのみ使いたい場合は、この属性を true に設定します。 721 * 標準はfalse:設定どおりとなります。 722 * fromStorage,fromBucket,toStorage,toBucket 723 * from や to だけを強制的に、ローカルファイルを指定する場合は、空文字列ではなく、 724 * fromStorage,fromBucket や、toStorage,toBucket に、"LOCAL" を指定します。 725 * storegeとbucketは、どちらかが、LOCAL の場合は、ローカルファイル を使用します。 726 * 727 * true/false以外を指定した場合はfalse扱いとします。 728 * 729 * @og.rev 8.0.1.0 (2021/10/29) useLocal 属性を追加。 730 * @og.rev 8.0.1.0 (2021/10/29) useLocal 属性を追加。storageType , bucketName 削除 731 * 732 * @param flag ローカル環境のみ [true:ローカルのみ/false:設定どおり] 733 */ 734 public void setUseLocal( final String flag ) { 735 useLocal = nval( getRequestParameter( flag ),useLocal ); 736 } 737 738 /** 739 * 【TAG】システム定数でクラウド設定されていても、クラウド環境を使用しない場合、trueを指定します(初期値:false)。 740 * 741 * @og.tag 742 * クラウド設定は、システム定数の『CLOUD_TARGET』と『CLOUD_BUCKET』の設定で自動的に使用しますが、 743 * どうしてもローカルでのみ使いたい場合は、この属性を true に設定します。 744 * 標準はfalse:設定どおりとなります。 745 * 746 * true/false以外を指定した場合はfalse扱いとします。 747 * 748 * @og.rev 8.0.1.0 (2021/10/29) useLocal 属性を追加。 749 * 750 * @param flag ローカル環境のみ [true:ローカルのみ/false:設定どおり] 751 */ 752 public void setFromLocal( final String flag ) { 753 fromLocal = nval( getRequestParameter( flag ),fromLocal ); 754 } 755 756 /** 757 * 【TAG】システム定数でクラウド設定されていても、クラウド環境を使用しない場合、trueを指定します(初期値:false)。 758 * 759 * @og.tag 760 * クラウド設定は、システム定数の『CLOUD_TARGET』と『CLOUD_BUCKET』の設定で自動的に使用しますが、 761 * どうしてもローカルでのみ使いたい場合は、この属性を true に設定します。 762 * 標準はfalse:設定どおりとなります。 763 * 764 * true/false以外を指定した場合はfalse扱いとします。 765 * 766 * @og.rev 8.0.1.0 (2021/10/29) useLocal 属性を追加。 767 * 768 * @param flag ローカル環境のみ [true:ローカルのみ/false:設定どおり] 769 */ 770 public void setToLocal( final String flag ) { 771 toLocal = nval( getRequestParameter( flag ),toLocal ); 772 } 773 774 /** 775 * このオブジェクトの文字列表現を返します。 776 * 基本的にデバッグ目的に使用します。 777 * 778 * @return このクラスの文字列表現 779 * @og.rtnNotNull 780 */ 781 @Override 782 public String toString() { 783 return ToString.title( this.getClass().getName() ) 784 .println( "VERSION" ,VERSION ) 785 .println( "fileURL" ,fileURL ) 786 .println( "file1" ,file1 ) 787 .println( "file2" ,file2 ) 788 .println( "action" ,action ) 789 .println( "rtnCode" ,rtnCode ) 790 .println( "notEquals" ,notEquals ) 791 .println( "useStop" ,useStop ) 792 .println( "Other..." ,getAttributes().getAttribute() ) 793 .fixForm().toString() ; 794 } 795}