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.filter;
017
018 import org.opengion.fukurou.util.FileUtil;
019 import org.opengion.fukurou.util.Closer;
020
021 import java.io.PrintWriter;
022 import java.io.BufferedOutputStream;
023 import java.io.FileOutputStream;
024 import java.io.IOException;
025 import java.io.File;
026 import java.io.ByteArrayOutputStream;
027 import javax.servlet.ServletOutputStream;
028 import javax.servlet.ServletResponse;
029
030 /**
031 * FileFilter で使用する、File圧縮するServletOutputStreamクラスですã?
032 *
033 * @og.group フィルター処ç�?
034 *
035 * @version 4.0
036 * @author Kazuhiko Hasegawa
037 * @since JDK5.0,
038 */
039 public class FileResponseStream extends ServletOutputStream {
040 /** å†?ƒ¨出力ストリーãƒ?*/
041 protected ByteArrayOutputStream filestream = null;
042 /** クローズ判å®?*/
043 protected boolean isClosed = false;
044 /** レスポンスオブジェクãƒ?*/
045 // protected ServletResponse response = null; // 5.5.2.6 (2012/05/25)
046 /** サーブレãƒ?ƒˆ出力ストリーãƒ?*/
047 protected ServletOutputStream output = null;
048
049 private final String filename ;
050
051 /**
052 * コンストラクター
053 *
054 * @param response レスポンス
055 * @param filename ファイルå�?
056 * @throws IOException 入出力エラーが発生したとã�?
057 */
058 public FileResponseStream( final ServletResponse response,final String filename ) throws IOException {
059 // 4.3.4.4 (2009/01/01)
060 // super();
061 this.filename = filename;
062 isClosed = false;
063 // this.response = response; // 5.5.2.6 (2012/05/25)
064 this.output = response.getOutputStream();
065 filestream = new ByteArrayOutputStream();
066 }
067
068 /**
069 * こã?ストリーãƒ?‚’閉じ、このストリーãƒ?�«関連するすべてのシスãƒ?ƒ リソースを解放しますã?
070 *
071 * close の汎用規ç´?�§は、close は出力ストリーãƒ?‚’閉じますã?閉じられたストリーãƒ??
072 * 出力å?ç�?‚’実行できません。またã?それを開き直すことはできませんã€?
073 *
074 * @og.rev 5.6.4.2 (2013/05/17) fileDownload のエンコードã?、UTF-8 ではなくã?UnicodeLittle でセーブするã?
075 *
076 * @throws IOException 入出力エラーが発生したとã�?
077 */
078 @Override
079 public void close() throws IOException {
080 if(isClosed) {
081 // System.out.println( "already been closed !" );
082 // throw new IOException("This output stream has already been closed");
083 return ;
084 }
085 try {
086 filestream.flush();
087
088 // 5.6.4.2 (2013/05/17) ファイル名が fileDownload で始まるå?合ã?、Streamのままセーブするã?
089 if( filename.indexOf( "fileDownload:" ) >= 0 ) {
090 BufferedOutputStream toStream = new BufferedOutputStream( new FileOutputStream( filename.replace( "fileDownload:","" ) ) );
091 filestream.writeTo( toStream );
092 Closer.ioClose( toStream );
093 }
094 else {
095 String msg = filestream.toString( "UTF-8" );
096 FileResponseTransform trans = new FileResponseTransform();
097 msg = trans.replace( filename,msg );
098
099 PrintWriter writer = FileUtil.getPrintWriter( new File( filename ), "UTF-8" );
100 writer.print( msg );
101 Closer.ioClose( writer );
102 }
103 System.out.println( filename + " Saved" );
104
105 output.flush();
106 }
107 catch( Throwable th ) {
108 System.out.println( filename + " Error! " + th );
109 }
110 finally {
111 isClosed = true;
112 Closer.ioClose( filestream );
113 Closer.ioClose( output );
114 }
115 }
116
117 /**
118 * こã?出力ストリーãƒ?‚’フラãƒ?‚·ュしã?バッファに入ってã�?‚‹出力バイトをすべて強制çš?›¸き込みますにã€?
119 *
120 * flush の汎用規ç´?�§は、それまでに書き込まれたバイトが出力ストリーãƒ??
121 * 実è£?�«よってバッファに入れられてã�?‚‹場合に flush を呼び出すと、それらのバイトã?
122 * ただちにそã?目çš??転送å?に書き込まれますã?
123 *
124 * @og.rev 5.1.7.0 (2010/06/01) isClosed == true の場合に Exception でなくã?return にするã€?
125 * @throws IOException 入出力エラーが発生したとã�?
126 */
127 @Override
128 public void flush() throws IOException {
129 if(isClosed) {
130 // throw new IOException("Cannot flush a closed output stream");
131 return ;
132 }
133 filestream.flush();
134 output.flush();
135 }
136
137 /**
138 * こã?出力ストリーãƒ?�«æŒ?®šされたバイトを書き込みますã?
139 *
140 * write の汎用規ç´?�§はã€? バイトが
141 * 出力ストリーãƒ?�«書き込まれますã?書き込まれるバイトã?、引数 b の下ä½?8 ビットですã?
142 * b の上ä½?24 ビットã?無視されますã?
143 *
144 * @og.rev 5.1.7.0 (2010/06/01) isClosed == true の場合に Exception でなくã?return にするã€?
145 *
146 * @param bt byteãƒ??タ
147 * @throws IOException 入出力エラーが発生したとã�?
148 */
149 @Override
150 public void write(final int bt) throws IOException {
151 if(isClosed) {
152 // throw new IOException("Cannot write to a closed output stream");
153 return ;
154 }
155 filestream.write((byte)bt);
156 output.write((byte)bt);
157 }
158
159 /**
160 * æŒ?®šされたバイトé?列からこの出力ストリーãƒ?�« b.length バイトを書き込みますã?
161 *
162 * write(b) の汎用規ç´?�§は、write(b) の効果ã? write(b, 0, b.length) を呼び出ã�?
163 * 場合とまったく同じですã?
164 *
165 * @param bt バイトé?åˆ?
166 * @throws IOException 入出力エラーが発生したとã�?
167 */
168 @Override
169 public void write(final byte[] bt) throws IOException {
170 write(bt, 0, bt.length);
171 }
172
173 /**
174 * オフセãƒ?ƒˆ off から始まる指定ã?バイトé?列からこの出力ストリーãƒ?�« len バイトを書き込みますã?
175 *
176 * write(b, off, len) の汎用規ç´?�§はã€??åˆ?b å†??ä¸?®šã?バイトが出力ストリーãƒ?�«é ?•ªに
177 * 書き込まれますã?こã?処ç�?�§æœ??に書き込まれるバイトã?要ç´?b[off]、最後に書き込まれる
178 * バイトã?要ç´?b[off+len-1] ですã?
179 *
180 * @og.rev 5.1.7.0 (2010/06/01) isClosed == true の場合に Exception でなくã?return にするã€?
181 *
182 * @param bt バイトé?åˆ?
183 * @param off オフセãƒ?ƒˆ数
184 * @param len 書き込みバイト数
185 * @throws IOException 入出力エラーが発生したとã�?
186 */
187 @Override
188 public void write(final byte bt[], final int off, final int len) throws IOException {
189 if(isClosed) {
190 // throw new IOException("Cannot write to a closed output stream");
191 return ;
192 }
193 output.write(bt, off, len);
194 filestream.write(bt, off, len);
195 }
196
197 /**
198 * すでにストリーãƒ?�Œ閉じられてã�?‚‹かどã�?�‹を返しますã?
199 *
200 * @return すでにストリーãƒ?�Œ閉じられてã�?‚‹かどã�?�‹
201 */
202 public boolean closed() {
203 return isClosed;
204 }
205
206 /**
207 * Checks if a non-blocking write will succeed. If this returns
208 * <code>false</code>, it will cause a callback to
209 * WriteListener#onWritePossible() when the buffer has emptied. If
210 * this method returns <code>false</code> no further data must be written
211 * until the contain calls WriteListener#onWritePossible().
212 *
213 * @og.rev 5.6.8.2 (2013/09/20) 新規追åŠ?Tomcat8 / Servlet 3.1 で追åŠ?�•れた abstract メソãƒ?ƒ‰)
214 *
215 * @return true:書き込み可能/false:不可 (true if data can be written, else false)
216 *
217 * @since Servlet 3.1
218 */
219 //@Override
220 public boolean isReady() { return false; }
221
222 /**
223 * Sets the WriteListener for this ServletOutputStream and
224 * thereby switches to non-blocking IO. It is only valid to switch to
225 * non-blocking IO within async processing or HTTP upgrade processing.
226 *
227 * @og.rev 5.6.8.2 (2013/09/20) 新規追åŠ?Tomcat8 / Servlet 3.1 で追åŠ?�•れた abstract メソãƒ?ƒ‰)
228 *
229 * @param listener The non-blocking IO write listener
230 *
231 * @throws IllegalStateException If this method is called if neither
232 * async nor HTTP upgrade is in progress or
233 * if the WriteListener has already
234 * been set
235 * @throws NullPointerException If listener is null
236 *
237 * @since Servlet 3.1
238 */
239 //@Override
240 // public void setWriteListener( final javax.servlet.WriteListener listener ) {
241 // // 何も実è£?�—なã�??
242 // }
243 }