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.Closer; 019 020 import java.io.ByteArrayOutputStream; 021 import java.io.IOException; 022 023 import java.util.zip.GZIPOutputStream; 024 import javax.servlet.ServletOutputStream; 025 import javax.servlet.http.HttpServletResponse; 026 027 /** 028 * GZIPFilter で使用する、GZIP圧縮するServletOutputStreamクラスです? 029 * 030 * @og.group フィルター処? 031 * 032 * @version 4.0 033 * @author Kazuhiko Hasegawa 034 * @since JDK5.0, 035 */ 036 public class GZIPResponseStream extends ServletOutputStream { 037 /** ?出力ストリー?*/ 038 protected ByteArrayOutputStream baos = null; 039 /** GZIP出力ストリー?*/ 040 protected GZIPOutputStream gzipstream = null; 041 /** クローズ判?*/ 042 protected boolean isClosed = false; 043 /** レスポンスオブジェク?*/ 044 protected HttpServletResponse response = null; 045 /** サーブレ?出力ストリー?*/ 046 protected ServletOutputStream output = null; 047 048 /** 049 * コンストラクター 050 * 051 * @param response HttpServletResponseオブジェク? 052 * @throws IOException 053 */ 054 public GZIPResponseStream(final HttpServletResponse response) throws IOException { 055 // 4.3.4.4 (2009/01/01) 056 // super(); 057 isClosed = false; 058 this.response = response; 059 this.output = response.getOutputStream(); 060 baos = new ByteArrayOutputStream(); 061 gzipstream = new GZIPOutputStream(baos); 062 } 063 064 /** 065 * こ?ストリー?閉じ、このストリー?関連するすべてのシス?リソースを解放します? 066 * 067 * close の汎用規?は、close は出力ストリー?閉じます?閉じられたストリー?? 068 * 出力??実行できません。また?それを開き直すことはできません? 069 * 070 * @og.rev 5.1.7.0 (2010/06/01) isClosed == true の場合に Exception でなく?return にする? 071 * 072 * @throws IOException 073 */ 074 @Override 075 public void close() throws IOException { 076 if(isClosed) { 077 // throw new IOException("This output stream has already been closed"); 078 return ; 079 } 080 try { 081 gzipstream.finish(); 082 083 byte[] bytes = baos.toByteArray(); 084 085 // response.addHeader("Content-Length", Integer.toString(bytes.length)); 086 response.setContentLength( bytes.length ); 087 // System.out.println( bytes.length ); 088 response.addHeader("Content-Encoding", "gzip"); 089 output.write(bytes); 090 output.flush(); 091 } 092 finally { 093 isClosed = true; 094 Closer.ioClose( output ); 095 } 096 } 097 098 /** 099 * こ?出力ストリー?フラ?ュし?バッファに入って?出力バイトをすべて強制?き込みますに? 100 * 101 * flush の汎用規?は、それまでに書き込まれたバイトが出力ストリー?? 102 * 実?よってバッファに入れられて?場合に flush を呼び出すと、それらのバイト? 103 * ただちにそ?目??転送?に書き込まれます? 104 * 105 * @og.rev 5.1.7.0 (2010/06/01) isClosed == true の場合に Exception でなく?return にする? 106 * 107 * @throws IOException 108 */ 109 @Override 110 public void flush() throws IOException { 111 if(isClosed) { 112 // throw new IOException("Cannot flush a closed output stream"); 113 return ; 114 } 115 gzipstream.flush(); 116 } 117 118 /** 119 * こ?出力ストリー??されたバイトを書き込みます? 120 * 121 * write の汎用規?は? バイトが 122 * 出力ストリー?書き込まれます?書き込まれるバイト?、引数 b の下?8 ビットです? 123 * b の上?24 ビット?無視されます? 124 * 125 * @og.rev 5.1.7.0 (2010/06/01) isClosed == true の場合に Exception でなく?return にする? 126 * 127 * @param bt byte??タ 128 * @throws IOException 129 */ 130 @Override 131 public void write(final int bt) throws IOException { 132 if(isClosed) { 133 // throw new IOException("Cannot write to a closed output stream"); 134 return ; 135 } 136 gzipstream.write((byte)bt); 137 } 138 139 /** 140 * ?されたバイト?列からこの出力ストリー? b.length バイトを書き込みます? 141 * 142 * write(b) の汎用規?は、write(b) の効果? write(b, 0, b.length) を呼び出? 143 * 場合とまったく同じです? 144 * 145 * @param bt バイト?? 146 * @throws IOException 147 */ 148 @Override 149 public void write(final byte[] bt) throws IOException { 150 write(bt, 0, bt.length); 151 } 152 153 /** 154 * オフセ? off から始まる指定?バイト?列からこの出力ストリー? len バイトを書き込みます? 155 * 156 * write(b, off, len) の汎用規?は???b ????バイトが出力ストリー??に 157 * 書き込まれます?こ?処???に書き込まれるバイト?要?b[off]、最後に書き込まれる 158 * バイト?要?b[off+len-1] です? 159 * 160 * @og.rev 5.1.7.0 (2010/06/01) isClosed == true の場合に Exception でなく?return にする? 161 * 162 * @param bt バイト?? 163 * @param off オフセ?数 164 * @param len 書き込みバイト数 165 * @throws IOException 166 */ 167 @Override 168 public void write(final byte bt[], final int off, final int len) throws IOException { 169 // System.out.println("writing..."); 170 if(isClosed) { 171 // throw new IOException("Cannot write to a closed output stream"); 172 return ; 173 } 174 gzipstream.write(bt, off, len); 175 } 176 177 /** 178 * すでにストリー?閉じられて?かど?を返します? 179 * 180 * @return すでにストリー?閉じられて?かど? 181 */ 182 public boolean closed() { 183 return isClosed; 184 } 185 }