KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mortbay > jetty > servlet > ServletHttpResponse


1 // ========================================================================
2
// $Id: ServletHttpResponse.java,v 1.65 2006/04/04 22:28:05 gregwilkins Exp $
3
// Copyright 2000-2004 Mort Bay Consulting Pty. Ltd.
4
// ------------------------------------------------------------------------
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
// ========================================================================
15

16 package org.mortbay.jetty.servlet;
17
18 import java.io.IOException JavaDoc;
19 import java.io.PrintWriter JavaDoc;
20 import java.util.Locale JavaDoc;
21
22 import javax.servlet.RequestDispatcher JavaDoc;
23 import javax.servlet.ServletException JavaDoc;
24 import javax.servlet.ServletOutputStream JavaDoc;
25 import javax.servlet.ServletResponse JavaDoc;
26 import javax.servlet.ServletResponseWrapper JavaDoc;
27 import javax.servlet.http.Cookie JavaDoc;
28 import javax.servlet.http.HttpServletResponse JavaDoc;
29 import javax.servlet.http.HttpSession JavaDoc;
30
31 import org.apache.commons.logging.Log;
32 import org.mortbay.log.LogFactory;
33 import org.mortbay.http.HttpContext;
34 import org.mortbay.http.HttpFields;
35 import org.mortbay.http.HttpOutputStream;
36 import org.mortbay.http.HttpResponse;
37 import org.mortbay.util.IO;
38 import org.mortbay.util.LogSupport;
39 import org.mortbay.util.StringUtil;
40 import org.mortbay.util.TypeUtil;
41 import org.mortbay.util.URI;
42
43 /* ------------------------------------------------------------ */
44 /** Servlet Response Wrapper.
45  * This class wraps a Jetty HTTP response as a 2.2 Servlet
46  * response.
47  *
48  * Note that this wrapper is not synchronized and if a response is to
49  * be operated on by multiple threads, then higher level
50  * synchronizations may be required.
51  *
52  * @version $Id: ServletHttpResponse.java,v 1.65 2006/04/04 22:28:05 gregwilkins Exp $
53  * @author Greg Wilkins (gregw)
54  */

55 public class ServletHttpResponse implements HttpServletResponse JavaDoc
56 {
57     private static Log log = LogFactory.getLog(ServletHttpResponse.class);
58
59     public static final int
60         DISABLED=-1,
61         NO_OUT=0,
62         OUTPUTSTREAM_OUT=1,
63         WRITER_OUT=2;
64
65     private static ServletWriter __nullServletWriter;
66     private static ServletOut __nullServletOut;
67     static
68     {
69         try{
70             __nullServletWriter =
71                 new ServletWriter(IO.getNullStream());
72             __nullServletOut =
73                 new ServletOut(IO.getNullStream());
74         }
75         catch (Exception JavaDoc e)
76         {
77             log.fatal(e); System.exit(1);
78         }
79     }
80     
81     
82     /* ------------------------------------------------------------ */
83     private HttpResponse _httpResponse;
84     private ServletHttpRequest _servletHttpRequest;
85     private int _outputState=NO_OUT;
86     private ServletOut _out =null;
87     private ServletWriter _writer=null;
88     private HttpSession JavaDoc _session=null;
89     private boolean _noSession=false;
90     private Locale JavaDoc _locale=null;
91     private boolean _charEncodingSetInContentType=false;
92
93     
94     /* ------------------------------------------------------------ */
95     public ServletHttpResponse(ServletHttpRequest request,HttpResponse response)
96     {
97         _servletHttpRequest=request;
98         _servletHttpRequest.setServletHttpResponse(this);
99         _httpResponse=response;
100     }
101
102     /* ------------------------------------------------------------ */
103     void recycle()
104     {
105         _outputState=NO_OUT;
106         _out=null;
107         _writer=null;
108         _session=null;
109         _noSession=false;
110         _locale=null;
111         _charEncodingSetInContentType=false;
112     }
113     
114     /* ------------------------------------------------------------ */
115     int getOutputState()
116     {
117         return _outputState;
118     }
119     
120     /* ------------------------------------------------------------ */
121     void setOutputState(int s)
122         throws IOException JavaDoc
123     {
124         if (s<0)
125         {
126             _outputState=DISABLED;
127             if (_writer!=null)
128                 _writer.disable();
129             _writer=null;
130             if (_out!=null)
131                 _out.disable();
132             _out=null;
133         }
134         else
135             _outputState=s;
136     }
137     
138     
139     /* ------------------------------------------------------------ */
140     HttpResponse getHttpResponse()
141     {
142         return _httpResponse;
143     }
144     
145     /* ------------------------------------------------------------ */
146     void commit()
147         throws IOException JavaDoc
148     {
149         if (_writer!=null && _writer.isWritten())
150             _writer.flush();
151         else
152             _httpResponse.commit();
153     }
154     
155     /* ------------------------------------------------------------ */
156     void complete()
157         throws IOException JavaDoc
158     {
159         _httpResponse.completing();
160         commit();
161         setOutputState(DISABLED);
162     }
163
164     /* ------------------------------------------------------------ */
165     public boolean isCommitted()
166     {
167         return _httpResponse.isCommitted();
168     }
169     
170     /* ------------------------------------------------------------ */
171     boolean isDirty()
172     {
173         return _httpResponse.isDirty();
174     }
175
176     /* ------------------------------------------------------------ */
177     public void setBufferSize(int size)
178     {
179         HttpOutputStream out = (HttpOutputStream)_httpResponse.getOutputStream();
180         if (out.isWritten() || _writer!=null && _writer.isWritten())
181             throw new IllegalStateException JavaDoc("Output written");
182         out.setBufferSize(size);
183     }
184     
185     /* ------------------------------------------------------------ */
186     public int getBufferSize()
187     {
188         return ((HttpOutputStream)_httpResponse.getOutputStream()).getBufferSize();
189     }
190     
191     /* ------------------------------------------------------------ */
192     public void flushBuffer()
193         throws IOException JavaDoc
194     {
195         if (((HttpOutputStream)_httpResponse.getOutputStream()).isClosed())
196             return;
197         
198         if (_writer!=null)
199             _writer.flush();
200         if (_out!=null)
201             _out.flush();
202         if (_writer==null && _out==null)
203             _httpResponse.getOutputStream().flush();
204         if (!_httpResponse.isCommitted())
205             _httpResponse.commit();
206     }
207     
208     /* ------------------------------------------------------------ */
209     public void resetBuffer()
210     {
211         if (isCommitted())
212             throw new IllegalStateException JavaDoc("Committed");
213         
214         ((HttpOutputStream)_httpResponse.getOutputStream()).resetBuffer();
215         if (_writer!=null) _writer.reset();
216     }
217     
218     /* ------------------------------------------------------------ */
219     public void reset()
220     {
221         resetBuffer();
222         _httpResponse.reset();
223     }
224     
225     /* ------------------------------------------------------------ */
226     /**
227      * Sets the locale of the response, setting the headers (including the
228      * Content-Type's charset) as appropriate. This method should be called
229      * before a call to {@link #getWriter}. By default, the response locale
230      * is the default locale for the server.
231      *
232      * @see #getLocale
233      * @param locale the Locale of the response
234      */

235     public void setLocale(Locale JavaDoc locale)
236     {
237         if (locale == null || isCommitted())
238             return;
239
240         _locale = locale;
241         setHeader(HttpFields.__ContentLanguage,locale.toString().replace('_','-'));
242                          
243         if (this._outputState==0)
244         {
245             /* get current MIME type from Content-Type header */
246             String JavaDoc type=_httpResponse.getField(HttpFields.__ContentType);
247             if (type==null)
248             {
249                 // servlet did not set Content-Type yet
250
// so lets assume default one
251
type="application/octet-stream";
252             }
253             
254             HttpContext httpContext=_servletHttpRequest.getServletHandler().getHttpContext();
255             if (httpContext instanceof ServletHttpContext)
256             {
257                 String JavaDoc charset = ((ServletHttpContext)httpContext).getLocaleEncoding(locale);
258                 if (charset != null && charset.length()>0)
259                 {
260                     int semi=type.indexOf(';');
261                     if (semi<0)
262                         type += "; charset="+charset;
263                     else if (!_charEncodingSetInContentType)
264                         type = type.substring(0,semi)+"; charset="+charset;
265                     
266                     setHeader(HttpFields.__ContentType,type);
267                 }
268                 
269             }
270         }
271     }
272     
273     /* ------------------------------------------------------------ */
274     public Locale JavaDoc getLocale()
275     {
276         if (_locale==null)
277             return Locale.getDefault();
278         return _locale;
279     }
280     
281     /* ------------------------------------------------------------ */
282     public void addCookie(Cookie JavaDoc cookie)
283     {
284         _httpResponse.addSetCookie(cookie);
285     }
286
287     /* ------------------------------------------------------------ */
288     public boolean containsHeader(String JavaDoc name)
289     {
290         return _httpResponse.containsField(name);
291     }
292
293     /* ------------------------------------------------------------ */
294     public String JavaDoc encodeURL(String JavaDoc url)
295     {
296         // should not encode if cookies in evidence
297
if (_servletHttpRequest==null ||
298             _servletHttpRequest.isRequestedSessionIdFromCookie() &&
299             _servletHttpRequest.getServletHandler().isUsingCookies())
300             return url;
301         
302         // get session;
303
if (_session==null && !_noSession)
304         {
305             _session=_servletHttpRequest.getSession(false);
306             _noSession=(_session==null);
307         }
308         
309         // no session or no url
310
if (_session == null || url==null)
311             return url;
312         
313         // invalid session
314
String JavaDoc id = _session.getId();
315         if (id == null)
316             return url;
317         
318         // Check host and port are for this server
319
// TODO not implemented
320

321         // Already encoded
322
int prefix=url.indexOf(SessionManager.__SessionUrlPrefix);
323         if (prefix!=-1)
324         {
325             int suffix=url.indexOf("?",prefix);
326             if (suffix<0)
327                 suffix=url.indexOf("#",prefix);
328
329             if (suffix<=prefix)
330                 return url.substring(0,prefix+SessionManager.__SessionUrlPrefix.length())+id;
331             return url.substring(0,prefix+SessionManager.__SessionUrlPrefix.length())+id+
332                 url.substring(suffix);
333         }
334         
335         // edit the session
336
int suffix=url.indexOf('?');
337         if (suffix<0)
338             suffix=url.indexOf('#');
339         if (suffix<0)
340             return url+SessionManager.__SessionUrlPrefix+id;
341         return url.substring(0,suffix)+
342             SessionManager.__SessionUrlPrefix+id+url.substring(suffix);
343     }
344
345     /* ------------------------------------------------------------ */
346     public String JavaDoc encodeRedirectURL(String JavaDoc url)
347     {
348         return encodeURL(url);
349     }
350
351     /* ------------------------------------------------------------ */
352     /**
353      * @deprecated As of version 2.1, use encodeURL(String url) instead
354      */

355     public String JavaDoc encodeUrl(String JavaDoc url)
356     {
357         return encodeURL(url);
358     }
359
360     /* ------------------------------------------------------------ */
361     /**
362      * @deprecated As of version 2.1, use
363      * encodeRedirectURL(String url) instead
364      */

365     public String JavaDoc encodeRedirectUrl(String JavaDoc url)
366     {
367         return encodeRedirectURL(url);
368     }
369
370     /* ------------------------------------------------------------ */
371     public void sendError(int status, String JavaDoc message)
372         throws IOException JavaDoc
373     {
374         // Find error page.
375
String JavaDoc error_page =
376             _servletHttpRequest.getServletHandler().getErrorPage(status,_servletHttpRequest);
377
378         resetBuffer();
379         
380         // Handle error page?
381
if (error_page==null)
382         {
383             // handle normally
384
_httpResponse.sendError(status,message);
385         }
386         else
387         {
388             _httpResponse.setStatus(status,message);
389             
390             if (message == null)
391             {
392                 message= (String JavaDoc)HttpResponse.__statusMsg.get(TypeUtil.newInteger(status));
393                 if (message == null)
394                     message= "" + status;
395             }
396
397             // handle error page
398
ServletHolder holder = _servletHttpRequest.getServletHolder();
399             if (holder!=null)
400                 _servletHttpRequest.setAttribute(ServletHandler.__J_S_ERROR_SERVLET_NAME,
401                                                  holder.getName());
402             _servletHttpRequest.setAttribute(ServletHandler.__J_S_ERROR_REQUEST_URI,
403                                              _servletHttpRequest.getRequestURI());
404             _servletHttpRequest.setAttribute(ServletHandler.__J_S_ERROR_STATUS_CODE,
405                                              new Integer JavaDoc(status));
406             _servletHttpRequest.setAttribute(ServletHandler.__J_S_ERROR_MESSAGE,
407                                              message);
408             
409             RequestDispatcher JavaDoc dispatcher=
410                 _servletHttpRequest.getServletHandler().getServletContext()
411                 .getRequestDispatcher(error_page);
412
413             try
414             {
415                 ((Dispatcher)dispatcher).error(_servletHttpRequest,this);
416             }
417             catch(ServletException JavaDoc e)
418             {
419                 log.warn(LogSupport.EXCEPTION,e);
420                 _httpResponse.sendError(status,message);
421             }
422         }
423         complete();
424     }
425
426     /* ------------------------------------------------------------ */
427     public void sendError(int status)
428         throws IOException JavaDoc
429     {
430         sendError(status,null);
431     }
432
433     /* ------------------------------------------------------------ */
434     public void sendRedirect(String JavaDoc url)
435         throws IOException JavaDoc
436     {
437         if (url==null)
438             throw new IllegalArgumentException JavaDoc();
439         
440         if (!URI.hasScheme(url))
441         {
442             StringBuffer JavaDoc buf = _servletHttpRequest.getHttpRequest().getRootURL();
443             if (url.startsWith("/"))
444                 buf.append(URI.canonicalPath(url));
445             else
446             {
447                 String JavaDoc path=_servletHttpRequest.getRequestURI();
448                 String JavaDoc parent=(path.endsWith("/"))?path:URI.parentPath(path);
449                 url=URI.canonicalPath(URI.addPaths(parent,url));
450                 if (!url.startsWith("/"))
451                     buf.append('/');
452                 buf.append(url);
453             }
454             
455             url=buf.toString();
456         }
457         
458         resetBuffer();
459         
460         _httpResponse.setField(HttpFields.__Location,url);
461         _httpResponse.setStatus(HttpResponse.__302_Moved_Temporarily);
462         complete();
463     }
464
465     /* ------------------------------------------------------------ */
466     public void setDateHeader(String JavaDoc name, long value)
467     {
468         try{_httpResponse.setDateField(name,value);}
469         catch(IllegalStateException JavaDoc e){LogSupport.ignore(log,e);}
470     }
471
472     /* ------------------------------------------------------------ */
473     public void setHeader(String JavaDoc name, String JavaDoc value)
474     {
475         try{_httpResponse.setField(name,value);}
476         catch(IllegalStateException JavaDoc e){LogSupport.ignore(log,e);}
477     }
478
479     /* ------------------------------------------------------------ */
480     public void setIntHeader(String JavaDoc name, int value)
481     {
482         try{_httpResponse.setIntField(name,value);}
483         catch(IllegalStateException JavaDoc e){LogSupport.ignore(log,e);}
484     }
485     
486     /* ------------------------------------------------------------ */
487     public void addDateHeader(String JavaDoc name, long value)
488     {
489         try{_httpResponse.addDateField(name,value);}
490         catch(IllegalStateException JavaDoc e){LogSupport.ignore(log,e);}
491     }
492
493     /* ------------------------------------------------------------ */
494     public void addHeader(String JavaDoc name, String JavaDoc value)
495     {
496         try{_httpResponse.addField(name,value);}
497         catch(IllegalStateException JavaDoc e){LogSupport.ignore(log,e);}
498     }
499     
500
501     /* ------------------------------------------------------------ */
502     public void addIntHeader(String JavaDoc name, int value)
503     {
504         try{_httpResponse.addIntField(name,value);}
505         catch(IllegalStateException JavaDoc e){LogSupport.ignore(log,e);}
506     }
507
508     /* ------------------------------------------------------------ */
509     public void setStatus(int status)
510     {
511         _httpResponse.setStatus(status);
512     }
513
514     /* ------------------------------------------------------------ */
515     /**
516     * @deprecated As of version 2.1 of the Servlet spec.
517     * To set a status code
518     * use <code>setStatus(int)</code>, to send an error with a description
519     * use <code>sendError(int, String)</code>.
520     *
521     * Sets the status code and message for this response.
522     *
523     * @param status the status code
524     * @param message the status message
525     */

526     public void setStatus(int status, String JavaDoc message)
527     {
528         setStatus(status);
529         _httpResponse.setReason(message);
530     }
531
532
533     /* ------------------------------------------------------------ */
534     public ServletOutputStream JavaDoc getOutputStream()
535     {
536         if (_outputState==DISABLED)
537             return __nullServletOut;
538         
539         if (_outputState!=NO_OUT && _outputState!=OUTPUTSTREAM_OUT)
540             throw new IllegalStateException JavaDoc();
541         
542         if (_writer!=null)
543         {
544             _writer.flush();
545             _writer.disable();
546             _writer=null;
547         }
548         
549         if (_out==null)
550             _out = new ServletOut(_servletHttpRequest.getHttpRequest()
551                                   .getOutputStream());
552         _outputState=OUTPUTSTREAM_OUT;
553         return _out;
554     }
555
556     /* ------------------------------------------------------------ */
557     public PrintWriter JavaDoc getWriter()
558         throws java.io.IOException JavaDoc
559     {
560         if (_outputState==DISABLED)
561             return __nullServletWriter;
562                                    
563         if (_outputState!=NO_OUT && _outputState!=WRITER_OUT)
564             throw new IllegalStateException JavaDoc();
565
566         // If we are switching modes, flush output to try avoid overlaps.
567
if (_out!=null)
568             _out.flush();
569         
570         /* if there is no writer yet */
571         if (_writer==null)
572         {
573             /* get encoding from Content-Type header */
574             String JavaDoc encoding = _httpResponse.getCharacterEncoding();
575             
576             if (encoding==null)
577             {
578                 if (_servletHttpRequest!=null)
579                 {
580                     /* implementation of educated defaults */
581                     String JavaDoc mimeType = _httpResponse.getMimeType();
582                     encoding = _servletHttpRequest.getServletHandler()
583                         .getHttpContext().getEncodingByMimeType(mimeType);
584                 }
585                 if (encoding==null)
586                     encoding = StringUtil.__ISO_8859_1;
587                 _httpResponse.setCharacterEncoding(encoding,true);
588             }
589             
590             /* construct Writer using correct encoding */
591             _writer = new ServletWriter(_httpResponse.getOutputStream(), encoding);
592         }
593         _outputState=WRITER_OUT;
594         return _writer;
595     }
596     
597     /* ------------------------------------------------------------ */
598     public void setContentLength(int len)
599     {
600         // Protect from setting after committed as default handling
601
// of a servlet HEAD request ALWAYS sets content length, even
602
// if the getHandling committed the response!
603
if (!isCommitted())
604             setIntHeader(HttpFields.__ContentLength,len);
605     }
606     
607     /* ------------------------------------------------------------ */
608     public String JavaDoc getContentType()
609     {
610         return _httpResponse.getContentType();
611     }
612     
613     /* ------------------------------------------------------------ */
614     public void setContentType(String JavaDoc contentType)
615     {
616         if (isCommitted() || contentType==null)
617             return;
618         
619         int semi=contentType.indexOf(';');
620         if (semi>0)
621         {
622             int charset0=contentType.indexOf("charset=",semi);
623             if (charset0>0)
624             {
625                 if (_outputState==WRITER_OUT)
626                 {
627                     // need to strip charset= from params
628
int charset1=contentType.indexOf(' ',charset0);
629                     
630                     if ((charset0==semi+1 && charset1<0) ||
631                         (charset0==semi+2 && charset1<0 && contentType.charAt(semi+1)==' ' ))
632                         _httpResponse.setContentType(contentType.substring(0,semi));
633                     else if (charset1<0)
634                         _httpResponse.setContentType(contentType.substring(0, charset0).trim());
635                     else
636                         _httpResponse.setContentType(contentType.substring(0, charset0)+contentType.substring(charset1));
637                 }
638                 else
639                 {
640                     _charEncodingSetInContentType=true;
641                     _httpResponse.setContentType(contentType);
642                 }
643             }
644             else
645                 _httpResponse.setContentType(contentType);
646         }
647         else
648             _httpResponse.setContentType(contentType);
649         
650         if (_locale!=null)
651             setLocale(_locale);
652     }
653
654     /* ------------------------------------------------------------ */
655     public void setCharacterEncoding(String JavaDoc encoding)
656     {
657         if (this._outputState==0 && !isCommitted())
658         {
659             _charEncodingSetInContentType=true;
660             _httpResponse.setCharacterEncoding(encoding,true);
661         }
662     }
663     
664     /* ------------------------------------------------------------ */
665     public String JavaDoc getCharacterEncoding()
666     {
667         String JavaDoc encoding=_httpResponse.getCharacterEncoding();
668         return (encoding==null)?StringUtil.__ISO_8859_1:encoding;
669     }
670     
671     /* ------------------------------------------------------------ */
672     public String JavaDoc toString()
673     {
674         return _httpResponse.toString();
675     }
676
677     
678     /* ------------------------------------------------------------ */
679     /** Unwrap a ServletResponse.
680      *
681      * @see javax.servlet.ServletResponseWrapper
682      * @see javax.servlet.http.HttpServletResponseWrapper
683      * @param response
684      * @return The core ServletHttpResponse which must be the
685      * underlying response object
686      */

687     public static ServletHttpResponse unwrap(ServletResponse JavaDoc response)
688     {
689         while (!(response instanceof ServletHttpResponse))
690         {
691             if (response instanceof ServletResponseWrapper JavaDoc)
692             {
693                 ServletResponseWrapper JavaDoc wrapper =
694                     (ServletResponseWrapper JavaDoc)response;
695                 response=wrapper.getResponse();
696             }
697             else
698                 throw new IllegalArgumentException JavaDoc("Does not wrap ServletHttpResponse");
699         }
700
701         return (ServletHttpResponse)response;
702     }
703
704
705 }
706
Popular Tags