KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jetspeed > services > webpage > WebPageCache


1 /*
2  * Copyright 2000-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.jetspeed.services.webpage;
18
19 // java.io
20
import java.io.IOException JavaDoc;
21 import java.io.FileOutputStream JavaDoc;
22 import java.io.InputStream JavaDoc;
23 import java.io.ByteArrayOutputStream JavaDoc;
24
25 // java.util
26
import java.util.HashMap JavaDoc;
27
28 // java.net
29
import java.net.URL JavaDoc;
30 import java.net.URLConnection JavaDoc;
31 import java.net.HttpURLConnection JavaDoc;
32 import java.net.MalformedURLException JavaDoc;
33
34 import org.apache.log4j.Logger;
35
36
37 /*
38  * Implements the WebPage service's static resource cache, for optimizing access to
39  * static resources from proxied hosts. Resources currently cached are read-only, static
40  * resources such as images, style sheets and scripts.
41  *
42  */

43
44 public class WebPageCache
45 {
46
47     // The Cache
48
private static HashMap JavaDoc cache = new HashMap JavaDoc();
49
50     // the log file singleton instance
51
static Logger log = Logger.getLogger(WebPageCache.class);
52
53     /**
54       * Given a cacheable web resource, writes the content of that resource to the servlet
55       * output stream. The first time that the resource is requested, the content is
56       * fetched from the proxied host. From then on, the resource content is served up from
57       * the cache.
58       *
59       * @param resource the resource that is being cached.
60       * @param neid the network element id.
61       * @param base the proxied host's base URL.
62       * @param host the Proxy Server base URL.
63       * @param data the RunData for the request.
64       * @return boolean true if the resource was read from the cache,
65       * false if read from the server.
66       */

67     public static boolean getResourceFromCache(String JavaDoc resource,
68                                                long sid,
69                                                String JavaDoc base,
70                                                String JavaDoc host,
71                                                ProxyRunData data)
72     {
73         try
74         {
75             CachedResource cr = (CachedResource)cache.get(resource);
76             if (null != cr) // is it in the cache...
77
{
78                 // yes, return cached item
79
byte[] bytes = cr.getContent();
80                 data.getResponse().getOutputStream().write(bytes, 0, bytes.length);
81                 return true;
82             }
83         
84             // not found in cache, so get it from proxied host
85
URL JavaDoc baseURL = new URL JavaDoc(base);
86             URL JavaDoc u = new URL JavaDoc(baseURL, resource);
87             HttpURLConnection JavaDoc con = (HttpURLConnection JavaDoc)u.openConnection();
88         
89             con.setDoInput(true);
90             con.setAllowUserInteraction(false);
91         
92             int contentType = WebPageHelper.getContentType(con.getHeaderField("content-type"), resource);
93         
94             byte[] content;
95
96             // get the proxied content, if its script, rewrite it
97
if (WebPageHelper.CT_JS == contentType)
98                 content = rewriteScript(con, sid, host, data, resource, base);
99             else
100                 content = getContentAndWrite(con, data);
101         
102             // create a new cached resource and put it in the cache
103
cr = new CachedResource(contentType, content);
104             cache.put(resource, cr);
105
106         }
107         catch (MalformedURLException JavaDoc ex)
108         {
109             log.error("CACHE URL EX:" + ex);
110             return false;
111
112         }
113         catch (IOException JavaDoc ex)
114         {
115             log.error("CACHE IO:" + ex);
116             return false;
117         }
118         return true;
119     }
120
121
122    /**
123      * Determines if a resource is cacheable, dependent on the extension:
124      * defined in CACHEABLE_RESOURCES (gif, jpeg, jpg, png, js, css)
125      *
126      * @param resource the resource that is being proxied.
127      * @return boolean true if the resource is a cacheable, otherwise false.
128      *
129      */

130     public static String JavaDoc[] CACHEABLE_RESOURCES = {
131         ".gif", ".jpeg", ".jpg", ".png", ".js", ".css" };
132
133     public static boolean isCacheableResource(String JavaDoc resource)
134     {
135         int pos = resource.lastIndexOf('.');
136         if (pos == -1)
137             return false;
138
139         if (resource.endsWith(".html"))
140             return false;
141
142         int length = resource.length();
143         if (pos >= length)
144             return false;
145
146         String JavaDoc ext = resource.substring(pos);
147         for (int ix=0; ix < CACHEABLE_RESOURCES.length; ix++) {
148             if (ext.equalsIgnoreCase(CACHEABLE_RESOURCES[ix])) {
149                 return true;
150             }
151         }
152         return false;
153     }
154
155     
156     /**
157       * Retrieves the content from the proxied host for the requested.
158       * Per cacheable resource, this is only called once. All further requests will
159       * return the cached content. The content is immediately written to the servlet's
160       * response output stream.
161       *
162       * @param con the HTTP connection to the proxied host.
163       * @param response the servlet response.
164       * @return byte[] the resource content, which will be stored in the cache.
165       */

166     public static byte[] getContentAndWrite(URLConnection JavaDoc con,
167                                             ProxyRunData data) throws IOException JavaDoc
168     {
169         int CAPACITY = 4096;
170     
171         InputStream JavaDoc is = con.getInputStream();
172         ByteArrayOutputStream JavaDoc buffer = new ByteArrayOutputStream JavaDoc();
173         byte[] bytes = new byte[CAPACITY];
174     
175         int readCount = 0;
176         while( ( readCount = is.read( bytes )) > 0 ) {
177     
178             buffer.write( bytes, 0, readCount);
179             data.getResponse().getOutputStream().write(bytes, 0, readCount);
180         }
181     
182         is.close();
183         return buffer.toByteArray();
184     }
185
186     /**
187       * Retrieves the script content from the proxied host for the requested.
188       * Per cacheable resource, this is only called once. All further requests will
189       * return the cached content. The content is first rewritten, rewriting all links
190       * found in the script back to the Proxy server. Then, the content is immediately
191       * written to the servlet's response output stream.
192       *
193       * @param con the HTTP connection to the proxied host.
194       * @param response the servlet response.
195       * @return byte[] the resource content, which will be stored in the cache.
196       */

197     public static byte[] rewriteScript(URLConnection JavaDoc con,
198                                        long sid,
199                                        String JavaDoc host,
200                                        ProxyRunData data,
201                                        String JavaDoc resource,
202                                        String JavaDoc base)
203                             throws IOException JavaDoc
204     {
205         int CAPACITY = 4096;
206
207         Configuration config = Configuration.getInstance();
208         InputStream JavaDoc is = con.getInputStream();
209         ByteArrayOutputStream JavaDoc buffer = new ByteArrayOutputStream JavaDoc();
210         byte[] bytes = new byte[CAPACITY];
211     
212         FileOutputStream JavaDoc fos = null;
213         boolean logging = config.getEnableContentLog();
214
215         // log content to a file if enabled
216
if (logging)
217         {
218             String JavaDoc fileName = data.getServlet().getServletContext().getRealPath(
219                                     config.getLogLocation() );
220             fos = new FileOutputStream JavaDoc(fileName, true);
221             WebPageHelper.writeHeader(fos, resource);
222         }
223
224         int readCount = 0;
225
226         // read in the script
227
while( ( readCount = is.read( bytes )) > 0 ) {
228             
229             buffer.write( bytes, 0, readCount);
230             if (logging)
231                 fos.write( bytes, 0, readCount);
232         }
233     
234         if (logging)
235             fos.close();
236
237         is.close();
238
239
240         String JavaDoc script = buffer.toString();
241
242
243         if (sid == -1)
244         { // FIXME: I seem to have lost this code....
245
// return HTMLRewriter.rewriteScript(script, resource, host, base);
246
}
247         return script.getBytes();
248
249         // FIXME: not rewriting scripts...
250
// return Rewriter.rewriteScript(script, sid, proxyHost, base);
251

252     }
253
254
255 }
256
Popular Tags