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 018import 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 026import 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 * 131 * @param newName ファイル名(nullの場合は、オリジナル) 132 * @param prefix 接頭辞(nullの場合は、何もつけない) 133 * @param sufix 接尾辞(nullの場合は、何もつけない) 134 * @param useBackup 置き換え後ファイルの処理方法(true:backupフォルダ/false:しない/rename:重複しない連番) 135 * @param fileURL クラウドストレージ用のURL 136// * @param hsession セッション 137 * @param storageType クラウドプラグイン名 138 * @param bucketName バケット名 139 * @return 最終的に作成されたファイルオブジェクト 140 */ 141// public String renameTo( final String newName , final String prefix , final String sufix , final String useBackup, final String fileURL, final HttpSession hsession ) { 142 public String renameTo( final String newName , final String prefix , final String sufix , final String useBackup, final String fileURL, 143 final String storageType, final String bucketName ) { 144 145 // 6.0.2.4 (2014/10/17) prfix が null でなければ、連結。newName が null なら、original を使う。 146 String newNm = StringUtil.nvalAdd( prefix, StringUtil.coalesce( newName,original ) ); 147 148 if( newNm == null || newNm.isEmpty() ) { 149 final String errMsg = "新ファイル名が存在しません。[" + newNm + "]" ; 150 throw new OgRuntimeException( errMsg ); 151 } 152 153 // 新ファイル名から拡張子取得 154 final String newExt = FileInfo.getSUFIX( newNm ); // 6.2.3.0 (2015/05/01) 155 if( newExt == null || newExt.isEmpty() ) { // 拡張子なし 156 final String oldExt = FileInfo.getSUFIX( original ); 157 newNm = StringUtil.nvalAdd( newNm , sufix , "." , oldExt ) ; // sufix を入れ込む。 158 } 159 else if( sufix != null ) { // 拡張子あり、sufixあり 160 final StringBuilder buf = new StringBuilder( newNm ); 161 buf.insert( newNm.length()-newExt.length()-1 , sufix ); 162 newNm = buf.toString() ; 163 } 164 165 // File newFile = new File( dir,newNm ); 166 final File newFile = HybsFileOperationFactory.create(storageType, bucketName, dir, newNm ); // 8.0.0.0 167 168 // 5.10.9.0 (2019/03/01) MODIFY 169 // File uniqFile = new File( dir , uniqKey ); // 5.7.1.1 (2013/12/13) アップロードされたファイル 170 final File uniqFile = HybsFileOperationFactory.create(storageType, bucketName, dir, uniqKey); 171 172 // 5.10.9.0 (2019/03/01) MODIFY HybsFileUtilクラスの利用に変更。 173 FileUtil.renameTo( uniqFile , newFile, useBackup ); // from ⇒ to の順番に指定。 174 175 // (2017/09/22) ADD FILE型をString型に変更したので、getName()をfilenameに設定。 176 filename = newFile.getName(); 177 178 // if( newNm != null && newNm.length() > 0 ) { 179 // 5.9.25.0 (2017/10/06) ADD bluemixクラウドストレージを利用する処理を追加 180// final String storage = HybsSystem.sys( "CLOUD_TARGET"); 181// if(storage != null && storage.length() > 0){ 182// // ストレージに保存 183// final StorageAPI storageApi = StorageAPIFactory.newStorageAPI(storage, HybsSystem.sys("CLOUD_BUCKET"), hsession); 184// storageApi.rename(fileURL, uniqKey, newNm, Boolean.valueOf( useBackup ), hsession); 185// // ファイル名をfilenameに設定する 186// filename = newNm; 187// } else { 188// // 標準のファイル作成 189// // newFile = new File( dir,newNm ); 190// 191// final File uniqFile = new File( dir , uniqKey ); // 5.7.1.1 (2013/12/13) アップロードされたファイル 192// 193// // 6.0.2.4 (2014/10/17) 戻り値は、変更後の新しい File オブジェクト 194// newFile = FileUtil.renameTo( uniqFile, newFile, useBackup ); // from ⇒ to の順番に指定。 195// 196// // 5.7.2.1 (2014/01/17) FileUtil.renameTo の引数の順番を間違えていた。 197// // FileUtil.renameTo( newFile, uniqFile , useBackup ); 198// // FileUtil.renameTo( uniqFile , newFile, useBackup ); // from ⇒ to の順番に指定。 199// // (2017/09/22) ADD FILE型をString型に変更したので、getName()をfilenameに設定。 200// filename = newFile.getName(); 201// } 202 // } 203 // // 5.7.1.1 (2013/12/13) ここの処理が走ることは無いはず。 204 // else { 205 // String errMsg = "新ファイル名が存在しません。[" + newNm + "]" ; 206 // throw new RuntimeException( errMsg ); 207 // } 208 209 // 5.7.2.1 (2014/01/17) FileUtil.renameTo の引数の順番を間違えていた。 210 // 6.0.2.4 (2014/10/17) 戻り値は、変更後の新しい File オブジェクト 211 // 新ファイル名のセットは、すべての処理が完了してから、設定する。 212 // 5.9.25.0 (2017/10/06) DELETE FILE型をString型に変更により、前の処理でfinenameは設定済み 213 return filename; 214 } 215 216 /** 217 * ファイル名(オリジナル)を取得します。 218 * 219 * @return ファイル名(オリジナル) 220 */ 221 public String getOriginalFileName() { 222 return original; 223 } 224 225 /** 226 * 自然比較メソッド 227 * インタフェース Comparable の 実装に関連して、再定義しています。 228 * 登録されたシーケンス(画面の表示順)で比較します。 229 * equals メソッドでは、キーの同一性のみに着目して判定しています。 230 * この比較では、(運用上同一キーは発生しませんが)たとえ同一キーが存在した 231 * としても、その比較値が同じになることを保証していません。 232 * 233 * @param other 比較対象のObject 234 * 235 * @return このオブジェクトが指定されたオブジェクトより小さい場合は負の整数、等しい場合はゼロ、大きい場合は正の整数 236 * @throws ClassCastException 引数が UploadedFile ではない場合 237 * @throws IllegalArgumentException 引数が null の場合 238 */ 239 @Override 240 public int compareTo( final UploadedFile other ) { 241 if( other == null ) { 242 final String errMsg = "引数が、null です。" ; 243 throw new IllegalArgumentException( errMsg ); 244 } 245 246 return uniqKey.compareTo( other.uniqKey ); 247 } 248 249 /** 250 * このオブジェクトと他のオブジェクトが等しいかどうかを示します。 251 * 画面は、画面IDが等しければ、言語や表示順に関係なく同一とみなされます。 252 * GUIInfo は、ユーザー個別に扱われ、そのグループには、key は唯一で、かつ 253 * 同一言語内で扱われるオブジェクトの為、同一とみなします。 254 * 255 * @param object 比較対象の参照オブジェクト 256 * 257 * @return 引数に指定されたオブジェクトとこのオブジェクトが等しい場合は true、そうでない場合は false 258 */ 259 @Override 260 public boolean equals( final Object object ) { 261 // 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 262 return object instanceof UploadedFile && uniqKey.equals( ((UploadedFile)object).uniqKey ) ; 263 } 264 265 /** 266 * オブジェクトのハッシュコード値を返します。 267 * このメソッドは、java.util.Hashtable によって提供されるような 268 * ハッシュテーブルで使用するために用意されています。 269 * equals( Object ) メソッドをオーバーライトした場合は、hashCode() メソッドも 270 * 必ず 記述する必要があります。 271 * この実装では、getKey().hashCode() と同値を返します。 272 * 273 * @return このオブジェクトのハッシュコード値 274 */ 275 @Override 276 public int hashCode() { 277 return uniqKey.hashCode() ; 278 } 279 280 /** 281 * オブジェクトの識別子として,詳細な画面情報を返します。 282 * 283 * @return 詳細な画面情報 284 * @og.rtnNotNull 285 */ 286 @Override 287 public String toString() { 288 final StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE ) 289 .append( this.getClass().getName() ).append( CR ) 290 .append( " uniqKey :").append( uniqKey ).append( CR ) 291 .append( " filename :").append( filename ).append( CR ) 292 .append( " name :").append( name ).append( CR ) 293 .append( " dir :").append( dir ).append( CR ) 294 .append( " original :").append( original ).append( CR ) 295 .append( " type :").append( type ).append( CR ); 296 return rtn.toString(); 297 } 298}