001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. The ASF licenses this file to You
004: * under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License. For additional information regarding
015: * copyright in this work, please see the NOTICE file in the top level
016: * directory of this distribution.
017: */
018:
019: package org.apache.roller.ui.rendering.servlets;
020:
021: import java.io.File;
022: import java.io.FileInputStream;
023: import java.io.IOException;
024: import java.io.InputStream;
025: import java.io.OutputStream;
026: import javax.servlet.ServletConfig;
027: import javax.servlet.ServletContext;
028: import javax.servlet.ServletException;
029: import javax.servlet.http.HttpServlet;
030: import javax.servlet.http.HttpServletRequest;
031: import javax.servlet.http.HttpServletResponse;
032: import org.apache.commons.logging.Log;
033: import org.apache.commons.logging.LogFactory;
034: import org.apache.roller.RollerException;
035: import org.apache.roller.business.FileManager;
036: import org.apache.roller.business.RollerFactory;
037: import org.apache.roller.business.ThemeManager;
038: import org.apache.roller.pojos.Theme;
039: import org.apache.roller.pojos.WeblogResource;
040: import org.apache.roller.pojos.WebsiteData;
041: import org.apache.roller.ui.rendering.util.ModDateHeaderUtil;
042: import org.apache.roller.ui.rendering.util.WeblogPreviewResourceRequest;
043:
044: /**
045: * Special previewing servlet which serves files uploaded by users as well as
046: * static resources in shared themes. This servlet differs from the normal
047: * ResourceServlet because it can accept urls parameters which affect how it
048: * behaves which are used for previewing.
049: *
050: * @web.servlet name="PreviewResourceServlet" load-on-startup="9"
051: * @web.servlet-mapping url-pattern="/roller-ui/authoring/previewresource/*"
052: */
053: public class PreviewResourceServlet extends HttpServlet {
054:
055: private static Log log = LogFactory
056: .getLog(PreviewResourceServlet.class);
057:
058: private ServletContext context = null;
059:
060: public void init(ServletConfig config) throws ServletException {
061:
062: super .init(config);
063:
064: log.info("Initializing PreviewResourceServlet");
065:
066: this .context = config.getServletContext();
067: }
068:
069: /**
070: * Handles requests for user uploaded resources.
071: */
072: public void doGet(HttpServletRequest request,
073: HttpServletResponse response) throws ServletException,
074: IOException {
075:
076: WebsiteData weblog = null;
077: String context = request.getContextPath();
078: String servlet = request.getServletPath();
079: String reqURI = request.getRequestURI();
080:
081: WeblogPreviewResourceRequest resourceRequest = null;
082: try {
083: // parse the incoming request and extract the relevant data
084: resourceRequest = new WeblogPreviewResourceRequest(request);
085:
086: weblog = resourceRequest.getWeblog();
087: if (weblog == null) {
088: throw new RollerException("unable to lookup weblog: "
089: + resourceRequest.getWeblogHandle());
090: }
091:
092: } catch (Exception e) {
093: // invalid resource request or weblog doesn't exist
094: log.debug("error creating weblog resource request", e);
095: response.sendError(HttpServletResponse.SC_NOT_FOUND);
096: return;
097: }
098:
099: log.debug("Resource requested ["
100: + resourceRequest.getResourcePath() + "]");
101:
102: long resourceLastMod = 0;
103: InputStream resourceStream = null;
104:
105: // first, see if we have a preview theme to operate from
106: if (resourceRequest.getThemeName() != null) {
107: Theme theme = resourceRequest.getTheme();
108: File resource = theme.getResource(resourceRequest
109: .getResourcePath());
110: resourceLastMod = resource.lastModified();
111: resourceStream = new FileInputStream(resource);
112: }
113:
114: // second, see if resource comes from weblog's configured shared theme
115: if (resourceStream == null
116: && !Theme.CUSTOM.equals(weblog.getEditorTheme())) {
117: try {
118: ThemeManager themeMgr = RollerFactory.getRoller()
119: .getThemeManager();
120: Theme weblogTheme = themeMgr.getTheme(weblog
121: .getEditorTheme());
122: File resource = weblogTheme.getResource(resourceRequest
123: .getResourcePath());
124: if (resource != null) {
125: resourceLastMod = resource.lastModified();
126: resourceStream = new FileInputStream(resource);
127: }
128: } catch (Exception ex) {
129: // hmmm, some kind of error getting theme. that's an error.
130: response
131: .sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
132: return;
133: }
134: }
135:
136: // if not from theme then see if resource is in weblog's upload dir
137: if (resourceStream == null) {
138: try {
139: FileManager fileMgr = RollerFactory.getRoller()
140: .getFileManager();
141: WeblogResource resource = fileMgr.getFile(weblog,
142: resourceRequest.getResourcePath());
143: resourceLastMod = resource.getLastModified();
144: resourceStream = resource.getInputStream();
145: } catch (Exception ex) {
146: // still not found? then we don't have it, 404.
147: log.debug("Unable to get resource", ex);
148: response.sendError(HttpServletResponse.SC_NOT_FOUND);
149: return;
150: }
151: }
152:
153: // Respond with 304 Not Modified if it is not modified.
154: if (ModDateHeaderUtil.respondIfNotModified(request, response,
155: resourceLastMod)) {
156: return;
157: } else {
158: // set last-modified date
159: ModDateHeaderUtil.setLastModifiedHeader(response,
160: resourceLastMod);
161: }
162:
163: // set the content type based on whatever is in our web.xml mime defs
164: response.setContentType(this .context
165: .getMimeType(resourceRequest.getResourcePath()));
166:
167: OutputStream out = null;
168: try {
169: // ok, lets serve up the file
170: byte[] buf = new byte[8192];
171: int length = 0;
172: out = response.getOutputStream();
173: while ((length = resourceStream.read(buf)) > 0) {
174: out.write(buf, 0, length);
175: }
176:
177: // cleanup
178: out.close();
179: resourceStream.close();
180:
181: } catch (Exception ex) {
182: log.error("Error writing resource file", ex);
183: if (!response.isCommitted()) {
184: response.reset();
185: response
186: .sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
187: }
188: }
189:
190: }
191:
192: }
|