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