KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > equinox > http > servlet > internal > ResourceRegistration


1 /*******************************************************************************
2  * Copyright (c) 2005-2007 Cognos Incorporated, IBM Corporation and others
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * Cognos Incorporated - initial API and implementation
10  * IBM Corporation - bug fixes and enhancements
11  *******************************************************************************/

12 package org.eclipse.equinox.http.servlet.internal;
13
14 import java.io.*;
15 import java.net.URL JavaDoc;
16 import java.net.URLConnection JavaDoc;
17 import java.security.*;
18 import javax.servlet.ServletContext JavaDoc;
19 import javax.servlet.http.HttpServletRequest JavaDoc;
20 import javax.servlet.http.HttpServletResponse JavaDoc;
21 import org.osgi.service.http.HttpContext;
22
23 public class ResourceRegistration extends Registration {
24     private static final String JavaDoc LAST_MODIFIED = "Last-Modified"; //$NON-NLS-1$
25
private static final String JavaDoc IF_MODIFIED_SINCE = "If-Modified-Since"; //$NON-NLS-1$
26
private static final String JavaDoc IF_NONE_MATCH = "If-None-Match"; //$NON-NLS-1$
27
private static final String JavaDoc ETAG = "ETag"; //$NON-NLS-1$
28

29     private String JavaDoc internalName;
30     HttpContext httpContext;
31     ServletContext JavaDoc servletContext;
32     private AccessControlContext acc;
33
34     public ResourceRegistration(String JavaDoc internalName, HttpContext context, ServletContext JavaDoc servletContext, AccessControlContext acc) {
35         this.internalName = internalName;
36         if (internalName.equals("/")) { //$NON-NLS-1$
37
this.internalName = ""; //$NON-NLS-1$
38
}
39         this.httpContext = context;
40         this.servletContext = servletContext;
41         this.acc = acc;
42     }
43
44     public boolean handleRequest(HttpServletRequest JavaDoc req, final HttpServletResponse JavaDoc resp, String JavaDoc alias) throws IOException {
45         if (httpContext.handleSecurity(req, resp)) {
46
47             String JavaDoc method = req.getMethod();
48             if (method.equals("GET") || method.equals("POST") || method.equals("HEAD")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
49

50                 String JavaDoc pathInfo = HttpServletRequestAdaptor.getDispatchPathInfo(req);
51                 int aliasLength = alias.equals("/") ? 0 : alias.length(); //$NON-NLS-1$
52
String JavaDoc resourcePath = internalName + pathInfo.substring(aliasLength);
53                 URL JavaDoc testURL = httpContext.getResource(resourcePath);
54                 if (testURL == null || resourcePath.endsWith("/")) { //$NON-NLS-1$
55
return false;
56                 }
57                 return writeResource(req, resp, resourcePath);
58             }
59             resp.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
60         }
61         return true;
62     }
63
64     private boolean writeResource(final HttpServletRequest JavaDoc req, final HttpServletResponse JavaDoc resp, final String JavaDoc resourcePath) throws IOException {
65         Boolean JavaDoc result = Boolean.TRUE;
66         try {
67             result = (Boolean JavaDoc) AccessController.doPrivileged(new PrivilegedExceptionAction() {
68
69                 public Object JavaDoc run() throws Exception JavaDoc {
70                     URL JavaDoc url = httpContext.getResource(resourcePath);
71                     if (url == null)
72                         return Boolean.FALSE;
73
74                     URLConnection JavaDoc connection = url.openConnection();
75                     long lastModified = connection.getLastModified();
76                     int contentLength = connection.getContentLength();
77
78                     // check to ensure that we're dealing with a real resource and in particular not a directory
79
if (contentLength <= 0)
80                         return Boolean.FALSE;
81
82                     String JavaDoc etag = null;
83                     if (lastModified != -1 && contentLength != -1)
84                         etag = "W/\"" + contentLength + "-" + lastModified + "\""; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
85

86                     // Check for cache revalidation.
87
// We should prefer ETag validation as the guarantees are stronger and all HTTP 1.1 clients should be using it
88
String JavaDoc ifNoneMatch = req.getHeader(IF_NONE_MATCH);
89                     if (ifNoneMatch != null && etag != null && ifNoneMatch.indexOf(etag) != -1) {
90                         resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
91                         return Boolean.TRUE;
92                     } else {
93                         long ifModifiedSince = req.getDateHeader(IF_MODIFIED_SINCE);
94                         // for purposes of comparison we add 999 to ifModifiedSince since the fidelity
95
// of the IMS header generally doesn't include milli-seconds
96
if (ifModifiedSince > -1 && lastModified > 0 && lastModified <= (ifModifiedSince + 999)) {
97                             resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
98                             return Boolean.TRUE;
99                         }
100                     }
101
102                     // return the full contents regularly
103
if (contentLength != -1)
104                         resp.setContentLength(contentLength);
105
106                     String JavaDoc contentType = httpContext.getMimeType(resourcePath);
107                     if (contentType == null)
108                         contentType = servletContext.getMimeType(resourcePath);
109
110                     if (contentType != null)
111                         resp.setContentType(contentType);
112
113                     if (lastModified > 0)
114                         resp.setDateHeader(LAST_MODIFIED, lastModified);
115
116                     if (etag != null)
117                         resp.setHeader(ETAG, etag);
118
119                     try {
120                         OutputStream os = resp.getOutputStream();
121                         int writtenContentLength = writeResourceToOutputStream(connection, os);
122                         if (contentLength == -1 || contentLength != writtenContentLength)
123                             resp.setContentLength(writtenContentLength);
124                     } catch (IllegalStateException JavaDoc e) { // can occur if the response output is already open as a Writer
125
Writer writer = resp.getWriter();
126                         writeResourceToWriter(connection, writer);
127                         // Since ContentLength is a measure of the number of bytes contained in the body
128
// of a message when we use a Writer we lose control of the exact byte count and
129
// defer the problem to the Servlet Engine's Writer implementation.
130
}
131                     return Boolean.TRUE;
132                 }
133             }, acc);
134         } catch (PrivilegedActionException e) {
135             throw (IOException) e.getException();
136         }
137         return result.booleanValue();
138     }
139
140     int writeResourceToOutputStream(URLConnection JavaDoc connection, OutputStream os) throws IOException {
141         InputStream is = connection.getInputStream();
142         try {
143             byte[] buffer = new byte[8192];
144             int bytesRead = is.read(buffer);
145             int writtenContentLength = 0;
146             while (bytesRead != -1) {
147                 os.write(buffer, 0, bytesRead);
148                 writtenContentLength += bytesRead;
149                 bytesRead = is.read(buffer);
150             }
151             return writtenContentLength;
152         } finally {
153             if (is != null)
154                 is.close();
155         }
156     }
157
158     void writeResourceToWriter(URLConnection JavaDoc connection, Writer writer) throws IOException {
159         InputStream is = connection.getInputStream();
160         try {
161             Reader reader = new InputStreamReader(connection.getInputStream());
162             try {
163                 char[] buffer = new char[8192];
164                 int charsRead = reader.read(buffer);
165                 while (charsRead != -1) {
166                     writer.write(buffer, 0, charsRead);
167                     charsRead = reader.read(buffer);
168                 }
169             } finally {
170                 if (reader != null) {
171                     reader.close(); // will also close input stream
172
is = null;
173                 }
174             }
175         } finally {
176             if (is != null)
177                 is.close();
178         }
179     }
180 }
181
Popular Tags