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.system.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        /** オリジナルのレスポンス */
038        protected HttpServletResponse origResponse      ;
039        /** アウトプットストリーム */
040        protected ServletOutputStream stream            ;
041        /** プリントライター */
042        protected PrintWriter writer                            ;
043
044        /**
045         * コンストラクター
046         *
047         * @param       response        HttpServletResponseオブジェクト
048         */
049        public GZIPResponseWrapper(final HttpServletResponse response) {
050                super(response);
051                origResponse = response;
052        }
053
054        /**
055         * ServletOutputStream の実体である GZIPResponseStream を作成して返します。
056         *
057         * @return      ServletOutputStreamオブジェクト
058         * @og.rtnNotNull
059         * @throws IOException オブジェクトの作成に失敗したとき、throw されます。
060         */
061        public ServletOutputStream createOutputStream() throws IOException {
062                return new GZIPResponseStream(origResponse);
063        }
064
065        /**
066         * 内部ストリーム を クローズします。
067         *
068         */
069        public void finishResponse() {
070                Closer.ioClose( writer );
071                Closer.ioClose( stream );
072        }
073
074        /**
075         * 内部ストリームの flush() メソッドを呼び出します。
076         *
077         * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
078         */
079        @Override
080        public void flushBuffer() throws IOException {
081                if( stream != null ) {
082                        stream.flush();
083                }
084        }
085
086        /**
087         * 内部ServletOutputStreamを返します。
088         *
089         * 内部オブジェクトが存在しない場合は、新規に作成します。
090         *
091         * @return      ServletOutputStreamオブジェクト
092         */
093        @Override
094        public ServletOutputStream getOutputStream() throws IOException {
095                if( writer != null ) {
096                        throw new IllegalStateException("getWriter() has already been called!");
097                }
098
099                if( stream == null ) {
100                        stream = createOutputStream();
101                }
102                return stream;
103        }
104
105        /**
106         * 内部PrintWriterを返します。
107         *
108         * 内部オブジェクトが存在しない場合は、新規に作成します。
109         *
110         * @return PrintWriterオブジェクト
111         */
112        @Override
113        public PrintWriter getWriter() throws IOException {
114                if( writer != null ) {
115                        return writer;
116                }
117
118                if( stream != null ) {
119                        throw new IllegalStateException("getOutputStream() has already been called!");
120                }
121
122                stream = createOutputStream();
123                writer = new PrintWriter(new OutputStreamWriter(stream, "UTF-8"));
124                return writer;
125        }
126
127        /**
128         * 内部ストリームのデータ長を設定します(何もしません)。
129         *
130         * @param       length  データ長
131         */
132        @Override
133        public void setContentLength(final int length) {
134                // ここでは処理を行いません。
135        }
136}