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 }