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