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