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