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.servlet; 017 018// import jakarta.servlet.http.HttpSession; // 5.9.25.0 (2017/10/06) クラウドストレージ追加対応 019 020import org.opengion.fukurou.system.OgRuntimeException ; // 6.4.2.0 (2016/01/29) 021import static org.opengion.fukurou.system.HybsConst.CR ; // 6.1.0.0 (2014/12/26) 022import org.opengion.fukurou.util.FileUtil; 023import org.opengion.fukurou.util.FileInfo; // 6.2.0.0 (2015/02/27) 024import org.opengion.fukurou.util.StringUtil; // 6.0.2.4 (2014/10/17) 025 026// import org.opengion.hayabusa.common.HybsSystem; // 5.9.25.0 (2017/10/06) クラウドストレージ追加対応 027// import org.opengion.hayabusa.io.StorageAPI; // 5.9.25.0 (2017/10/06) クラウドストレージ追加対応 028// import org.opengion.hayabusa.io.StorageAPIFactory; // 5.9.25.0 (2017/10/06) クラウドストレージ追加対応 029import org.opengion.hayabusa.io.HybsFileOperationFactory; // 8.0.0.0 (2021/09/30) 030 031import java.io.File; 032 033/** 034 * ファイルをサーバーにアップロードする場合に使用されるファイル管理クラスです。 035 * HTML5 ファイルアップロードの複数選択(multiple)対応 に伴い、一つのクラスとして public化します。 036 * 037 * @og.group その他機能 038 * @og.rev 5.7.1.1 (2013/12/13) HTML5 ファイルアップロードの複数選択(multiple)対応 039 * @og.rev 5.9.25.0 (2017/10/06) クラウドストレージ追加対応 040 * 041 * @version 4.0 042 * @author Kazuhiko Hasegawa 043 * @since JDK5.0, 044 */ 045public final class UploadedFile implements Comparable<UploadedFile> { 046 047 /** バッファの初期容量を通常より多い目に設定します。 {@value} */ 048 public static final int BUFFER_MIDDLE = 200; 049 050 // 5.9.25.0 (2017/10/06) MODIFY File型をString型に変更 051 private String filename ; // 現時点での置き換え後ファイル名 052 053 private final String uniqKey ; // アップロードされたファイル名(ユニークにしておきます) 054 private final String dir ; 055 private final String name ; 056 private final String original ; 057 private final String type ; 058 059 /** 060 * アップロードファイルの管理オブジェクトを作成します。 061 * 062 * @og.rev 5.7.1.1 (2013/12/13) HTML5 ファイルアップロードの複数選択(multiple)対応 063 * 064 * @param uniqKey ユニークキー(初期アップロードファイル名) 065 * @param dir ファイルを保管するフォルダ 066 * @param name ファイルアップロードされた時のname属性 067 * @param original ファイル名(オリジナル) 068 * @param type コンテントタイプ 069 */ 070 UploadedFile( final String uniqKey, final String dir, final String name, final String original, final String type ) { 071 this.uniqKey = uniqKey; // 5.7.1.1 (2013/12/13) uniqKey を確定させる。 072 this.dir = dir; 073 this.name = name; 074 this.original = original; 075 this.type = type; 076 } 077 078 /** 079 * ファイルアップロードされた時のname属性を取得します。 080 * 081 * @og.rev 5.7.1.1 (2013/12/13) HTML5 ファイルアップロードの複数選択(multiple)対応 082 * 083 * @return ファイルアップロードされた時のname属性 084 */ 085 public String getName() { 086 return name; 087 } 088 089 /** 090 * コンテントタイプを取得します。 091 * 092 * @return コンテントタイプ 093 */ 094 public String getContentType() { 095 return type; 096 } 097 098 /** 099 * ファイル名(置き換え後)を取得します。 100 * 101 * @og.rev 5.7.1.2 (2013/12/20) zip 対応で、Fileオブジェクトを返すようにします。 102 * @og.rev 5.9.25.0 (2017/10/06) FILE型をString型に変更 103 * 104 * @return ファイル名(置き換え後) 105 */ 106 public String getUploadFile(){ 107 return filename; 108 } 109 110 /** 111 * ファイル名(置き換え後)の置き換えを実行します。 112 * useBackup = true にすると、dir の直下に、"_backup" フォルダを作成します。 113 * バックアップファイル名は、元のファイル名(拡張子含む) + "_" + 現在時刻のlong値 + "." + 元のファイルの拡張子 114 * 115 * newName が null の場合は、original のファイル名に、変換します。 116 * 117 * 6.0.2.4 (2014/10/17) 118 * useBackup="rename" で、すでに同名のファイルが存在した場合に、"_001" のような文字列を追加したファイルにリネームします。 119 * Windowsの " - コピー (2)" に近いですが、桁数を抑えるのと、useBackup="true" と異なり、過去の同一ファイル名は 120 * そのまま、有効になります。同一ファイルが同一フォルダに存在する場合のみ連番が付与されます。 121 * 122 * newName の指定に、フォルダ名を含めることを可能にしました。 123 * 124 * @og.rev 5.7.1.1 (2013/12/13) 新規追加 125 * @og.rev 5.7.2.1 (2014/01/17) FileUtil.renameTo の引数の順番を間違えていた。 126 * @og.rev 6.0.2.4 (2014/10/17) useBackup 修正、newName に、フォルダ名を含めることが可能 127 * @og.rev 6.2.0.0 (2015/02/27) FileInfoクラスを使用。 (FileUtil#getExtension(String) の廃止) 128 * @og.rev 5.9.25.0 (2017/10/06) returnをString型に変更。引数にfileURLとsessionを追加 129 * @og.rev 5.10.9.0 (2019/03/01) クラウドストレージ対応の追加。 130 * @og.rev 8.0.1.0 (2021/10/29) useLocal 属性を追加。storageType , bucketName 削除 131 * 132 * @param newName ファイル名(nullの場合は、オリジナル) 133 * @param prefix 接頭辞(nullの場合は、何もつけない) 134 * @param sufix 接尾辞(nullの場合は、何もつけない) 135 * @param useBackup 置き換え後ファイルの処理方法(true:backupフォルダ/false:しない/rename:重複しない連番) 136 * @param fileURL クラウドストレージ用のURL 137// * @param hsession セッション 138// * @param storage クラウドプラグイン名(ローカルファイルを強制する場合は、LOCAL を指定する) 139// * @param bucket バケット名(ローカルファイルを強制する場合は、LOCAL を指定する) 140 * @param useLocal 強制的にローカルファイルを使用する場合、true にセットします。 141 * @return 最終的に作成されたファイルオブジェクト 142 */ 143// public String renameTo( final String newName , final String prefix , final String sufix , final String useBackup, final String fileURL, final HttpSession hsession ) { 144 public String renameTo( final String newName , final String prefix , final String sufix , final String useBackup, final String fileURL, 145// final String storage, final String bucket ) { 146 final boolean useLocal ) { 147 148 // 6.0.2.4 (2014/10/17) prfix が null でなければ、連結。newName が null なら、original を使う。 149 String newNm = StringUtil.nvalAdd( prefix, StringUtil.coalesce( newName,original ) ); 150 151 if( newNm == null || newNm.isEmpty() ) { 152 final String errMsg = "新ファイル名が存在しません。[" + newNm + "]" ; 153 throw new OgRuntimeException( errMsg ); 154 } 155 156 // 新ファイル名から拡張子取得 157 final String newExt = FileInfo.getSUFIX( newNm ); // 6.2.3.0 (2015/05/01) 158 if( newExt == null || newExt.isEmpty() ) { // 拡張子なし 159 final String oldExt = FileInfo.getSUFIX( original ); 160 newNm = StringUtil.nvalAdd( newNm , sufix , "." , oldExt ) ; // sufix を入れ込む。 161 } 162 else if( sufix != null ) { // 拡張子あり、sufixあり 163 final StringBuilder buf = new StringBuilder( newNm ); 164 buf.insert( newNm.length()-newExt.length()-1 , sufix ); 165 newNm = buf.toString() ; 166 } 167 168 // 8.0.1.0 (2021/10/29) storageType , bucketName 削除 169 // File newFile = new File( dir,newNm ); 170// final File newFile = HybsFileOperationFactory.create(storage, bucket, dir, newNm ); // 8.0.0.0 171 final File newFile = HybsFileOperationFactory.create(useLocal, dir, newNm ); // 8.0.0.0 172 173 // 5.10.9.0 (2019/03/01) MODIFY 174 // File uniqFile = new File( dir , uniqKey ); // 5.7.1.1 (2013/12/13) アップロードされたファイル 175// final File uniqFile = HybsFileOperationFactory.create(storage, bucket, dir, uniqKey); 176 final File uniqFile = HybsFileOperationFactory.create(useLocal, dir, uniqKey); 177 178 // 5.10.9.0 (2019/03/01) MODIFY HybsFileUtilクラスの利用に変更。 179 FileUtil.renameTo( uniqFile , newFile, useBackup ); // from ⇒ to の順番に指定。 180 181 // (2017/09/22) ADD FILE型をString型に変更したので、getName()をfilenameに設定。 182 filename = newFile.getName(); 183 184 // if( newNm != null && newNm.length() > 0 ) { 185 // 5.9.25.0 (2017/10/06) ADD bluemixクラウドストレージを利用する処理を追加 186// final String storage = HybsSystem.sys( "CLOUD_TARGET"); 187// if(storage != null && storage.length() > 0){ 188// // ストレージに保存 189// final StorageAPI storageApi = StorageAPIFactory.newStorageAPI(storage, HybsSystem.sys("CLOUD_BUCKET"), hsession); 190// storageApi.rename(fileURL, uniqKey, newNm, Boolean.valueOf( useBackup ), hsession); 191// // ファイル名をfilenameに設定する 192// filename = newNm; 193// } else { 194// // 標準のファイル作成 195// // newFile = new File( dir,newNm ); 196// 197// final File uniqFile = new File( dir , uniqKey ); // 5.7.1.1 (2013/12/13) アップロードされたファイル 198// 199// // 6.0.2.4 (2014/10/17) 戻り値は、変更後の新しい File オブジェクト 200// newFile = FileUtil.renameTo( uniqFile, newFile, useBackup ); // from ⇒ to の順番に指定。 201// 202// // 5.7.2.1 (2014/01/17) FileUtil.renameTo の引数の順番を間違えていた。 203// // FileUtil.renameTo( newFile, uniqFile , useBackup ); 204// // FileUtil.renameTo( uniqFile , newFile, useBackup ); // from ⇒ to の順番に指定。 205// // (2017/09/22) ADD FILE型をString型に変更したので、getName()をfilenameに設定。 206// filename = newFile.getName(); 207// } 208 // } 209 // // 5.7.1.1 (2013/12/13) ここの処理が走ることは無いはず。 210 // else { 211 // String errMsg = "新ファイル名が存在しません。[" + newNm + "]" ; 212 // throw new RuntimeException( errMsg ); 213 // } 214 215 // 5.7.2.1 (2014/01/17) FileUtil.renameTo の引数の順番を間違えていた。 216 // 6.0.2.4 (2014/10/17) 戻り値は、変更後の新しい File オブジェクト 217 // 新ファイル名のセットは、すべての処理が完了してから、設定する。 218 // 5.9.25.0 (2017/10/06) DELETE FILE型をString型に変更により、前の処理でfinenameは設定済み 219 return filename; 220 } 221 222 /** 223 * ファイル名(オリジナル)を取得します。 224 * 225 * @return ファイル名(オリジナル) 226 */ 227 public String getOriginalFileName() { 228 return original; 229 } 230 231 /** 232 * 自然比較メソッド 233 * インタフェース Comparable の 実装に関連して、再定義しています。 234 * 登録されたシーケンス(画面の表示順)で比較します。 235 * equals メソッドでは、キーの同一性のみに着目して判定しています。 236 * この比較では、(運用上同一キーは発生しませんが)たとえ同一キーが存在した 237 * としても、その比較値が同じになることを保証していません。 238 * 239 * @param other 比較対象のObject 240 * 241 * @return このオブジェクトが指定されたオブジェクトより小さい場合は負の整数、等しい場合はゼロ、大きい場合は正の整数 242 * @throws ClassCastException 引数が UploadedFile ではない場合 243 * @throws IllegalArgumentException 引数が null の場合 244 */ 245 @Override 246 public int compareTo( final UploadedFile other ) { 247 if( other == null ) { 248 final String errMsg = "引数が、null です。" ; 249 throw new IllegalArgumentException( errMsg ); 250 } 251 252 return uniqKey.compareTo( other.uniqKey ); 253 } 254 255 /** 256 * このオブジェクトと他のオブジェクトが等しいかどうかを示します。 257 * 画面は、画面IDが等しければ、言語や表示順に関係なく同一とみなされます。 258 * GUIInfo は、ユーザー個別に扱われ、そのグループには、key は唯一で、かつ 259 * 同一言語内で扱われるオブジェクトの為、同一とみなします。 260 * 261 * @param object 比較対象の参照オブジェクト 262 * 263 * @return 引数に指定されたオブジェクトとこのオブジェクトが等しい場合は true、そうでない場合は false 264 */ 265 @Override 266 public boolean equals( final Object object ) { 267 // 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 268 return object instanceof UploadedFile && uniqKey.equals( ((UploadedFile)object).uniqKey ) ; 269 } 270 271 /** 272 * オブジェクトのハッシュコード値を返します。 273 * このメソッドは、java.util.Hashtable によって提供されるような 274 * ハッシュテーブルで使用するために用意されています。 275 * equals( Object ) メソッドをオーバーライトした場合は、hashCode() メソッドも 276 * 必ず 記述する必要があります。 277 * この実装では、getKey().hashCode() と同値を返します。 278 * 279 * @return このオブジェクトのハッシュコード値 280 */ 281 @Override 282 public int hashCode() { 283 return uniqKey.hashCode() ; 284 } 285 286 /** 287 * オブジェクトの識別子として,詳細な画面情報を返します。 288 * 289 * @return 詳細な画面情報 290 * @og.rtnNotNull 291 */ 292 @Override 293 public String toString() { 294 final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ) 295 .append( this.getClass().getName() ).append( CR ) 296 .append( " uniqKey :").append( uniqKey ).append( CR ) 297 .append( " filename :").append( filename ).append( CR ) 298 .append( " name :").append( name ).append( CR ) 299 .append( " dir :").append( dir ).append( CR ) 300 .append( " original :").append( original ).append( CR ) 301 .append( " type :").append( type ).append( CR ); 302 return rtn.toString(); 303 } 304}