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     */
016    package org.opengion.hayabusa.servlet;
017    
018    import java.io.File;
019    import java.io.IOException;
020    
021    /**
022     * ファイルをサーバ?にア??ロードする?合に使用されるファイル管?ラスです?
023     * HTML5 ファイルア??ロード??選択?ultiple?対?に伴???のクラスとして public化します?
024     *
025     * @og.group そ?他機?
026     * @og.rev 5.7.1.1 (2013/12/13) HTML5 ファイルア??ロード??選択?ultiple?対?
027     *
028     * @version  4.0
029     * @author       Kazuhiko Hasegawa
030     * @since    JDK5.0,
031     */
032    public final class UploadedFile implements Comparable<UploadedFile> {
033    
034            /** バッファの初期容量を通常より多い目に設定します?  {@value}  */
035            public static final int BUFFER_MIDDLE = 200;
036    
037            /** シス?依存?改行記号をセ?します?     */
038            public static final String CR = System.getProperty("line.separator");
039    
040            private String filename = null;         // 現時点での置き換え後ファイル?
041    
042            private final String uniqKey ;          // ア??ロードされたファイル?ユニ?クにしておきま?
043            private final String dir;
044            private final String name;
045            private final String original;
046            private final String type;
047    
048            /**
049             * ア??ロードファイルの管?ブジェクトを作?します?
050             *
051             * @og.rev 5.7.1.1 (2013/12/13) HTML5 ファイルア??ロード??選択?ultiple?対?
052             *
053             * @param       uniqKey         ユニ?クキー(初期ア??ロードファイル?
054             * @param       dir                     ファイルを保管するフォル?
055             * @param       name            ファイルア??ロードされた時?name属?
056             * @param       original        ファイル?オリジナル)
057             * @param       type    コン?トタイ?
058             */
059    //      UploadedFile( final String dir, final String name, final String filename, final String original, final String type) {
060            UploadedFile( final String uniqKey, final String dir, final String name, final String original, final String type ) {
061                    this.uniqKey    = uniqKey;              // 5.7.1.1 (2013/12/13) uniqKey を確定させる?
062                    this.dir                = dir;
063                    this.name               = name;
064    //              this.filename   = filename;
065                    this.original   = original;
066                    this.type               = type;
067            }
068    
069            /**
070             * ファイルア??ロードされた時?name属?を取得します?
071             *
072             * @og.rev 5.7.1.1 (2013/12/13) HTML5 ファイルア??ロード??選択?ultiple?対?
073             *
074             * @return      ファイルア??ロードされた時?name属?
075             */
076            public String getName() {
077                    return name;
078            }
079    
080            /**
081             * コン?トタイプを取得します?
082             *
083             * @return      コン?トタイ?
084             */
085            public String getContentType() {
086                    return type;
087            }
088    
089            /**
090             * ファイル?置き換え?を取得します?
091             *
092             * @return      ファイル?置き換え?
093             */
094            public String getFilesystemName() {
095                    return filename;
096            }
097    
098            /**
099             * ファイル?置き換え?の置き換えを実行します?
100             * useBackup = true にすると、dir の直下に?_backup" フォル?作?します?
101             * バックア??ファイル名?、?のファイル?拡張子含? ??"_" + 現在時刻のlong値 + "." + ??ファイルの拡張?
102             *
103             * newName ?null の場合?、original のファイル名に、変換します?
104             *
105             * @og.rev 5.7.1.1 (2013/12/13) 新規追?
106             *
107             * @param       newName         ファイル?置き換え?
108             * @param       useBackup       置き換え後ファイルをバ?ア??するかど?(true:バックア??する/false:しな?
109             */
110            public void renameTo( final String newName , final boolean useBackup ) {
111                    String newNm = newName ;
112                    // 新規ファイル名を作?します?(拡張子?
113                    if( newNm != null && newNm.length() > 0 ) {
114                            // 新ファイル名から拡張子取?
115                            String newExt = getExtension( newNm );
116                            if( newExt == null || newExt.length() == 0 ) {
117                                    String oldExt = getExtension( original );
118                                    newNm = newNm + "." + oldExt ;
119                            }
120                    }
121                    else {
122                            newNm = original;
123                    }
124    
125                    if( newNm != null && newNm.length() > 0 ) {
126                            File newFile = new File( dir,newNm );
127                            // 置き換えファイルの存在チェ??
128                            if( newFile.exists() ) {
129                                    if( useBackup ) {
130                                            // newNm にフォル?層を含??合に、そなえて?
131                                            File parent = newFile.getParentFile();                  // バックア??すべきファイルのフォル?
132                                            File backup = new File( parent , "_backup" );   // そ?直下に?_backup" フォル?作?
133                                            if( !backup.exists() && !backup.mkdirs() ) {
134                                                    String errMsg = "バックア??処?backupフォル??作?に失敗しました?" + backup + "]";
135                                                    throw new RuntimeException( errMsg );
136                                            }
137                                            // バックア??ファイル名?、?のファイル?拡張子含? ??"_" + 現在時刻のlong値 + "." + ??ファイルの拡張?
138                                            String bkupName = newFile.getName() + "_" + System.currentTimeMillis() + "."  + getExtension( newNm ) ;
139                                            File fromFile = new File( dir,newNm );          // オリジナルの newFile をrename するとまずいので、同名?Fileオブジェクトを作?
140                                            File bkupFile = new File( backup,bkupName );
141    
142                                            if( !fromFile.renameTo( bkupFile ) ) {
143                                                    String errMsg = "バックア??処?バックア??ファイルをリネ??きませんでした? +CR
144                                                                                             + "  [" + fromFile + "] ?[" + bkupFile + "]" ;
145                                                    throw new RuntimeException( errMsg );
146                                            }
147                                    }
148                                    else if( !newFile.delete() ) {
149                                            String errMsg = "既存?ファイル[" + newNm + "]が削除できませんでした?;
150                                            throw new RuntimeException( errMsg );
151                                    }
152                            }
153    
154                            File uniqFile = new File( dir + File.separator + uniqKey );             // 5.7.1.1 (2013/12/13) ア??ロードされたファイル
155                            if( !uniqFile.renameTo( newFile ) ) {
156                                    String errMsg = "??ファイルをリネ??きませんでした? + CR
157                                                                            + "  [" + uniqFile + "] ?[" + newFile + "]" ;
158                                    throw new RuntimeException( errMsg );
159                            }
160                    }
161                    // 5.7.1.1 (2013/12/13) ここの処?走ることは無??ず?
162                    else {
163                            String errMsg = "新ファイル名が存在しません?" + newNm + "]" ;
164                            throw new RuntimeException( errMsg );
165                    }
166                    // 新ファイル名?セ?は、すべての処?完?てから、設定する?
167                    filename = newNm ;
168            }
169    
170            /**
171             * ファイル?置き換え?をセ?します?
172             *
173             * @og.rev 5.7.1.1 (2013/12/13) ?
174             *
175             * @param       name    ファイル?置き換え?
176             */
177    //      public void setFilesystemName( final String name ) {
178    //              filename = name;
179    //      }
180    
181            /**
182             * ファイル?オリジナル)を取得します?
183             *
184             * @return      ファイル?オリジナル)
185             */
186            public String getOriginalFileName() {
187                    return original;
188            }
189    
190            /**
191             * ファイル?置き換え?の File オブジェクトを取得します?
192             *
193             * @og.rev 5.7.1.1 (2013/12/13) ??
194             *
195             * @return Fileオブジェク?
196             */
197    //      public File getFile() {
198    //              if(dir == null || filename == null) {
199    //                      return null;
200    //              }
201    //              else {
202    //                      return new File(dir + File.separator + filename);
203    //              }
204    //      }
205    
206            /**
207             * ファイル名か?拡張子を取得します?
208             *
209             * @og.rev 5.7.1.1 (2013/12/13) ローカルに移動?若干のロジ?変更
210             *
211             * @param       fileName        ファイル?
212             * @return      拡張?
213             */
214            private String getExtension( final String fileName ) {
215                    int index = fileName.lastIndexOf('.');
216    //              if(index!=-1) {
217    //                      return fileName.substring(index + 1, fileName.length());
218    //              }
219                    if( index >= 0 ) {
220                            return fileName.substring( index + 1 );
221                    }
222                    return "";
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                            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                    if( object instanceof UploadedFile ) {
262                            return uniqKey.equals( ((UploadedFile)object).uniqKey );
263                    }
264    
265                    return false ;
266            }
267    
268            /**
269             * オブジェクト?ハッシュコード?を返します?
270             * こ?メソ?は、java.util.Hashtable によって提供されるような
271             * ハッシュ??ブルで使用するために用意されて?す?
272             * equals( Object ) メソ?をオーバ?ライトした?合?、hashCode() メソ??
273             * ? 記述する?があります?
274             * こ?実?は、getKey().hashCode() と同?を返します?
275             *
276             * @return  こ?オブジェクト?ハッシュコード?
277             */
278            @Override
279            public int hashCode() {
280                    return uniqKey.hashCode() ;
281            }
282    
283            /**
284             * オブジェクト?識別子として?詳細な画面??を返します?
285             *
286             * @return  詳細な画面??
287             */
288            @Override
289            public String toString() {
290                    StringBuilder rtn = new StringBuilder( BUFFER_MIDDLE );
291                    rtn.append( this.getClass().getName()                   ).append( CR );
292                    rtn.append( "  uniqKey  :").append( uniqKey             ).append( CR );
293                    rtn.append( "  filename :").append( filename    ).append( CR );
294                    rtn.append( "  name     :").append( name                ).append( CR );
295                    rtn.append( "  dir      :").append( dir                 ).append( CR );
296                    rtn.append( "  original :").append( original    ).append( CR );
297                    rtn.append( "  type     :").append( type                ).append( CR );
298                    return rtn.toString();
299            }
300    }