View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.tomahawk.application.jsp;
20  
21  import javax.servlet.ServletOutputStream;
22  import javax.servlet.http.HttpServletResponse;
23  import javax.servlet.http.HttpServletResponseWrapper;
24  import java.io.*;
25  import java.nio.ByteBuffer;
26  import java.nio.CharBuffer;
27  import java.nio.charset.Charset;
28  import java.nio.charset.CharsetDecoder;
29  
30  /**
31   * @since 1.1.7
32   * @author Bruno Aranda (latest modification by $Author: lu4242 $)
33   * @version $Revision: 691871 $ $Date: 2008-09-03 23:32:08 -0500 (Wed, 03 Sep 2008) $
34   */
35  public class ViewResponseWrapper extends HttpServletResponseWrapper
36  {
37      private PrintWriter _writer;
38      private CharArrayWriter _charArrayWriter;
39      private int _status = HttpServletResponse.SC_OK;
40      private WrappedServletOutputStream _byteArrayWriter;
41  
42      public ViewResponseWrapper(HttpServletResponse httpServletResponse)
43      {
44          super(httpServletResponse);
45      }
46  
47      @Override
48      public void sendError(int status) throws IOException
49      {
50          super.sendError(status);
51          _status = status;
52      }
53  
54      @Override
55      public void sendError(int status, String errorMessage) throws IOException
56      {
57          super.sendError(status, errorMessage);
58          _status = status;
59      }
60  
61      @Override
62      public void setStatus(int status)
63      {
64          super.setStatus(status);
65          _status = status;
66      }
67  
68      @Override
69      public void setStatus(int status, String errorMessage)
70      {
71          super.setStatus(status, errorMessage);
72          _status = status;
73      }
74  
75      public int getStatus()
76      {
77          return _status;
78      }
79  
80      public void flushToWrappedResponse() throws IOException
81      {
82          if (_charArrayWriter != null)
83          {
84              _charArrayWriter.writeTo(getResponse().getWriter());
85              _charArrayWriter.reset();
86              _writer.flush();
87          }
88          else if (_byteArrayWriter != null)
89          {
90              getResponse().getOutputStream().write(_byteArrayWriter.toByteArray());
91              _byteArrayWriter.reset();
92              _byteArrayWriter.flush();
93          }
94      }
95  
96      public void flushToWriter(Writer writer,String encoding) throws IOException
97      {
98          if (_charArrayWriter != null)
99          {
100             _charArrayWriter.writeTo(writer);
101             _charArrayWriter.reset();
102             _writer.flush();
103         }
104         else if (_byteArrayWriter != null)
105         {
106             _byteArrayWriter.writeTo(writer,encoding);
107             _byteArrayWriter.reset();
108             _byteArrayWriter.flush();
109         }
110         writer.flush();
111     }
112 
113     @Override
114     public ServletOutputStream getOutputStream() throws IOException
115     {
116         if (_charArrayWriter != null) throw new IllegalStateException();
117         if (_byteArrayWriter == null)
118         {
119             _byteArrayWriter = new WrappedServletOutputStream();
120         }
121         return _byteArrayWriter;
122     }
123 
124     @Override
125     public PrintWriter getWriter() throws IOException
126     {
127         if (_byteArrayWriter != null) throw new IllegalStateException();
128         if (_writer == null)
129         {
130             _charArrayWriter = new CharArrayWriter(4096);
131             _writer = new PrintWriter(_charArrayWriter);
132         }
133         return _writer;
134     }
135 
136     @Override
137     public void reset()
138     {
139         if (_charArrayWriter != null)
140         {
141             _charArrayWriter.reset();
142         }
143     }
144 
145     @Override
146     public String toString()
147     {
148         if (_charArrayWriter != null)
149         {
150             return _charArrayWriter.toString();
151         }
152         return null;
153     }
154 
155     static class WrappedServletOutputStream extends ServletOutputStream
156     {
157         private WrappedByteArrayOutputStream _byteArrayOutputStream;
158 
159 
160         public WrappedServletOutputStream()
161         {
162             _byteArrayOutputStream = new WrappedByteArrayOutputStream(1024);
163         }
164 
165         public void write(int i) throws IOException
166         {
167             _byteArrayOutputStream.write(i);
168         }
169 
170         public byte[] toByteArray()
171         {
172             return _byteArrayOutputStream.toByteArray();
173         }
174         
175         /**
176          * Write the data of this stream to the writer, using
177          * the charset encoding supplied or if null the default charset.
178          * 
179          * @param out
180          * @param encoding
181          * @throws IOException
182          */
183         private void writeTo(Writer out, String encoding) throws IOException{
184             //Get the charset based on the encoding or return the default if 
185             //encoding == null
186             Charset charset = (encoding == null) ? 
187                     Charset.defaultCharset() : Charset.forName(encoding);
188             CharsetDecoder decoder = charset.newDecoder();
189             CharBuffer decodedBuffer = decoder.decode(
190                     ByteBuffer.wrap(_byteArrayOutputStream.getInnerArray(),
191                             0,_byteArrayOutputStream.getInnerCount()));
192             if (decodedBuffer.hasArray()){
193                 out.write(decodedBuffer.array());
194             }
195         }
196 
197         public void reset()
198         {
199             _byteArrayOutputStream.reset();
200         }
201         
202         /**
203          * This Wrapper is used to provide additional methods to 
204          * get the buf and count variables, to use it to decode
205          * in WrappedServletOutputStream.writeTo and avoid buffer
206          * duplication.
207          */
208         static class WrappedByteArrayOutputStream extends ByteArrayOutputStream{
209             
210             public WrappedByteArrayOutputStream(){
211                 super();
212             }
213             
214             public WrappedByteArrayOutputStream(int size){
215                 super(size);                
216             }
217             
218             private byte[] getInnerArray(){
219                 return buf; 
220             }
221             
222             private int getInnerCount(){
223                 return count;
224             }
225         }
226 
227     }
228 }