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