View Javadoc

1   /***
2    * Licensed under the Artistic License; you may not use this file
3    * except in compliance with the License.
4    * You may obtain a copy of the License at
5    *
6    *      http://displaytag.sourceforge.net/license.html
7    *
8    * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
9    * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
10   * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11   */
12  package org.displaytag.filter;
13  
14  import java.io.CharArrayWriter;
15  import java.io.IOException;
16  import java.io.PrintWriter;
17  
18  import javax.servlet.ServletOutputStream;
19  import javax.servlet.http.HttpServletResponse;
20  import javax.servlet.http.HttpServletResponseWrapper;
21  
22  import org.apache.commons.lang.ArrayUtils;
23  import org.apache.commons.lang.StringUtils;
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.displaytag.tags.TableTagParameters;
27  
28  
29  /***
30   * J2ee 1.3 implementation of BufferedResponseWrapper. Need to extend HttpServletResponseWrapper for Weblogic
31   * compatibility.
32   * @author rapruitt
33   * @author Fabrizio Giustina
34   * @version $Revision: 1.4 $ ($Author: fgiust $)
35   */
36  public class BufferedResponseWrapper13Impl extends HttpServletResponseWrapper implements BufferedResponseWrapper
37  {
38  
39      /***
40       * logger.
41       */
42      private static Log log = LogFactory.getLog(BufferedResponseWrapper13Impl.class);
43  
44      /***
45       * The buffered response.
46       */
47      private CharArrayWriter outputWriter;
48  
49      /***
50       * The outputWriter stream.
51       */
52      private SimpleServletOutputStream servletOutputStream;
53  
54      /***
55       * The contentType.
56       */
57      private String contentType;
58  
59      /***
60       * If state is set, allow getOutputStream() to return the "real" output stream, elsewhere returns a internal buffer.
61       */
62      private boolean state;
63  
64      /***
65       * Writer has been requested.
66       */
67      private boolean outRequested;
68  
69      /***
70       * @param httpServletResponse the response to wrap
71       */
72      public BufferedResponseWrapper13Impl(HttpServletResponse httpServletResponse)
73      {
74          super(httpServletResponse);
75          this.outputWriter = new CharArrayWriter();
76          this.servletOutputStream = new SimpleServletOutputStream();
77      }
78  
79      /***
80       * @see org.displaytag.filter.BufferedResponseWrapper#getContentType()
81       */
82      public String getContentType()
83      {
84          return this.contentType;
85      }
86  
87      /***
88       * The content type is NOT set on the wrapped response. You must set it manually. Overrides any previously set
89       * value.
90       * @param theContentType the content type.
91       */
92      public void setContentType(String theContentType)
93      {
94          if (state)
95          {
96              log.debug("Allowing content type");
97  
98              if (this.contentType != null && // content type has been set before
99                  this.contentType.indexOf("charset") > -1) // and it specified charset
100             {
101                 // so copy the charset
102                 String charset = this.contentType.substring(this.contentType.indexOf("charset"));
103                 if (log.isDebugEnabled())
104                 {
105                     log.debug("Adding charset: [" + charset + "]");
106                 }
107 
108                 getResponse().setContentType(StringUtils.substringBefore(theContentType, "charset") + ' ' + charset);
109             }
110             else
111             {
112                 getResponse().setContentType(theContentType);
113             }
114 
115         }
116         this.contentType = theContentType;
117     }
118 
119     /***
120      * @see javax.servlet.ServletResponse#getWriter()
121      */
122     public PrintWriter getWriter() throws IOException
123     {
124 
125         if (state && !outRequested)
126         {
127             log.debug("getWriter() returned");
128 
129             // ok, exporting in progress, discard old data and go on streaming
130             this.servletOutputStream.reset();
131             this.outputWriter.reset();
132             this.outRequested = true;
133             return ((HttpServletResponse) getResponse()).getWriter();
134         }
135 
136         return new PrintWriter(this.outputWriter);
137     }
138 
139     /***
140      * Flush the buffer, not the response.
141      * @throws IOException if encountered when flushing
142      */
143     public void flushBuffer() throws IOException
144     {
145         if (outputWriter != null)
146         {
147             this.outputWriter.flush();
148             this.servletOutputStream.outputStream.reset();
149         }
150     }
151 
152     /***
153      * @see javax.servlet.ServletResponse#getOutputStream()
154      */
155     public ServletOutputStream getOutputStream() throws IOException
156     {
157         if (state && !outRequested)
158         {
159             log.debug("getOutputStream() returned");
160 
161             // ok, exporting in progress, discard old data and go on streaming
162             this.servletOutputStream.reset();
163             this.outputWriter.reset();
164             this.outRequested = true;
165             return ((HttpServletResponse) getResponse()).getOutputStream();
166         }
167         return this.servletOutputStream;
168     }
169 
170     /***
171      * @see javax.servlet.http.HttpServletResponse#addHeader(java.lang.String, java.lang.String)
172      */
173     public void addHeader(String name, String value)
174     {
175         // if the "magic parameter" is set, a table tag is going to call getOutputStream()
176         if (TableTagParameters.PARAMETER_EXPORTING.equals(name))
177         {
178             log.debug("Magic header received, real response is now accessible");
179             state = true;
180         }
181         else
182         {
183             if (!ArrayUtils.contains(FILTERED_HEADERS, StringUtils.lowerCase(name)))
184             {
185                 ((HttpServletResponse) getResponse()).addHeader(name, value);
186             }
187         }
188     }
189 
190     /***
191      * @see org.displaytag.filter.BufferedResponseWrapper#isOutRequested()
192      */
193     public boolean isOutRequested()
194     {
195         return this.outRequested;
196     }
197 
198     /***
199      * @see org.displaytag.filter.BufferedResponseWrapper#getContentAsString()
200      */
201     public String getContentAsString()
202     {
203         return this.outputWriter.toString() + this.servletOutputStream.toString();
204     }
205 
206     /***
207      * @see javax.servlet.http.HttpServletResponse#setDateHeader(java.lang.String, long)
208      */
209     public void setDateHeader(String name, long date)
210     {
211         if (!ArrayUtils.contains(FILTERED_HEADERS, StringUtils.lowerCase(name)))
212         {
213             ((HttpServletResponse) getResponse()).setDateHeader(name, date);
214         }
215     }
216 
217     /***
218      * @see javax.servlet.http.HttpServletResponse#addDateHeader(java.lang.String, long)
219      */
220     public void addDateHeader(String name, long date)
221     {
222         if (!ArrayUtils.contains(FILTERED_HEADERS, StringUtils.lowerCase(name)))
223         {
224             ((HttpServletResponse) getResponse()).addDateHeader(name, date);
225         }
226     }
227 
228     /***
229      * @see javax.servlet.http.HttpServletResponse#setHeader(java.lang.String, java.lang.String)
230      */
231     public void setHeader(String name, String value)
232     {
233         if (!ArrayUtils.contains(FILTERED_HEADERS, StringUtils.lowerCase(name)))
234         {
235             ((HttpServletResponse) getResponse()).setHeader(name, value);
236         }
237     }
238 
239     /***
240      * @see javax.servlet.http.HttpServletResponse#setIntHeader(java.lang.String, int)
241      */
242     public void setIntHeader(String name, int value)
243     {
244         if (!ArrayUtils.contains(FILTERED_HEADERS, StringUtils.lowerCase(name)))
245         {
246             ((HttpServletResponse) getResponse()).setIntHeader(name, value);
247         }
248     }
249 
250     /***
251      * @see javax.servlet.http.HttpServletResponse#addIntHeader(java.lang.String, int)
252      */
253     public void addIntHeader(String name, int value)
254     {
255         if (!ArrayUtils.contains(FILTERED_HEADERS, StringUtils.lowerCase(name)))
256         {
257             ((HttpServletResponse) getResponse()).addIntHeader(name, value);
258         }
259     }
260 
261 }