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