KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > opensymphony > oscache > web > filter > ResponseContent


1 /*
2  * Copyright (c) 2002-2003 by OpenSymphony
3  * All rights reserved.
4  */

5 package com.opensymphony.oscache.web.filter;
6
7 import java.io.*;
8
9 import java.util.Locale JavaDoc;
10 import java.util.zip.GZIPInputStream JavaDoc;
11
12 import javax.servlet.ServletResponse JavaDoc;
13 import javax.servlet.http.HttpServletResponse JavaDoc;
14
15 /**
16  * Holds the servlet response in a byte array so that it can be held
17  * in the cache (and, since this class is serializable, optionally
18  * persisted to disk).
19  *
20  * @version $Revision: 1.3 $
21  * @author <a HREF="mailto:sergek@lokitech.com">Serge Knystautas</a>
22  */

23 public class ResponseContent implements Serializable {
24     private transient ByteArrayOutputStream bout = new ByteArrayOutputStream(1000);
25     private Locale JavaDoc locale = null;
26     private String JavaDoc contentEncoding = null;
27     private String JavaDoc contentType = null;
28     private byte[] content = null;
29     private long expires = Long.MAX_VALUE;
30     private long lastModified = -1;
31     private long maxAge = -60;
32
33     public String JavaDoc getContentType() {
34         return contentType;
35     }
36     
37     /**
38      * Set the content type. We capture this so that when we serve this
39      * data from cache, we can set the correct content type on the response.
40      */

41     public void setContentType(String JavaDoc value) {
42         contentType = value;
43     }
44
45     public long getLastModified() {
46         return lastModified;
47     }
48
49     public void setLastModified(long value) {
50         lastModified = value;
51     }
52
53     public String JavaDoc getContentEncoding() {
54         return contentEncoding;
55     }
56
57     public void setContentEncoding(String JavaDoc contentEncoding) {
58         this.contentEncoding = contentEncoding;
59     }
60
61     /**
62      * Set the Locale. We capture this so that when we serve this data from
63      * cache, we can set the correct locale on the response.
64      */

65     public void setLocale(Locale JavaDoc value) {
66         locale = value;
67     }
68
69     /**
70      * @return the expires date and time in miliseconds when the content will be stale
71      */

72     public long getExpires() {
73         return expires;
74     }
75
76     /**
77      * Sets the expires date and time in miliseconds.
78      * @param value time in miliseconds when the content will expire
79      */

80     public void setExpires(long value) {
81         expires = value;
82     }
83
84     /**
85      * Returns the max age of the content in miliseconds. If expires header and cache control are
86      * enabled both, both will be equal.
87      * @return the max age of the content in miliseconds, if -1 max-age is disabled
88      */

89     public long getMaxAge() {
90         return maxAge;
91     }
92
93     /**
94      * Sets the max age date and time in miliseconds. If the parameter is -1, the max-age parameter
95      * won't be set by default in the Cache-Control header.
96      * @param value sets the intial
97      */

98     public void setMaxAge(long value) {
99         maxAge = value;
100     }
101
102     /**
103      * Get an output stream. This is used by the {@link SplitServletOutputStream}
104      * to capture the original (uncached) response into a byte array.
105      * @return the original (uncached) response, returns null if response is already committed.
106      */

107     public OutputStream getOutputStream() {
108         return bout;
109     }
110
111     /**
112      * Gets the size of this cached content.
113      *
114      * @return The size of the content, in bytes. If no content
115      * exists, this method returns <code>-1</code>.
116      */

117     public int getSize() {
118         return (content != null) ? content.length : (-1);
119     }
120
121     /**
122      * Called once the response has been written in its entirety. This
123      * method commits the response output stream by converting the output
124      * stream into a byte array.
125      */

126     public void commit() {
127         if (bout != null) {
128             content = bout.toByteArray();
129             bout = null;
130         }
131     }
132
133     /**
134      * Writes this cached data out to the supplied <code>ServletResponse</code>.
135      *
136      * @param response The servlet response to output the cached content to.
137      * @throws IOException
138      */

139     public void writeTo(ServletResponse JavaDoc response) throws IOException {
140         writeTo(response, false, false);
141     }
142
143     /**
144      * Writes this cached data out to the supplied <code>ServletResponse</code>.
145      *
146      * @param response The servlet response to output the cached content to.
147      * @param fragment is true if this content a fragment or part of a page
148      * @param acceptsGZip is true if client browser supports gzip compression
149      * @throws IOException
150      */

151     public void writeTo(ServletResponse JavaDoc response, boolean fragment, boolean acceptsGZip) throws IOException {
152         //Send the content type and data to this response
153
if (contentType != null) {
154             response.setContentType(contentType);
155         }
156         
157         if (fragment) {
158             // Don't support gzip compression if the content is a fragment of a page
159
acceptsGZip = false;
160         } else {
161             // add special headers for a complete page
162
if (response instanceof HttpServletResponse JavaDoc) {
163                 HttpServletResponse JavaDoc httpResponse = (HttpServletResponse JavaDoc) response;
164                 
165                 // add the last modified header
166
if (lastModified != -1) {
167                     httpResponse.setDateHeader(CacheFilter.HEADER_LAST_MODIFIED, lastModified);
168                 }
169                 
170                 // add the expires header
171
if (expires != Long.MAX_VALUE) {
172                     httpResponse.setDateHeader(CacheFilter.HEADER_EXPIRES, expires);
173                 }
174                 
175                 // add the cache-control header for max-age
176
if (maxAge == CacheFilter.MAX_AGE_NO_INIT || maxAge == CacheFilter.MAX_AGE_TIME) {
177                     // do nothing
178
} else if (maxAge > 0) { // set max-age based on life time
179
long currentMaxAge = maxAge / 1000 - System.currentTimeMillis() / 1000;
180                     if (currentMaxAge < 0) {
181                         currentMaxAge = 0;
182                     }
183                     httpResponse.addHeader(CacheFilter.HEADER_CACHE_CONTROL, "max-age=" + currentMaxAge);
184                 } else {
185                     httpResponse.addHeader(CacheFilter.HEADER_CACHE_CONTROL, "max-age=" + (-maxAge));
186                 }
187                 
188             }
189         }
190
191         if (locale != null) {
192             response.setLocale(locale);
193         }
194
195         OutputStream out = new BufferedOutputStream(response.getOutputStream());
196
197         if (isContentGZiped()) {
198             if (acceptsGZip) {
199                 ((HttpServletResponse JavaDoc) response).addHeader(CacheFilter.HEADER_CONTENT_ENCODING, "gzip");
200                 response.setContentLength(content.length);
201                 out.write(content);
202             } else {
203                 // client doesn't support, so we have to uncompress it
204
ByteArrayInputStream bais = new ByteArrayInputStream(content);
205                 GZIPInputStream JavaDoc zis = new GZIPInputStream JavaDoc(bais);
206
207                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
208                 int numBytesRead = 0;
209                 byte[] tempBytes = new byte[4196];
210
211                 while ((numBytesRead = zis.read(tempBytes, 0, tempBytes.length)) != -1) {
212                     baos.write(tempBytes, 0, numBytesRead);
213                 }
214
215                 byte[] result = baos.toByteArray();
216
217                 response.setContentLength(result.length);
218                 out.write(result);
219             }
220         } else {
221             // the content isn't compressed
222
// regardless if the client browser supports gzip we will just return the content
223
response.setContentLength(content.length);
224             out.write(content);
225         }
226         out.flush();
227     }
228     
229     
230     /**
231      * @return true if the content is GZIP compressed
232      */

233     public boolean isContentGZiped() {
234         return "gzip".equals(contentEncoding);
235     }
236
237 }
238
Popular Tags