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.IOException;
022: import java.util.HashMap;
023: import java.util.Map;
024: import javax.servlet.ServletConfig;
025: import javax.servlet.ServletException;
026: import javax.servlet.http.HttpServlet;
027: import javax.servlet.http.HttpServletRequest;
028: import javax.servlet.http.HttpServletResponse;
029: import javax.servlet.jsp.JspFactory;
030: import javax.servlet.jsp.PageContext;
031: import org.apache.commons.logging.Log;
032: import org.apache.commons.logging.LogFactory;
033: import org.apache.roller.RollerException;
034: import org.apache.roller.config.RollerConfig;
035: import org.apache.roller.config.RollerRuntimeConfig;
036: import org.apache.roller.pojos.Template;
037: import org.apache.roller.pojos.Theme;
038: import org.apache.roller.pojos.WebsiteData;
039: import org.apache.roller.ui.core.RollerContext;
040: import org.apache.roller.util.cache.CachedContent;
041: import org.apache.roller.ui.rendering.Renderer;
042: import org.apache.roller.ui.rendering.RendererManager;
043: import org.apache.roller.ui.rendering.model.ModelLoader;
044: import org.apache.roller.ui.rendering.util.WeblogPreviewRequest;
045:
046: /**
047: * Responsible for rendering weblog page previews.
048: *
049: * This servlet is used as part of the authoring interface to provide previews
050: * of what a weblog will look like with a given theme. It is not available
051: * outside of the authoring interface.
052: *
053: * @web.servlet name="PreviewServlet" load-on-startup="9"
054: * @web.servlet-mapping url-pattern="/roller-ui/authoring/preview/*"
055: */
056: public class PreviewServlet extends HttpServlet {
057:
058: private static Log log = LogFactory.getLog(PreviewServlet.class);
059:
060: /**
061: * Init method for this servlet
062: */
063: public void init(ServletConfig servletConfig)
064: throws ServletException {
065:
066: super .init(servletConfig);
067:
068: log.info("Initializing PreviewServlet");
069: }
070:
071: /**
072: * Handle GET requests for weblog pages.
073: */
074: public void doGet(HttpServletRequest request,
075: HttpServletResponse response) throws ServletException,
076: IOException {
077:
078: log.debug("Entering");
079:
080: WebsiteData weblog = null;
081:
082: WeblogPreviewRequest previewRequest = null;
083: try {
084: previewRequest = new WeblogPreviewRequest(request);
085:
086: // lookup weblog specified by preview request
087: weblog = previewRequest.getWeblog();
088: if (weblog == null) {
089: throw new RollerException("unable to lookup weblog: "
090: + previewRequest.getWeblogHandle());
091: }
092: } catch (Exception e) {
093: // some kind of error parsing the request or getting weblog
094: log.error("error creating preview request", e);
095: response.sendError(HttpServletResponse.SC_NOT_FOUND);
096: return;
097: }
098:
099: // try getting the preview theme
100: log.debug("preview theme = " + previewRequest.getThemeName());
101: Theme previewTheme = previewRequest.getTheme();
102:
103: // construct a temporary Website object for this request
104: // and set the EditorTheme to our previewTheme
105: WebsiteData tmpWebsite = new WebsiteData();
106: tmpWebsite.setData(weblog);
107: if (previewTheme != null && previewTheme.isEnabled()) {
108: tmpWebsite.setEditorTheme(previewTheme.getName());
109: } else if (Theme.CUSTOM.equals(previewRequest.getThemeName())) {
110: tmpWebsite.setEditorTheme(Theme.CUSTOM);
111: }
112:
113: // we've got to set the weblog in our previewRequest because that's
114: // the object that gets referenced during rendering operations
115: previewRequest.setWeblog(tmpWebsite);
116:
117: Template page = null;
118: try {
119: // we just want to show the default view
120: page = tmpWebsite.getDefaultPage();
121:
122: if (page == null) {
123: throw new RollerException(
124: "No default page for weblog: "
125: + tmpWebsite.getHandle());
126: }
127: } catch (RollerException re) {
128: // couldn't get page
129: response
130: .sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
131: log.error("Error getting default page for preview", re);
132: return;
133: }
134:
135: log.debug("preview page found, dealing with it");
136:
137: // set the content type
138: String pageLink = previewRequest.getWeblogPageName();
139: String mimeType = pageLink != null ? RollerContext
140: .getServletContext().getMimeType(pageLink) : null;
141: String contentType = "text/html; charset=utf-8";
142: if (mimeType != null) {
143: // we found a match ... set the content type
144: contentType = mimeType + "; charset=utf-8";
145: } else if ("_css".equals(previewRequest.getWeblogPageName())) {
146: // TODO: store content-type for each page so this hack is unnecessary
147: contentType = "text/css; charset=utf-8";
148: }
149:
150: // looks like we need to render content
151: Map model = new HashMap();
152: try {
153: PageContext pageContext = JspFactory.getDefaultFactory()
154: .getPageContext(this , request, response, "", false,
155: 8192, true);
156:
157: // special hack for menu tag
158: request.setAttribute("pageRequest", previewRequest);
159:
160: // populate the rendering model
161: Map initData = new HashMap();
162: initData.put("request", request);
163: initData.put("weblogRequest", previewRequest);
164: initData.put("pageContext", pageContext);
165:
166: // Load models for page previewing
167: String pageModels = RollerConfig
168: .getProperty("rendering.previewModels");
169: ModelLoader.loadModels(pageModels, model, initData, true);
170:
171: // Load special models for site-wide blog
172: if (RollerRuntimeConfig
173: .isSiteWideWeblog(weblog.getHandle())) {
174: String siteModels = RollerConfig
175: .getProperty("rendering.siteModels");
176: ModelLoader.loadModels(siteModels, model, initData,
177: true);
178: }
179:
180: // Load weblog custom models
181: ModelLoader.loadCustomModels(weblog, model, initData);
182:
183: // ick, gotta load pre-3.0 model stuff as well :(
184: ModelLoader.loadOldModels(model, request, response,
185: pageContext, previewRequest);
186:
187: } catch (RollerException ex) {
188: log.error("ERROR loading model for page", ex);
189:
190: if (!response.isCommitted())
191: response.reset();
192: response
193: .sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
194: return;
195: }
196:
197: // lookup Renderer we are going to use
198: Renderer renderer = null;
199: try {
200: log.debug("Looking up renderer");
201: renderer = RendererManager.getRenderer(page);
202: } catch (Exception e) {
203: // nobody wants to render my content :(
204: log.error(
205: "Couldn't find renderer for page " + page.getId(),
206: e);
207:
208: if (!response.isCommitted())
209: response.reset();
210: response.sendError(HttpServletResponse.SC_NOT_FOUND);
211: return;
212: }
213:
214: // render content. use default size of about 24K for a standard page
215: CachedContent rendererOutput = new CachedContent(24567);
216: try {
217: log.debug("Doing rendering");
218: renderer.render(model, rendererOutput.getCachedWriter());
219:
220: // flush rendered output and close
221: rendererOutput.flush();
222: rendererOutput.close();
223: } catch (Exception e) {
224: // bummer, error during rendering
225: log.error(
226: "Error during rendering for page " + page.getId(),
227: e);
228:
229: if (!response.isCommitted())
230: response.reset();
231: response.sendError(HttpServletResponse.SC_NOT_FOUND);
232: return;
233: }
234:
235: // post rendering process
236:
237: // flush rendered content to response
238: log.debug("Flushing response output");
239: response.setContentType(contentType);
240: response.setContentLength(rendererOutput.getContent().length);
241: response.getOutputStream().write(rendererOutput.getContent());
242:
243: log.debug("Exiting");
244: }
245:
246: }
|