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