001: /*
002: * Copyright (c) 2002-2003 by OpenSymphony
003: * All rights reserved.
004: */
005: /*
006: * Created on 27/08/2003
007: *
008: */
009: package com.opensymphony.webwork.views.freemarker;
010:
011: import com.opensymphony.webwork.RequestUtils;
012: import com.opensymphony.webwork.ServletActionContext;
013: import com.opensymphony.xwork.util.OgnlValueStack;
014: import freemarker.template.*;
015:
016: import javax.servlet.ServletContext;
017: import javax.servlet.ServletException;
018: import javax.servlet.http.HttpServlet;
019: import javax.servlet.http.HttpServletRequest;
020: import javax.servlet.http.HttpServletResponse;
021: import java.io.FileNotFoundException;
022: import java.io.IOException;
023: import java.util.Locale;
024:
025: /**
026: * @author CameronBraid
027: * @deprecated Please use the FreemarkerResult result type instead
028: */
029: public class FreemarkerServlet extends HttpServlet {
030:
031: protected Configuration configuration;
032:
033: /**
034: *
035: */
036: public FreemarkerServlet() {
037: super ();
038: }
039:
040: final public void doGet(HttpServletRequest request,
041: HttpServletResponse response) throws ServletException,
042: IOException {
043: request.setAttribute("webwork.freemarker.servlet", this );
044: process(request, response);
045: }
046:
047: final public void doPost(HttpServletRequest request,
048: HttpServletResponse response) throws ServletException,
049: IOException {
050: request.setAttribute("webwork.freemarker.servlet", this );
051: process(request, response);
052: }
053:
054: public void init() throws ServletException {
055: try {
056: configuration = createConfiguration();
057: } catch (TemplateException e) {
058: throw new ServletException(
059: "could not configure Freemarker", e);
060: }
061: }
062:
063: /**
064: * This method is called from process() to obtain the
065: * FreeMarker object wrapper object that this result will use
066: * for adapting objects into
067: * template models.. This is a hook that allows you
068: * to custom-configure the wrapper object in a subclass.
069: * <p/>
070: * <b>
071: * The default implementation returns @see Configuration#getObjectWrapper()
072: * </b>
073: */
074: protected ObjectWrapper getObjectWrapper() {
075: return configuration.getObjectWrapper();
076: }
077:
078: protected Configuration createConfiguration()
079: throws TemplateException {
080: return FreemarkerManager.getInstance().getConfiguration(
081: getServletContext());
082: }
083:
084: protected TemplateModel createModel(ObjectWrapper wrapper,
085: ServletContext servletContext, HttpServletRequest request,
086: HttpServletResponse response) throws TemplateModelException {
087:
088: OgnlValueStack stack = ServletActionContext.getContext()
089: .getValueStack();
090: Object action = null;
091: if (ServletActionContext.getContext().getActionInvocation() != null) {
092: action = ServletActionContext.getContext()
093: .getActionInvocation().getAction();
094: }
095: TemplateModel model = FreemarkerManager.getInstance()
096: .buildTemplateModel(stack, action, servletContext,
097: request, response, wrapper);
098: return model;
099: }
100:
101: /**
102: * Returns the locale used for the
103: * {@link Configuration#getTemplate(String, Locale)} call.
104: * The base implementation simply returns the locale setting of the
105: * configuration. Override this method to provide different behaviour, i.e.
106: * to use the locale indicated in the request.
107: */
108: protected Locale deduceLocale(String templatePath,
109: HttpServletRequest request, HttpServletResponse response) {
110: return configuration.getLocale();
111: }
112:
113: /**
114: * Called after the execution returns from template.process().
115: * This is a generic hook you might use in subclasses to perform a specific
116: * action after the template is processed. It will be invoked even if the
117: * template processing throws an exception. By default does nothing.
118: *
119: * @param request the actual HTTP request
120: * @param response the actual HTTP response
121: * @param template the template that was executed
122: * @param data the data that was passed to the template
123: */
124: protected void postTemplateProcess(HttpServletRequest request,
125: HttpServletResponse response, Template template,
126: TemplateModel data) throws ServletException, IOException {
127: }
128:
129: // /**
130: // * If the parameter "nocache" was set to true, generate a set of headers
131: // * that will advise the HTTP client not to cache the returned page.
132: // */
133: // private void setBrowserCachingPolicy(HttpServletResponse response)
134: // {
135: // if (nocache)
136: // {
137: // // HTTP 1.1 browsers should defeat caching on this header
138: // response.setHeader("Cache-Control", "no-cache");
139: // // HTTP 1.0 browsers should defeat caching on this header
140: // response.setHeader("Pragma", "no-cache");
141: // // Last resort for those that ignore all of the above
142: // response.setHeader("Expires", EXPIRATION_DATE);
143: // }
144: // }
145:
146: /**
147: * Called before the execution is passed to template.process().
148: * This is a generic hook you might use in subclasses to perform a specific
149: * action before the template is processed. By default does nothing.
150: * A typical action to perform here is to inject application-specific
151: * objects into the model root
152: *
153: * @param request the actual HTTP request
154: * @param response the actual HTTP response
155: * @param template the template that will get executed
156: * @param data the data that will be passed to the template
157: * @return true to process the template, false to suppress template processing.
158: */
159: protected boolean preTemplateProcess(HttpServletRequest request,
160: HttpServletResponse response, Template template,
161: TemplateModel data) throws ServletException, IOException {
162: return true;
163: }
164:
165: /**
166: * Maps the request URL to a template path that is passed to
167: * {@link Configuration#getTemplate(String, Locale)}. You can override it
168: * (i.e. to provide advanced rewriting capabilities), but you are strongly
169: * encouraged to call the overridden method first, then only modify its
170: * return value.
171: *
172: * @param request the currently processed request
173: * @return a String representing the template path
174: */
175: protected String requestUrlToTemplatePath(HttpServletRequest request) {
176: // First, see if it is an included request
177: String includeServletPath = (String) request
178: .getAttribute("javax.servlet.include.servlet_path");
179:
180: if (includeServletPath != null) {
181: // Try path info; only if that's null (servlet is mapped to an
182: // URL extension instead of to prefix) use servlet path.
183: String includePathInfo = (String) request
184: .getAttribute("javax.servlet.include.path_info");
185:
186: return (includePathInfo == null) ? includeServletPath
187: : includePathInfo;
188: }
189:
190: // Seems that the servlet was not called as the result of a
191: // RequestDispatcher.include(...). Try pathInfo then servletPath again,
192: // only now directly on the request object:
193: String path = request.getPathInfo();
194:
195: if (path != null) {
196: return path;
197: }
198:
199: path = RequestUtils.getServletPath(request);
200:
201: if (path != null) {
202: return path;
203: }
204:
205: // Seems that it is a servlet mapped with prefix, and there was no extra path info.
206: return "";
207: }
208:
209: private void process(HttpServletRequest request,
210: HttpServletResponse response) throws ServletException,
211: IOException {
212: String path = requestUrlToTemplatePath(request);
213:
214: Template template = null;
215:
216: try {
217: template = configuration.getTemplate(path, deduceLocale(
218: path, request, response));
219: } catch (FileNotFoundException e) {
220: response.sendError(HttpServletResponse.SC_NOT_FOUND);
221:
222: return;
223: }
224:
225: Object attrContentType = template
226: .getCustomAttribute("content_type");
227:
228: if (attrContentType != null) {
229: response.setContentType(attrContentType.toString());
230: } else {
231: response.setContentType("text/html; charset="
232: + template.getEncoding());
233: }
234:
235: // // Set cache policy
236: // setBrowserCachingPolicy(response);
237: ServletContext servletContext = getServletContext();
238:
239: try {
240: TemplateModel model = createModel(getObjectWrapper(),
241: servletContext, request, response);
242:
243: // Give subclasses a chance to hook into preprocessing
244: if (preTemplateProcess(request, response, template, model)) {
245: try {
246: // Process the template
247: template.process(model, response.getWriter());
248: } finally {
249: // Give subclasses a chance to hook into postprocessing
250: postTemplateProcess(request, response, template,
251: model);
252: }
253: }
254: } catch (TemplateException te) {
255: // only throw a servlet exception if not a debug handler
256: // this is what the original freemarker.ext.servlet.FreemarkerServlet does
257: if ((configuration.getTemplateExceptionHandler() != freemarker.template.TemplateExceptionHandler.HTML_DEBUG_HANDLER)
258: && (configuration.getTemplateExceptionHandler() != freemarker.template.TemplateExceptionHandler.DEBUG_HANDLER)) {
259: throw new ServletException(te);
260: }
261: }
262: }
263: }
|