KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > blandware > atleap > webapp > servlet > ResourceServlet


1 /*
2  * Copyright 2004 Blandware (http://www.blandware.com)
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 package com.blandware.atleap.webapp.servlet;
17
18 import com.blandware.atleap.common.Constants;
19 import com.blandware.atleap.common.util.ConvertUtil;
20 import com.blandware.atleap.model.core.ContentDocument;
21 import com.blandware.atleap.model.core.ContentResource;
22 import com.blandware.atleap.model.core.Role;
23 import com.blandware.atleap.service.core.ContentResourceManager;
24 import com.blandware.atleap.webapp.util.core.CacheUtil;
25 import com.blandware.atleap.webapp.util.core.GlobalProperties;
26 import com.blandware.atleap.webapp.util.core.WebappConstants;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.springframework.context.ApplicationContext;
30 import org.springframework.web.context.support.WebApplicationContextUtils;
31
32 import javax.servlet.ServletConfig JavaDoc;
33 import javax.servlet.ServletException JavaDoc;
34 import javax.servlet.http.HttpServlet JavaDoc;
35 import javax.servlet.http.HttpServletRequest JavaDoc;
36 import javax.servlet.http.HttpServletResponse JavaDoc;
37 import java.io.IOException JavaDoc;
38 import java.io.OutputStream JavaDoc;
39 import java.util.ArrayList JavaDoc;
40 import java.util.List JavaDoc;
41 import java.util.StringTokenizer JavaDoc;
42
43 /**
44  * <p>Servlet to return content resource</p>
45  * <p>Following attributes are accepted:
46  * <ul>
47  * <li>
48  * <code>uri</code> -- the URI of resource to obtain (can be passed as a request
49  * parameter or request attribute)
50  * </li>
51  * <li>
52  * <code>view</code> -- whether the resource will be just viewed. This has a
53  * higher precedence than <code>download</code> (can be passed as a request
54  * parameter)
55  * </li>
56  * <li>
57  * <code>download</code> -- whether the resource will be downloaded (can be
58  * passed as a request parameter)
59  * </li>
60  * </ul>
61  * </p>
62  * <p><a HREF="ResourceServlet.java.htm"><i>View Source</i></a></p>
63  *
64  * @author Andrey Grebnev <a HREF="mailto:andrey.grebnev@blandware.com">&lt;andrey.grebnev@blandware.com&gt;</a>
65  * @version $Revision: 1.3 $ $Date: 2005/08/15 09:08:22 $
66  * @web.servlet name="resource" load-on-startup="1"
67  * @web.servlet-mapping url-pattern="/servlet/resource/*"
68  */

69 public class ResourceServlet extends HttpServlet JavaDoc {
70
71     /**
72      * Commons Logging instance.
73      */

74     protected transient final Log log = LogFactory.getLog(ResourceServlet.class);
75
76     /**
77      * Initializes the servlet.
78      */

79     public void init(ServletConfig JavaDoc config) throws ServletException JavaDoc {
80         super.init(config);
81     }
82
83     /**
84      * Destroys the servlet.
85      */

86     public void destroy() {
87         super.destroy();
88     }
89
90     /**
91      * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
92      *
93      * @param request servlet request
94      * @param response servlet response
95      */

96     protected void processRequest(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
97             throws ServletException JavaDoc, IOException JavaDoc {
98         ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
99
100         String JavaDoc uri = null;
101         if ( request.getParameter("uri") != null ) {
102             uri = request.getParameter("uri");
103         } else if ( request.getAttribute("uri") != null ) {
104             uri = (String JavaDoc) request.getAttribute("uri");
105         } else {
106             String JavaDoc message = "Missing 'uri' parameter in the request";
107             if ( log.isWarnEnabled() ) {
108                 log.warn(message);
109             }
110             response.sendError(HttpServletResponse.SC_NOT_FOUND);
111             return;
112         }
113
114         log.debug("URI: " + uri);
115
116         boolean download = request.getParameter("download") != null;
117         boolean view = request.getParameter("view") != null;
118
119         byte[] resourceData = null;
120         String JavaDoc mimeType = null;
121         List JavaDoc roleNames = new ArrayList JavaDoc();
122         String JavaDoc charset = null;
123         long lastModified = -1;
124
125         //try to get from cache
126
CacheUtil cacheUtil = CacheUtil.getInstance(request);
127         CacheUtil.ResourceData rd = cacheUtil.getResourceFromCache(uri);
128
129         if ( rd != null ) {
130             resourceData = rd.getData();
131             //WARNING the resource data can be null if its size is big. We need it in order to allow return SC_NOT_MODIFIED
132
mimeType = rd.getMimeType();
133             roleNames = ConvertUtil.convertStringToList(rd.getRoles(), ",", true);
134             charset = rd.getCharset();
135             lastModified = rd.getLastModified();
136
137             if ( log.isDebugEnabled() ) {
138                 log.debug("Retrieving resource from Cache with mimeType=" + mimeType + " and uri=" + uri + " and roles=" + roleNames.toString());
139             }
140         }
141
142         //check ifnonmatch header
143
if ( request.getMethod().equals("GET") && lastModified != -1 ) {
144             if (processBrowserCache(roleNames, lastModified, request, response))
145                 return;
146         }
147
148
149         if ( resourceData == null ) {
150             //get from DB
151
ContentResourceManager contentResourceManager = (ContentResourceManager) ctx.getBean(Constants.CONTENT_RESOURCE_MANAGER_BEAN);
152             ContentResource contentResource = contentResourceManager.findContentResourceByUri(uri);
153             if ( contentResource == null ) {
154                 if ( log.isErrorEnabled() ) {
155                     log.error("No content resource with uri=" + uri + " could be found");
156                 }
157                 response.sendError(HttpServletResponse.SC_NOT_FOUND);
158                 return;
159             }
160             resourceData = contentResource.getResourceData().getData();
161             mimeType = contentResource.getMimeType();
162             lastModified = contentResource.getLastUpdatedDatetime().getTime();
163
164             if ( contentResource instanceof ContentDocument ) {
165                 charset = ((ContentDocument) contentResource).getCharset();
166             }
167
168             //getting names of roles
169
List JavaDoc roles = contentResource.getRoles();
170             for ( int i = 0; i < roles.size(); i++ ) {
171                 Role role = (Role) roles.get(i);
172                 roleNames.add(role.getName());
173             }
174
175             //put into cache
176
String JavaDoc roleNamesString = null;
177             if ( roleNames.size() > 0 ) {
178                 roleNamesString = ConvertUtil.convertListToString(roleNames, ",");
179             }
180             rd = new CacheUtil.ResourceData(resourceData, mimeType, charset, roleNamesString, lastModified);
181             cacheUtil.putResourceInCache(rd, uri);
182             if ( log.isDebugEnabled() ) {
183                 log.debug("Retrieving resource from DB with mimeType=" + mimeType + " and uri=" + uri);
184             }
185         }
186
187         if (processBrowserCache(roleNames, lastModified, request, response))
188             return;
189
190         //check roles
191
boolean granted = false;
192         if ( roleNames != null && roleNames.size() > 0 ) {
193             for ( int i = 0; i < roleNames.size(); i++ ) {
194                 String JavaDoc roleName = (String JavaDoc) roleNames.get(i);
195                 if ( request.isUserInRole(roleName) ) {
196                     if ( log.isDebugEnabled() ) {
197                         log.debug(" User '" + request.getRemoteUser() +
198                                 "' has role '" + roleName + "', granting access");
199                     }
200                     granted = true;
201                     break;
202                 }
203             }
204         } else {
205             granted = true;
206             if ( log.isDebugEnabled() ) {
207                 log.debug("Anonymous user granting access");
208             }
209         }
210
211         if ( !granted ) {
212             // The current user is not authorized for this action
213
if ( log.isDebugEnabled() ) {
214                 log.debug(" User '" + request.getRemoteUser() +
215                         "' does not have any required role, denying access");
216             }
217             response.sendError(HttpServletResponse.SC_FORBIDDEN);
218             return;
219         }
220
221         String JavaDoc charsetSuffix = "";
222         if ( charset != null ) {
223             charsetSuffix = ";charset=" + charset;
224         }
225
226         if ( !download && !view && mimeType != null ) {
227             response.setContentType(mimeType + charsetSuffix);
228         } else {
229             String JavaDoc filename = "";
230             int slash = uri.lastIndexOf("/");
231             if ( slash >= 0 ) {
232                 filename = uri.substring(slash + 1, uri.length());
233             }
234             if ( (view || (!view && !download)) && mimeType != null ) {
235                 response.setHeader("Content-Disposition", "inline; filename=\"" + filename + "\"");
236                 response.setContentType(mimeType);
237                 response.setContentType(mimeType + charsetSuffix);
238             } else {
239                 response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
240                 response.setContentType("application/octet-stream");
241             }
242             response.setHeader("Content-Transfer-Encoding", "binary");
243         }
244
245         OutputStream JavaDoc out = response.getOutputStream();
246         response.setContentLength(resourceData.length);
247         out.write(resourceData);
248         out.flush();
249         out.close();
250     }
251
252     /**
253      * Sets up cache headers
254      *
255      * @param roleNames List of roles assigned to resource
256      * @param request The request being processed
257      * @param response The response being generated
258      * @return <code>true</code> if we should return SC_NOT_MODIFIED
259      */

260     protected boolean processBrowserCache(List JavaDoc roleNames, long lastModified, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) {
261         //ETag generation
262
String JavaDoc username = request.getRemoteUser();
263         StringBuffer JavaDoc eTagBuffer = new StringBuffer JavaDoc("W/\"").append(username).append("-").append(lastModified).append("\"");
264         String JavaDoc eTag = eTagBuffer.toString();
265         response.setHeader("ETag", eTag);
266
267         boolean conditionSatisfied = false;
268
269         int maxAge = ((Integer JavaDoc)GlobalProperties.getInstance(getServletContext()).getInteger(WebappConstants.CACHE_RESOURCE_MAXAGE_PROPERTY, -1)).intValue();
270         if ( maxAge < 0 ) {
271             response.setHeader("Cache-Control", "no-cache,no-store,max-age=0");
272             response.setHeader("Pragma", "no-cache");
273         } else {
274             String JavaDoc cacheType = "public";
275             if (roleNames.size() != 0) {
276                 cacheType = "private";
277             }
278             response.setHeader("Cache-Control", cacheType + ",max-age="+maxAge);
279             response.setHeader("Pragma", "");
280
281             String JavaDoc headerValue = request.getHeader("If-None-Match");
282             if (headerValue != null) {
283                 if (!headerValue.equals("*")) {
284                     StringTokenizer JavaDoc commaTokenizer =
285                             new StringTokenizer JavaDoc(headerValue, ",");
286                     while (!conditionSatisfied && commaTokenizer.hasMoreTokens()) {
287                         String JavaDoc currentToken = commaTokenizer.nextToken();
288                         if (currentToken.trim().equals(eTag)) {
289                             conditionSatisfied = true;
290                         }
291                     }
292                 } else {
293                     conditionSatisfied = true;
294                 }
295                 if (conditionSatisfied) {
296                     response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
297                 }
298             }
299         }
300
301         return conditionSatisfied;
302
303     }
304
305     /**
306      * Handles the HTTP <code>GET</code> method.
307      *
308      * @param request servlet request
309      * @param response servlet response
310      */

311     protected void doGet(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
312             throws ServletException JavaDoc, IOException JavaDoc {
313         processRequest(request, response);
314     }
315
316     /**
317      * Handles the HTTP <code>POST</code> method.
318      *
319      * @param request servlet request
320      * @param response servlet response
321      */

322     protected void doPost(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
323             throws ServletException JavaDoc, IOException JavaDoc {
324         processRequest(request, response);
325     }
326
327     /**
328      * Returns a short description of the servlet.
329      */

330     public String JavaDoc getServletInfo() {
331         return "Servlet to return content resource";
332     }
333
334 }
Popular Tags