KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > barracuda > core > helper > servlet > ResourceGateway


1 /*
2  * Copyright (C) 2003 Christian Cryder [christianc@granitepeaks.com]
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * $Id: ResourceGateway.java,v 1.18 2004/02/01 05:16:28 christianc Exp $
19  */

20 package org.enhydra.barracuda.core.helper.servlet;
21
22 import java.io.*;
23 import java.lang.ref.*;
24 import javax.servlet.*;
25 import javax.servlet.http.*;
26
27 import org.apache.log4j.*;
28
29 import org.enhydra.barracuda.plankton.data.*;
30 import org.enhydra.barracuda.plankton.http.*;
31
32
33 /**
34  * <p>The purpose of this servlet is to look for a static resource
35  * on the classpath and return it to the client
36  */

37 public class ResourceGateway extends HttpServlet {
38
39     //public vars...eventually, these should probably be final
40
protected static final Logger logger = Logger.getLogger(ResourceGateway.class.getName());
41
42     //these are intentionally non-final, so that you can programatically
43
//change them if need be
44
public static String JavaDoc EXT_RESOURCE_ID = "xlib";
45     public static String JavaDoc RESOURCE_NOT_FOUND = "ResourceNotFound";
46
47
48     //-------------------- ResourceGateway -----------------------
49
/**
50      * <p>Handle the default HttpRequest.
51      *
52      * @param req the servlet request
53      * @param resp the servlet response
54      * @throws ServletException
55      * @throws IOException
56      */

57     public void handleDefault(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
58         //figure out what resource we're looking for
59
//jrk_2002-12-02.1 - don't prepend "/" otherwise the context classloader won't find the resource
60
//String resourceName = "/"+EXT_RESOURCE_ID + req.getPathInfo();
61
String JavaDoc resourceName = EXT_RESOURCE_ID + req.getPathInfo();
62         if (logger.isDebugEnabled()) logger.debug("Looking for static resource: "+resourceName);
63
64         //get the object from cache
65
Object JavaDoc resource = ContextServices.getObjectFromCache(this.getServletContext(), resourceName, new LocalReferenceFactory(resourceName));
66
67         //check the results
68
//...byte array
69
if (resource instanceof LocalResource) {
70
71             //csc_061202.1 - added
72
//set the caching hdrs (this will allow the static resources to be cached by the browser)
73
resp.setHeader("Cache-Control","public");
74             resp.setDateHeader("Last-Modified", System.currentTimeMillis());
75
76             //set the content type
77
if (logger.isDebugEnabled()) logger.debug("Got resource from cache");
78             LocalResource lr = (LocalResource)resource;
79             resp.setContentType(lr.contentType);
80             if (logger.isDebugEnabled()) logger.debug("Set content-type: "+lr.contentType);
81
82             //now return the requested document
83
OutputStream out = resp.getOutputStream();
84             out.write(lr.contentData);
85             //out.flush();
86
resp.flushBuffer(); //instead of out.flush for Servlet 2.2 compatibility (Craig McClanahan http://w4.metronet.com/~wjm/tomcat/2000/Nov/msg00174.html)
87
if (logger.isDebugEnabled()) logger.debug("Wrote data: "+lr.contentData.length+" bytes");
88
89         //...resource not found
90
} else {
91             if (logger.isDebugEnabled()) logger.debug("Resource not found");
92             resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Resource Not Found: "+resourceName);
93         }
94     }
95
96     /**
97      * Used to create a SoftReference to a specified resource
98      */

99     class LocalReferenceFactory implements ReferenceFactory {
100         String JavaDoc resourceName = null;
101
102         public LocalReferenceFactory(String JavaDoc iresourceName) {
103             resourceName = iresourceName;
104         }
105
106         public Reference getObjectReference() {
107             if (logger.isDebugEnabled()) logger.debug("Resource not in cache...will load from classpath");
108
109             //figure out the content type (see: http://www.isi.edu/in-notes/iana/assignments/media-types/media-types for source list)
110
String JavaDoc contentType = ResourceGateway.this.getServletContext().getMimeType(resourceName);
111             if (contentType==null) contentType = "text/plain";
112
113             //get the resource
114
if (logger.isDebugEnabled()) logger.debug("Attempting to read: "+resourceName);
115
116             Object JavaDoc result = null;
117             byte[] dstbytes = new byte[10240];
118             try {
119                 //read in the file and store it in a byte array
120
//jrk_2002-12-02.2 - get the resource from the context classloader instead of just the local classloader
121
//BufferedInputStream in = new BufferedInputStream(this.getClass().getResourceAsStream(resourceName));
122
BufferedInputStream in = new BufferedInputStream(Thread.currentThread().getContextClassLoader().getResourceAsStream(resourceName));
123                 int offset = 0;
124                 int len = 1024;
125                 byte[] inbytes = new byte[len];
126                 while (true) {
127                     int cnt = in.read(inbytes, 0, len);
128                     if (cnt==-1) break;
129                     if (offset+cnt>=dstbytes.length) {
130                         byte[] newbytes = new byte[(int) (dstbytes.length+(len*5))];
131                         System.arraycopy(dstbytes, 0, newbytes, 0, dstbytes.length);
132                         dstbytes = newbytes;
133                     }
134                     System.arraycopy(inbytes, 0, dstbytes, offset, cnt);
135                     offset+=cnt;
136                 }
137                 //merg_100201.1 - Added a close() statement after reading the resource
138
//from the inputstream. I noticed that I couldn't redeploy the app when
139
//it used the ResourceGateway. This simple .close() fixes it.
140
in.close();
141
142                 //when we're done trim off the excess
143
byte[] newbytes = new byte[offset];
144                 System.arraycopy(dstbytes, 0, newbytes, 0, offset);
145                 dstbytes = newbytes;
146
147                 //once we're done reading, create a local resource object
148
if (logger.isDebugEnabled()) logger.debug("Success!");
149                 LocalResource lr = new LocalResource();
150                 lr.contentType = contentType;
151                 lr.contentData = dstbytes;
152                 result = lr;
153             } catch (IOException e) {
154                 if (logger.isDebugEnabled()) logger.debug("Failure: "+e);
155                 result = RESOURCE_NOT_FOUND;
156             }
157             return new SoftReference(result);
158         }
159
160     }
161
162     /**
163      * The actual resource that gets cached
164      */

165     class LocalResource {
166         public String JavaDoc contentType = null;
167         public byte[] contentData = null;
168     }
169
170
171     //-------------------- HTTPServlet ---------------------------
172
/**
173      * <p>By default the GET request is mapped to the handleDefault method
174      *
175      * @param req the servlet request
176      * @param resp the servlet response
177      * @throws ServletException
178      * @throws IOException
179      */

180     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
181         handleDefault(req, resp);
182     }
183
184     /**
185      * <p>By default the POST request is mapped to the handleDefault method
186      *
187      * @param req the servlet request
188      * @param resp the servlet response
189      * @throws ServletException
190      * @throws IOException
191      */

192     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
193         handleDefault(req, resp);
194     }
195
196     //-------------------- Servlet -------------------------------
197
/**
198      * <p>Here's where we initialize the servlet.
199      */

200     public void init() throws ServletException {
201         logger.info("initializing servlet");
202     }
203
204 }
205
Popular Tags