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  import java.util.Locale;
18  
19  import javax.servlet.ServletOutputStream;
20  import javax.servlet.ServletResponse;
21  import javax.servlet.http.Cookie;
22  import javax.servlet.http.HttpServletResponse;
23  
24  import org.apache.commons.lang.ArrayUtils;
25  import org.apache.commons.lang.StringUtils;
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.displaytag.tags.TableTagParameters;
29  
30  
31  /***
32   * J2ee 1.2 implementation of BufferedResponseWrapper..
33   * @author rapruitt
34   * @author Fabrizio Giustina
35   * @version $Revision: 1.4 $ ($Author: fgiust $)
36   */
37  public class BufferedResponseWrapper12Impl implements BufferedResponseWrapper // don't extend j2ee 1.3
38  // HttpServletResponseWrapper
39  {
40  
41      /***
42       * logger.
43       */
44      private static Log log = LogFactory.getLog(BufferedResponseWrapper12Impl.class);
45  
46      /***
47       * The buffered response.
48       */
49      private CharArrayWriter outputWriter;
50  
51      /***
52       * The outputWriter stream.
53       */
54      private SimpleServletOutputStream servletOutputStream;
55  
56      /***
57       * The contentType.
58       */
59      private String contentType;
60  
61      /***
62       * The wrapped response.
63       */
64      private HttpServletResponse response;
65  
66      /***
67       * If state is set, allow getOutputStream() to return the "real" output stream, elsewhere returns a internal buffer.
68       */
69      private boolean state;
70  
71      /***
72       * Writer has been requested.
73       */
74      private boolean outRequested;
75  
76      /***
77       * @param httpServletResponse the response to wrap
78       */
79      public BufferedResponseWrapper12Impl(HttpServletResponse httpServletResponse)
80      {
81          this.response = httpServletResponse;
82          this.outputWriter = new CharArrayWriter();
83          this.servletOutputStream = new SimpleServletOutputStream();
84      }
85  
86      /***
87       * Returns the wrapped servletResponse.
88       * @return wrapped servletResponse
89       */
90      public ServletResponse getResponse()
91      {
92          return this.response;
93      }
94  
95      /***
96       * @see org.displaytag.filter.BufferedResponseWrapper#getContentType()
97       */
98      public String getContentType()
99      {
100         return this.contentType;
101     }
102 
103     /***
104      * The content type is NOT set on the wrapped response. You must set it manually. Overrides any previously set
105      * value.
106      * @param theContentType the content type.
107      */
108     public void setContentType(String theContentType)
109     {
110         if (state)
111         {
112             log.debug("Allowing content type");
113 
114             if (this.contentType != null && // content type has been set before
115                 this.contentType.indexOf("charset") > -1) // and it specified charset
116             {
117                 // so copy the charset
118                 String charset = this.contentType.substring(this.contentType.indexOf("charset"));
119                 if (log.isDebugEnabled())
120                 {
121                     log.debug("Adding charset: [" + charset + "]");
122                 }
123 
124                 getResponse().setContentType(StringUtils.substringBefore(theContentType, "charset") + ' ' + charset);
125             }
126             else
127             {
128                 getResponse().setContentType(theContentType);
129             }
130 
131         }
132         this.contentType = theContentType;
133     }
134 
135     /***
136      * @see javax.servlet.ServletResponse#getWriter()
137      */
138     public PrintWriter getWriter() throws IOException
139     {
140 
141         if (state && !outRequested)
142         {
143             log.debug("getWriter() returned");
144 
145             // ok, exporting in progress, discard old data and go on streaming
146             this.servletOutputStream.reset();
147             this.outputWriter.reset();
148             this.outRequested = true;
149             return ((HttpServletResponse) getResponse()).getWriter();
150         }
151 
152         return new PrintWriter(this.outputWriter);
153     }
154 
155     /***
156      * Flush the buffer, not the response.
157      * @throws IOException if encountered when flushing
158      */
159     public void flushBuffer() throws IOException
160     {
161         if (outputWriter != null)
162         {
163             this.outputWriter.flush();
164             this.servletOutputStream.outputStream.reset();
165         }
166     }
167 
168     /***
169      * @see javax.servlet.ServletResponse#getOutputStream()
170      */
171     public ServletOutputStream getOutputStream() throws IOException
172     {
173         if (state && !outRequested)
174         {
175             log.debug("getOutputStream() returned");
176 
177             // ok, exporting in progress, discard old data and go on streaming
178             this.servletOutputStream.reset();
179             this.outputWriter.reset();
180             this.outRequested = true;
181             return ((HttpServletResponse) getResponse()).getOutputStream();
182         }
183         return this.servletOutputStream;
184     }
185 
186     /***
187      * @see javax.servlet.http.HttpServletResponse#addHeader(java.lang.String, java.lang.String)
188      */
189     public void addHeader(String name, String value)
190     {
191         // if the "magic parameter" is set, a table tag is going to call getOutputStream()
192         if (TableTagParameters.PARAMETER_EXPORTING.equals(name))
193         {
194             log.debug("Magic header received, real response is now accessible");
195             state = true;
196         }
197         else
198         {
199             if (!ArrayUtils.contains(FILTERED_HEADERS, StringUtils.lowerCase(name)))
200             {
201                 ((HttpServletResponse) getResponse()).addHeader(name, value);
202             }
203         }
204     }
205 
206     /***
207      * @see org.displaytag.filter.BufferedResponseWrapper#isOutRequested()
208      */
209     public boolean isOutRequested()
210     {
211         return this.outRequested;
212     }
213 
214     /***
215      * @see org.displaytag.filter.BufferedResponseWrapper#getContentAsString()
216      */
217     public String getContentAsString()
218     {
219         return this.outputWriter.toString() + this.servletOutputStream.toString();
220     }
221 
222     // -- standard methods --
223 
224     /***
225      * Not available in servlets 2.2. Needed to compile with servlets 2.3.
226      * @see javax.servlet.ServletResponse#resetBuffer()
227      */
228     public void resetBuffer()
229     {
230         // not available in servlets 2.2
231     }
232 
233     /***
234      * @see javax.servlet.ServletResponse#getCharacterEncoding()
235      */
236     public String getCharacterEncoding()
237     {
238         return response.getCharacterEncoding();
239     }
240 
241     /***
242      * @see javax.servlet.ServletResponse#setContentLength(int)
243      */
244     public void setContentLength(int len)
245     {
246         response.setContentLength(len);
247     }
248 
249     /***
250      * @see javax.servlet.ServletResponse#setBufferSize(int)
251      */
252     public void setBufferSize(int size)
253     {
254         response.setBufferSize(size);
255     }
256 
257     /***
258      * @see javax.servlet.ServletResponse#getBufferSize()
259      */
260     public int getBufferSize()
261     {
262         return response.getBufferSize();
263     }
264 
265     /***
266      * @see javax.servlet.ServletResponse#isCommitted()
267      */
268     public boolean isCommitted()
269     {
270         return response.isCommitted();
271     }
272 
273     /***
274      * @see javax.servlet.ServletResponse#reset()
275      */
276     public void reset()
277     {
278         response.reset();
279     }
280 
281     /***
282      * @see javax.servlet.ServletResponse#setLocale(java.util.Locale)
283      */
284     public void setLocale(Locale loc)
285     {
286         response.setLocale(loc);
287     }
288 
289     /***
290      * @see javax.servlet.ServletResponse#getLocale()
291      */
292     public Locale getLocale()
293     {
294         return response.getLocale();
295     }
296 
297     /***
298      * @see javax.servlet.http.HttpServletResponse#addCookie(javax.servlet.http.Cookie)
299      */
300     public void addCookie(Cookie cookie)
301     {
302         response.addCookie(cookie);
303     }
304 
305     /***
306      * @see javax.servlet.http.HttpServletResponse#containsHeader(java.lang.String)
307      */
308     public boolean containsHeader(String name)
309     {
310         return response.containsHeader(name);
311     }
312 
313     /***
314      * @see javax.servlet.http.HttpServletResponse#encodeURL(java.lang.String)
315      */
316     public String encodeURL(String url)
317     {
318         return response.encodeURL(url);
319     }
320 
321     /***
322      * @see javax.servlet.http.HttpServletResponse#encodeRedirectURL(java.lang.String)
323      */
324     public String encodeRedirectURL(String url)
325     {
326         return response.encodeRedirectURL(url);
327     }
328 
329     /***
330      * @see javax.servlet.http.HttpServletResponse#encodeUrl(java.lang.String)
331      * @deprecated
332      */
333     public String encodeUrl(String url)
334     {
335         return response.encodeUrl(url);
336     }
337 
338     /***
339      * @see javax.servlet.http.HttpServletResponse#encodeRedirectUrl(java.lang.String)
340      * @deprecated
341      */
342     public String encodeRedirectUrl(String url)
343     {
344         return response.encodeRedirectUrl(url);
345     }
346 
347     /***
348      * @see javax.servlet.http.HttpServletResponse#sendError(int, java.lang.String)
349      */
350     public void sendError(int sc, String msg) throws IOException
351     {
352         response.sendError(sc, msg);
353     }
354 
355     /***
356      * @see javax.servlet.http.HttpServletResponse#sendError(int)
357      */
358     public void sendError(int sc) throws IOException
359     {
360         response.sendError(sc);
361     }
362 
363     /***
364      * @see javax.servlet.http.HttpServletResponse#sendRedirect(java.lang.String)
365      */
366     public void sendRedirect(String location) throws IOException
367     {
368         response.sendRedirect(location);
369     }
370 
371     /***
372      * @see javax.servlet.http.HttpServletResponse#setDateHeader(java.lang.String, long)
373      */
374     public void setDateHeader(String name, long date)
375     {
376         if (!ArrayUtils.contains(FILTERED_HEADERS, StringUtils.lowerCase(name)))
377         {
378             response.setDateHeader(name, date);
379         }
380     }
381 
382     /***
383      * @see javax.servlet.http.HttpServletResponse#addDateHeader(java.lang.String, long)
384      */
385     public void addDateHeader(String name, long date)
386     {
387         if (!ArrayUtils.contains(FILTERED_HEADERS, StringUtils.lowerCase(name)))
388         {
389             response.addDateHeader(name, date);
390         }
391     }
392 
393     /***
394      * @see javax.servlet.http.HttpServletResponse#setHeader(java.lang.String, java.lang.String)
395      */
396     public void setHeader(String name, String value)
397     {
398         if (!ArrayUtils.contains(FILTERED_HEADERS, StringUtils.lowerCase(name)))
399         {
400             response.setHeader(name, value);
401         }
402     }
403 
404     /***
405      * @see javax.servlet.http.HttpServletResponse#setIntHeader(java.lang.String, int)
406      */
407     public void setIntHeader(String name, int value)
408     {
409         if (!ArrayUtils.contains(FILTERED_HEADERS, StringUtils.lowerCase(name)))
410         {
411             response.setIntHeader(name, value);
412         }
413     }
414 
415     /***
416      * @see javax.servlet.http.HttpServletResponse#addIntHeader(java.lang.String, int)
417      */
418     public void addIntHeader(String name, int value)
419     {
420         if (!ArrayUtils.contains(FILTERED_HEADERS, StringUtils.lowerCase(name)))
421         {
422             response.addIntHeader(name, value);
423         }
424     }
425 
426     /***
427      * @see javax.servlet.http.HttpServletResponse#setStatus(int)
428      */
429     public void setStatus(int sc)
430     {
431         response.setStatus(sc);
432     }
433 
434     /***
435      * @see javax.servlet.http.HttpServletResponse#setStatus(int, java.lang.String)
436      * @deprecated
437      */
438     public void setStatus(int sc, String sm)
439     {
440         response.setStatus(sc, sm);
441     }
442 
443 }