01: package pygmy.handlers;
02:
03: import pygmy.core.*;
04:
05: import java.io.IOException;
06: import java.io.InputStream;
07: import java.util.logging.Logger;
08: import java.util.logging.Level;
09:
10: /**
11: * <p>
12: * This serves up files from the class path. Usually this is used to serve files from within a jar file that is
13: * within the classpath of the application running. However, you could serve up files from anywhere in the classpath,
14: * no just jar files. This makes it easy to package part of your web content inside a jar file for easy distribution,
15: * but make it transparently available without the user needing to extract the content from the jar file. This is
16: * great for static or default content that you don't want users to have to manage. By putting a FileHandler and a
17: * ResourceHandler in a chain filtering on the same url-prefix, you can allow users to override or augment content
18: * from the jar file by placing the same file on the file system, but load the default from the jar file if the file
19: * not on the file system.
20: * </p>
21: *
22: * <table class="inner">
23: * <tr class="header"><td>Parameter Name</td><td>Explanation</td><td>Default Value</td><td>Required</td></tr>
24: * <tr class="row"><td>url-prefix</td><td>The prefix to filter request urls.</td><td>None</td><td>Yes</td></tr>
25: * <tr class="altrow"><td>resourceMount</td><td>A path within the classpath to the root of the folder to share.
26: * The requested url minus the url-prefix will be added to this path to yield the path loaded from the classpath.
27: * </td><td>None</td><td>Yes</td></tr>
28: * <tr class="row"><td>default</td><td>The name of the default resource that should be used if no file is specified in the URL. ( like index.html )</td><td>index.html</td><td>No</td></tr>
29: * </table>
30: */
31: public class ResourceHandler extends AbstractHandler implements Handler {
32: private static final Logger log = Logger
33: .getLogger(ResourceHandler.class.getName());
34:
35: public static final ConfigOption RESOURCE_MOUNT_OPTION = new ConfigOption(
36: "resourceMount", "/",
37: "A path within the classpath to the root of the folder to share.");
38: public static final ConfigOption DEFAULT_RESOURCE_OPTION = new ConfigOption(
39: "default", "index.html", "The default resource name.");
40:
41: private String resourceMount;
42: private String defaultResource;
43:
44: public boolean initialize(String handlerName, Server server) {
45: super .initialize(handlerName, server);
46: this .resourceMount = RESOURCE_MOUNT_OPTION.getProperty(server,
47: handlerName);
48: this .defaultResource = DEFAULT_RESOURCE_OPTION.getProperty(
49: server, handlerName);
50: return true;
51: }
52:
53: protected boolean handleBody(HttpRequest request,
54: HttpResponse response) throws IOException {
55: String resource = Http.join(resourceMount, request.getUrl()
56: .substring(getUrlPrefix().length()));
57: if (resource.endsWith("/")) {
58: resource += defaultResource;
59: } else if (resource.lastIndexOf('.') < 0) {
60: resource += "/" + defaultResource;
61: }
62: if (log.isLoggable(Level.INFO)) {
63: log.info("Loading resource: " + resource);
64: }
65: String mimeType = getMimeType(resource);
66: InputStream is = getClass().getResourceAsStream(resource);
67:
68: if (mimeType == null || is == null) {
69: log
70: .warning("Resource was not found or the mime type was not understood. (Found file="
71: + (is != null)
72: + ") (Found mime-type="
73: + (mimeType != null) + ")");
74: return false;
75: }
76: response.setMimeType(mimeType);
77: response.sendResponse(is, -1);
78: return true;
79: }
80:
81: }
|