View Javadoc

1   /*
2   Wotonomy: OpenStep design patterns for pure Java applications.
3   Copyright (C) 2000 Blacksmith, Inc.
4   
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9   
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  Lesser General Public License for more details.
14  
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, see http://www.gnu.org
17  */
18  
19  package net.wotonomy.web;
20  
21  import java.text.SimpleDateFormat;
22  import java.util.Date;
23  import java.util.TimeZone;
24  
25  import net.wotonomy.foundation.NSArray;
26  
27  /***
28  * A pure java implementation of WOResponse.
29  *
30  * @author michael@mpowers.net
31  * @author $Author: cgruber $
32  * @version $Revision: 905 $
33  */
34  public class WOResponse extends WOMessage
35      implements WOActionResults
36  {
37  	protected static String defaultEncoding;
38      private static SimpleDateFormat htmlDateFormat;
39      static
40      {
41          defaultEncoding = "ISO8859_1";
42          htmlDateFormat = new SimpleDateFormat(
43              "EEE, dd MMM yyyy HH:mm:ss z" );
44          htmlDateFormat.setTimeZone(
45              TimeZone.getTimeZone( "GMT" ) );
46      }
47  
48  	private int status;
49  
50  	/***
51  	* Parameterless constructor which should not be called.
52  	*/
53      public WOResponse ()
54      {
55  		status = -1; // -1 indicates not yet set
56      }
57  
58  	/***
59  	* Sets the status code of the response.
60  	* You should use the constants defined in HttpServletResponse.
61  	*/
62      public void setStatus (int code)
63      {
64      	status = code;
65      }
66  
67  	/***
68  	* Gets the current status code for the response.
69  	*/
70      public int status ()
71      {
72      	return status;
73      }
74  
75  	/***
76  	* Sets a header in the response to disable client caching.
77  	* (Whether this works depends on the client implementation.)
78  	*/
79      public void disableClientCaching ()
80      {
81          String dateString = htmlDateFormat.format( new Date() );
82          setHeader( dateString, "Date" );
83          setHeader( dateString, "Expires" );
84          setHeader( "no-cache", "Pragma" );
85          setHeaders( new NSArray( new Object[] { 
86              "private", "no-cache", "max-age = 0" } ), "Cache-Control" );
87          //System.out.println( "disableClientCaching: " + dateString );        
88      }
89  
90      /***
91      * Returns this object.  (Implements the WOActionResults interface.)
92      */
93      public WOResponse generateResponse()
94      {
95      	return this;
96      }
97  
98  	/***
99  	* Generates the response using the specified servlet response,
100 	* but does not flush the buffer. The caller is responsible
101 	* for sending the response to the client.  <br><br>
102 	* Note that this method is currently responsible for setting 
103 	* the content type to "text/html".  As far as I can tell, WORequests
104 	* have no way to set the content type and therefore must always
105 	* be of type "text/html".
106 	*/
107     void generateServletResponse 
108     	(javax.servlet.http.HttpServletResponse response)
109     {
110         if ( WOApplication.application().isPageRefreshOnBacktrackEnabled() )
111         {
112             disableClientCaching();
113         }
114 
115 	    String key;
116     	java.util.Enumeration e, f;
117 	    
118 	    // set content type: might be overwritten by headers below
119         response.setContentType( "text/html" );
120 	    
121 	    // set status
122 	    if ( status != -1 )
123 	    {
124 	    	response.setStatus( status );	    
125 		}
126 
127 	    // set headers
128 	    f = _headers.allKeys().objectEnumerator();
129 		while ( f.hasMoreElements() )
130 		{
131             key = f.nextElement().toString();
132 	    	e = ((NSArray)_headers.objectForKey( key )).objectEnumerator();
133 	    	if ( e.hasMoreElements() )
134             {
135                 // overwrite existing header
136                 response.setHeader( key, e.nextElement().toString() );
137             }
138             while ( e.hasMoreElements() )
139             {
140                 response.addHeader( key, e.nextElement().toString() );
141             }
142 		}
143 
144 	    // set cookies
145 	    e = _cookies.allValues().objectEnumerator();
146 	    while ( e.hasMoreElements() )
147 	    {
148 	    	response.addCookie( (WOCookie) e.nextElement() );
149 	    }
150 
151 		try
152 		{
153             // write content
154             response.getOutputStream().write(_contentData.bytes() );
155             if ( status > 299 )
156             {
157                 response.sendError( status );
158             }
159 	    }
160 	    catch ( Exception exc )
161 		{
162 			throw new RuntimeException( 
163 				"Error writing response: " + exc );    	   
164 		}
165     }
166 
167 
168 	/***
169 	* Returns the current default encoding seting.
170 	*/
171     public static String defaultEncoding ()
172     {
173     	return defaultEncoding;
174     }
175 
176 	/***
177 	* Sets the default encoding setting.
178 	*/
179     public static void setDefaultEncoding (String encoding)
180     {
181     	defaultEncoding = encoding;
182     }
183 
184 }