001: /*
002: * This file is part of the WfMOpen project.
003: * Copyright (C) 2001-2006 Danet GmbH (www.danet.de), BU BTS.
004: * All rights reserved.
005: *
006: * This program is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU General Public License as published by
008: * the Free Software Foundation; either version 2 of the License, or
009: * (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: * $Id: MyFacesResourceLoader.java,v 1.3 2006/12/12 09:58:39 drmlipp Exp $
021: *
022: * $Log: MyFacesResourceLoader.java,v $
023: * Revision 1.3 2006/12/12 09:58:39 drmlipp
024: * Added resources and minor cleanup.
025: *
026: * Revision 1.2.4.1 2006/11/08 12:47:02 drmlipp
027: * Started using stylesheet.
028: *
029: * Revision 1.2 2006/10/06 15:26:51 drmlipp
030: * Improved.
031: *
032: * Revision 1.1 2006/10/05 13:27:39 drmlipp
033: * New tag for XML display.
034: *
035: */
036: package de.danet.an.util.jsf.taglib;
037:
038: import java.io.IOException;
039: import java.io.InputStream;
040: import java.util.Calendar;
041:
042: import javax.servlet.ServletContext;
043: import javax.servlet.http.HttpServletRequest;
044: import javax.servlet.http.HttpServletResponse;
045:
046: /**
047: * This class provides the resource loader for this taglib.
048: *
049: * @author Michael Lipp
050: *
051: */
052: public class MyFacesResourceLoader extends
053: org.apache.myfaces.renderkit.html.util.MyFacesResourceLoader {
054:
055: static final String DE_DANET_AN_UTIL_JSF_TAGLIB = "de.danet.an.util.jsf";
056: private static final org.apache.commons.logging.Log logger = org.apache.commons.logging.LogFactory
057: .getLog(MyFacesResourceLoader.class);
058:
059: /**
060: * Given a URI of form "{partial.class.name}/{resourceName}", locate the
061: * specified file within the current classpath and write it to the response
062: * object.
063: * <p>
064: * The partial class name has "de.danet.an.util.jsf.taglib." prepended to it
065: * to form the fully qualified classname. This class object is loaded, and
066: * Class.getResourceAsStream is called on it, passing a uri of "resource/" +
067: * {resourceName}.
068: * <p>
069: * The data written to the response stream includes http headers which
070: * define the mime content-type; this is deduced from the filename suffix of
071: * the resource.
072: * <p>
073: *
074: * @see org.apache.myfaces.shared.renderkit.html.util.ResourceLoader#serveResource
075: * javax.servlet.http.HttpServletRequest,
076: * javax.servlet.http.HttpServletResponse, java.lang.String)
077: */
078: public void serveResource(ServletContext context,
079: HttpServletRequest request, HttpServletResponse response,
080: String resourceUri) throws IOException {
081: String[] uriParts = resourceUri.split("/", 2);
082:
083: String component = uriParts[0];
084: if (component == null || component.trim().length() == 0) {
085: response.sendError(HttpServletResponse.SC_BAD_REQUEST,
086: "Invalid request");
087: logger
088: .error("Could not find parameter for component to load a resource.");
089: return;
090: }
091: Class componentClass;
092: String className = DE_DANET_AN_UTIL_JSF_TAGLIB + "."
093: + component;
094: try {
095: componentClass = loadComponentClass(className);
096: } catch (ClassNotFoundException e) {
097: response.sendError(HttpServletResponse.SC_BAD_REQUEST, e
098: .getMessage());
099: logger.error("Could not find the class for component "
100: + className + " to load a resource.");
101: return;
102: }
103: String resource = uriParts[1];
104: if (resource == null || resource.trim().length() == 0) {
105: response.sendError(HttpServletResponse.SC_BAD_REQUEST,
106: "No resource defined");
107: logger.error("No resource defined component class "
108: + className);
109: return;
110: }
111: resource = "resource/" + resource;
112:
113: InputStream is = componentClass.getResourceAsStream(resource);
114: if (is == null) {
115: response.sendError(HttpServletResponse.SC_NOT_FOUND,
116: "Unable to find resource " + resource
117: + " for component " + component
118: + ". Check that this file is available "
119: + "in the classpath in sub-directory "
120: + "/resource of the package-directory.");
121: logger.error("Unable to find resource " + resource
122: + " for component " + component
123: + ". Check that this file is available "
124: + "in the classpath in sub-directory "
125: + "/resource of the package-directory.");
126: } else {
127: defineContentHeaders(request, response, resource);
128: defineCaching(request, response, resource);
129: writeResource(request, response, is);
130: }
131: }
132:
133: private static long loadTime = System.currentTimeMillis();
134:
135: /**
136: * Get the last-modified time of the resource.
137: * <p>
138: * Unfortunately this is not possible with files inside jars. We therefore
139: * simply use the load time of the application.
140: */
141: private static long getLastModified() {
142: return loadTime;
143: }
144:
145: /**
146: * Output http headers telling the browser (and possibly intermediate
147: * caches) how to cache this data.
148: * <p>
149: * The expiry time in this header info is set to 7 days. This is not a
150: * problem as the overall URI contains a "cache key" that changes whenever
151: * the webapp is redeployed (see AddResource.getCacheKey), meaning that all
152: * browsers will effectively reload files on webapp redeploy.
153: */
154: protected void defineCaching(HttpServletRequest request,
155: HttpServletResponse response, String resource) {
156: response.setDateHeader("Last-Modified", getLastModified());
157:
158: Calendar expires = Calendar.getInstance();
159: expires.add(Calendar.DAY_OF_YEAR, 7);
160: response.setDateHeader("Expires", expires.getTimeInMillis());
161: }
162: }
|