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.multipart;
017
018import org.opengion.fukurou.util.Closer ;
019
020import java.io.File;
021import java.io.InputStream;
022import java.io.OutputStream;
023import java.io.BufferedOutputStream;
024import java.io.FileOutputStream;
025import java.io.IOException;
026import javax.servlet.ServletInputStream;
027
028/**
029 * ファイルアップロード時のマルチパート処理のファイルパート部品です。
030 *
031 * ファイル情報を取り扱います。
032 *
033 * @og.group その他機能
034 *
035 * @version  4.0
036 * @author   Kazuhiko Hasegawa
037 * @since    JDK5.0,
038 */
039public class FilePart extends Part {
040
041        private String filename;
042        private final String filePath;
043        private final String contentType;
044        private final PartInputStream partInput;
045
046        /**
047         * ファイルパート部品 オブジェクトを構築する、コンストラクター
048         *
049         * @param       name            Part名称
050         * @param       in                      ServletInputStreamオブジェクト
051         * @param       boundary        境界文字
052         * @param       contentType     コンテンツタイプ
053         * @param       filename        ファイル名
054         * @param       filePath        ファイルパス
055         * @throws IOException 入出力エラーが発生したとき
056         */
057        FilePart( final String name, final ServletInputStream in, final String boundary,
058                        final String contentType, final String filename, final String filePath)
059                                                                                        throws IOException {
060                super(name);
061                this.filename = filename;
062                this.filePath = filePath;
063                this.contentType = contentType;
064                partInput = new PartInputStream(in, boundary);
065        }
066
067        /**
068         * ファイル名を取得します。
069         *
070         * @return      ファイル名
071         */
072        public String getFilename() {
073                return filename;
074        }
075
076        /**
077         * ファイル名をセットします。
078         *
079         * @param  fname ファイル名
080         */
081        public void setFilename( final String fname ) {
082                filename = fname ;
083        }
084
085        /**
086         * ファイルパスを取得します。
087         *
088         * @return      ファイルパス
089         */
090        public String getFilePath() {
091                return filePath;
092        }
093
094        /**
095         * コンテンツタイプを取得します。
096         *
097         * @return      コンテンツタイプ
098         */
099        public String getContentType() {
100                return contentType;
101        }
102
103        /**
104         * 入力ストリームを取得します。
105         *
106         * @return      入力ストリーム
107         */
108        public InputStream getInputStream() {
109                return partInput;
110        }
111
112        /**
113         * 指定のファイルに書き出します。
114         *
115         * @param       fileOrDirectory 出力先ファイル名/ディレクトリ名
116         *
117         * @return      ストリームに書き出したバイト数
118         * @throws  IOException 入出力エラーが発生したとき
119         */
120        public long writeTo( final File fileOrDirectory ) throws IOException {
121                long written = 0;
122
123                OutputStream fileOut = null;
124                try {
125                        // Only do something if this part contains a file
126                        if(filename != null) {
127                                // Check if user supplied directory
128                                File file;
129                                if(fileOrDirectory.isDirectory()) {
130                                        // Write it to that dir the user supplied,
131                                        // with the filename it arrived with
132                                        file = new File(fileOrDirectory, filename);
133                                }
134                                else {
135                                        // Write it to the file the user supplied,
136                                        // ignoring the filename it arrived with
137                                        file = fileOrDirectory;
138                                }
139                                fileOut = new BufferedOutputStream(new FileOutputStream(file));
140                                written = write(fileOut);
141                        }
142                }
143                finally {
144                        Closer.ioClose( fileOut );              // 4.0.0 (2006/01/31) close 処理時の IOException を無視
145                }
146                return written;
147        }
148
149        /**
150         * 指定のストリームに書き出します。
151         *
152         * @param       out     OutputStreamオブジェクト
153         *
154         * @return      ストリームに書き出したバイト数
155         * @throws  IOException 入出力エラーが発生したとき
156         */
157        long write( final OutputStream out ) throws IOException {
158                // decode macbinary if this was sent
159                long size=0;
160                int read;
161                byte[] buf = new byte[8 * 1024];
162                while((read = partInput.read(buf)) != -1) {
163                        out.write(buf, 0, read);
164                        size += read;
165                }
166                return size;
167        }
168
169        /**
170         * ファイルかどうか
171         *
172         * @return      (常に true)
173         */
174        @Override
175        public boolean isFile() {
176                return true;
177        }
178}