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.filter;
017
018import org.opengion.fukurou.util.Closer;
019
020import java.io.PrintWriter;
021import java.io.IOException;
022import java.io.OutputStreamWriter;
023import javax.servlet.ServletOutputStream;
024import javax.servlet.http.HttpServletResponseWrapper;
025import javax.servlet.http.HttpServletResponse;
026
027/**
028 * GZIPFilter で使用する、GZIP圧縮されたレスポンスのラッパクラスです。
029 *
030 * @og.group フィルター処理
031 *
032 * @version  4.0
033 * @author   Kazuhiko Hasegawa
034 * @since    JDK5.0,
035 */
036public class GZIPResponseWrapper extends HttpServletResponseWrapper {
037        protected HttpServletResponse origResponse = null;
038        protected ServletOutputStream stream = null;
039        protected PrintWriter writer = null;
040
041        /**
042         * コンストラクター
043         *
044         * @param       response        HttpServletResponseオブジェクト
045         */
046        public GZIPResponseWrapper(final HttpServletResponse response) {
047                super(response);
048                origResponse = response;
049        }
050
051        /**
052         * ServletOutputStream の実体である GZIPResponseStream を作成して返します。
053         *
054         * @return      ServletOutputStreamオブジェクト
055         * @throws IOException オブジェクトの作成に失敗したとき、throw されます。
056         */
057        public ServletOutputStream createOutputStream() throws IOException {
058                return (new GZIPResponseStream(origResponse));
059        }
060
061        /**
062         * 内部ストリーム を クローズします。
063         *
064         */
065        public void finishResponse() {
066                Closer.ioClose( writer );
067                Closer.ioClose( stream );
068        }
069
070        /**
071         * 内部ストリームの flush() メソッドを呼び出します。
072         *
073         */
074        @Override
075        public void flushBuffer() throws IOException {
076                stream.flush();
077        }
078
079        /**
080         * 内部ServletOutputStreamを返します。
081         *
082         * 内部オブジェクトが存在しない場合は、新規に作成します。
083         *
084         * @return      ServletOutputStreamオブジェクト
085         */
086        @Override
087        public ServletOutputStream getOutputStream() throws IOException {
088                if(writer != null) {
089                        throw new IllegalStateException("getWriter() has already been called!");
090                }
091
092                if(stream == null) {
093                        stream = createOutputStream();
094                }
095                return (stream);
096        }
097
098        /**
099         * 内部PrintWriterを返します。
100         *
101         * 内部オブジェクトが存在しない場合は、新規に作成します。
102         *
103         * @return PrintWriterオブジェクト
104         */
105        @Override
106        public PrintWriter getWriter() throws IOException {
107                if(writer != null) {
108                        return (writer);
109                }
110
111                if(stream != null) {
112                        throw new IllegalStateException("getOutputStream() has already been called!");
113                }
114
115                stream = createOutputStream();
116                writer = new PrintWriter(new OutputStreamWriter(stream, "UTF-8"));
117                return (writer);
118        }
119
120        /**
121         * 内部ストリームのデータ長を設定します(何もしません)。
122         *
123         * @param       length  データ長
124         */
125        @Override
126        public void setContentLength(final int length) {
127                // ここでは処理を行いません。
128        }
129}