| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
| TemplateServlet |
|
| 3.4444444444444446;3.444 |
| 1 | /* | |
| 2 | * @(#)TemplateServlet.java | |
| 3 | * | |
| 4 | * Copyright (c) 1995-2000 Open Doors Software, Inc. All Rights Reserved. | |
| 5 | * | |
| 6 | * This software is the confidential and proprietary information of Open Doors Software | |
| 7 | * Inc. ("Confidential Information"). You shall not | |
| 8 | * disclose such Confidential Information and shall use it only in | |
| 9 | * accordance with the terms of the license agreement you entered into | |
| 10 | * with Open Doors Software. | |
| 11 | * | |
| 12 | * Open Doors Software MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE | |
| 13 | * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | |
| 14 | * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | |
| 15 | * PURPOSE, OR NON-INFRINGEMENT. OPEN DOORS SOFTWARE SHALL NOT BE LIABLE FOR ANY DAMAGES | |
| 16 | * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING | |
| 17 | * THIS SOFTWARE OR ITS DERIVATIVES. | |
| 18 | * | |
| 19 | * | |
| 20 | */ | |
| 21 | package org.webmacro.servlet; | |
| 22 | ||
| 23 | import javax.servlet.ServletConfig; | |
| 24 | import javax.servlet.ServletException; | |
| 25 | import javax.servlet.http.HttpServlet; | |
| 26 | import javax.servlet.http.HttpServletRequest; | |
| 27 | import javax.servlet.http.HttpServletResponse; | |
| 28 | ||
| 29 | import org.slf4j.Logger; | |
| 30 | ||
| 31 | import org.webmacro.Context; | |
| 32 | import org.webmacro.util.Settings; | |
| 33 | import org.webmacro.util.WMEval; | |
| 34 | ||
| 35 | /** | |
| 36 | * <p> | |
| 37 | * TemplateServlet provides a servlet to evaluate templates directly as long | |
| 38 | * as the template type or types is mapped to this servlet. (Yes, you can | |
| 39 | * map more than one type in a web.xml file to the same servlet). | |
| 40 | * </p> | |
| 41 | * <p> | |
| 42 | * TemplateServlet offers delegation and global processing. You do not need to subclass | |
| 43 | * this servlet. Implement ServletRouter by setting a configuration attribute. | |
| 44 | * Populate the context in a delegate, not a subclass. | |
| 45 | * This servlet provides pre-processing of a | |
| 46 | * global and request-level template. | |
| 47 | * On servlet initialization, a global template is evaluated once. (This can be refreshed). | |
| 48 | * Since the template may just be creating static blocks, these blocks are then automatically | |
| 49 | * in the context under the name you assign for global processing. Therefore, in your | |
| 50 | * template, you could refer to $Global.CreditCardForm with parameters and evaluate that | |
| 51 | * form as a block. See the wiki page BlockLevelExpressionism for more information on this. | |
| 52 | * Similarly, if your configuration of this servlet specifies a per-Request level template, | |
| 53 | * it will be evaluated and the context placed into the working context prior to evaluation | |
| 54 | * of the actual template. | |
| 55 | * </p> | |
| 56 | * <p> | |
| 57 | * These configuration options make it possible to create automatically | |
| 58 | * a global context and a per request context. | |
| 59 | * A global context means that there is no longer any processing | |
| 60 | * associated with the globals: it is evaluated once. A per-request means that | |
| 61 | * you can always assume that a certain template gets evaluated for every request. | |
| 62 | * </p> | |
| 63 | * <p> | |
| 64 | * This Servlet extends the base class of the JSDK definition eliminating any | |
| 65 | * magic in a super-class. | |
| 66 | * </p> | |
| 67 | * | |
| 68 | * @since 24 Jan 2004 | |
| 69 | * @author lanesharman | |
| 70 | */ | |
| 71 | 0 | public class TemplateServlet extends HttpServlet { |
| 72 | ||
| 73 | private static final long serialVersionUID = 1L; | |
| 74 | ||
| 75 | /** | |
| 76 | * The thread-safe evaluator of all templates. | |
| 77 | */ | |
| 78 | protected WMEval wm; | |
| 79 | ||
| 80 | /** | |
| 81 | * The global context. | |
| 82 | */ | |
| 83 | protected Context globalContext; | |
| 84 | ||
| 85 | /** | |
| 86 | * The global context name to place in the context. | |
| 87 | */ | |
| 88 | protected String globalName; | |
| 89 | ||
| 90 | /** | |
| 91 | * The global template. | |
| 92 | */ | |
| 93 | protected String globalTemplate; | |
| 94 | ||
| 95 | /** | |
| 96 | * The name that identifies the per-request context. | |
| 97 | */ | |
| 98 | protected String requestName; | |
| 99 | ||
| 100 | /** | |
| 101 | * The per-request template. | |
| 102 | */ | |
| 103 | protected String requestTemplate; | |
| 104 | ||
| 105 | /** | |
| 106 | * The default template to load in a directory such as index.wm, index.wmt, index.tml | |
| 107 | */ | |
| 108 | 0 | private static String defaultTemplate = "index.tml"; |
| 109 | ||
| 110 | /** | |
| 111 | * The delegate to populate the context for the application. | |
| 112 | */ | |
| 113 | private ServletRouter servletRouter; | |
| 114 | ||
| 115 | protected Logger log; | |
| 116 | ||
| 117 | ||
| 118 | /** | |
| 119 | * Looks for a global template to evaluate (defined in WebMacro.properties). | |
| 120 | * If defined, the global context is made available to every request as a | |
| 121 | * var specified in WebMacro.properties. | |
| 122 | */ | |
| 123 | public void init(ServletConfig conf) throws ServletException { | |
| 124 | 0 | super.init(conf); |
| 125 | // run the application template, Application.tml. | |
| 126 | try { | |
| 127 | 0 | wm = new WMEval(this); |
| 128 | 0 | log = wm.getLog(); |
| 129 | 0 | Settings settings = wm.getSettings(); |
| 130 | 0 | log("Settings: " + settings.getAsProperties()); |
| 131 | 0 | globalName = settings.getSetting("GlobalTemplate.ContextName", null); |
| 132 | 0 | globalTemplate = settings.getSetting("GlobalTemplate.Resource", |
| 133 | null); | |
| 134 | 0 | requestName = settings.getSetting("RequestTemplate.ContextName", |
| 135 | null); | |
| 136 | 0 | requestTemplate = settings.getSetting("RequestTemplate.Resource", |
| 137 | null); | |
| 138 | 0 | String w = settings.getSetting("TemplateServlet.DefaultTemplate"); |
| 139 | 0 | if (w != null) { |
| 140 | 0 | defaultTemplate = w; |
| 141 | } | |
| 142 | 0 | String sr = settings.getSetting("TemplateServlet.ServletRouter"); |
| 143 | 0 | if (sr != null) { |
| 144 | 0 | this.servletRouter = (ServletRouter) Class.forName(sr).newInstance(); |
| 145 | } | |
| 146 | 0 | refreshGlobalContext(); |
| 147 | 0 | log("TemplateServlet initialized."); |
| 148 | 0 | } catch (Exception e) { |
| 149 | 0 | wm.error("Unable to initialize", e); |
| 150 | 0 | e.printStackTrace(System.err); |
| 151 | 0 | log("TemplateServlet failed to initialize: " + e.toString()); |
| 152 | 0 | throw new ServletException(e.toString()); |
| 153 | 0 | } |
| 154 | 0 | } |
| 155 | ||
| 156 | /** | |
| 157 | * Calls locateTemplate() and then getTemplate(), a base method, to find the | |
| 158 | * template and render it. | |
| 159 | */ | |
| 160 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) | |
| 161 | throws ServletException, java.io.IOException { | |
| 162 | try { | |
| 163 | 0 | doResponse(req, resp); |
| 164 | 0 | } catch (Exception e) { |
| 165 | 0 | this.log("Unable to return a template using " + req, e); |
| 166 | 0 | e.printStackTrace(System.err); |
| 167 | 0 | throw new ServletException(e.toString()); |
| 168 | 0 | } |
| 169 | 0 | } |
| 170 | ||
| 171 | /** | |
| 172 | * Calls locateTemplate() and then getTemplate(), a base method, to find the | |
| 173 | * template and render it. | |
| 174 | */ | |
| 175 | protected void doPost(HttpServletRequest req, HttpServletResponse resp) | |
| 176 | throws ServletException, java.io.IOException { | |
| 177 | 0 | doGet(req, resp); |
| 178 | 0 | } |
| 179 | ||
| 180 | /** | |
| 181 | * Method which prepares the response and sends it. | |
| 182 | * <p> | |
| 183 | * The default implementation is as follows: | |
| 184 | * | |
| 185 | * <pre> | |
| 186 | * 1) Locate the template as the URI. | |
| 187 | * 2) Create a new context; if there is a global context | |
| 188 | * populate the context with it according to the parameters | |
| 189 | * in WebMacro.properties. | |
| 190 | * 3) If there is a per-request context, perform the equivalent | |
| 191 | * action of (2) above. | |
| 192 | * 4) If there is a | |
| 193 | * </pre> | |
| 194 | * | |
| 195 | * Override this method to perform your own response handling. | |
| 196 | * | |
| 197 | * @param request The request which has a uri such as /en/welcome.tml | |
| 198 | * @param response The response object | |
| 199 | * @return The template to evaluate and return as the response. | |
| 200 | */ | |
| 201 | protected String doResponse(HttpServletRequest request, | |
| 202 | HttpServletResponse response) throws ServletException { | |
| 203 | 0 | String templateName = locateTemplate(request); |
| 204 | 0 | WebContext context = wm.getNewContext(request, response); |
| 205 | 0 | loadGlobalContext(context); |
| 206 | 0 | loadRequestContext(context, templateName, request, response); |
| 207 | 0 | loadDelegationContext(context, templateName, request, response); |
| 208 | 0 | return wm.eval(context, templateName, response); |
| 209 | } | |
| 210 | ||
| 211 | /** | |
| 212 | * Default implenentation for locating the template. | |
| 213 | */ | |
| 214 | protected String locateTemplate(HttpServletRequest request) { | |
| 215 | 0 | String value = null; // request.getPathInfo().substring(1); // strip out the |
| 216 | 0 | value = (String) request.getAttribute("javax.servlet.include.servlet_path"); |
| 217 | 0 | if (value == null) value = request.getServletPath(); |
| 218 | 0 | log.info("request.getPathInfo(): " + request.getPathInfo()); |
| 219 | 0 | log.info("javax.servlet.include.servlet_path: " + request.getAttribute("javax.servlet.include.servlet_path")); |
| 220 | 0 | log.info("request.getServletPath(): " + request.getServletPath()); |
| 221 | 0 | if (value == null || value.trim().length() == 0) { |
| 222 | 0 | return defaultTemplate; |
| 223 | 0 | } else if (value.endsWith("/")) { |
| 224 | 0 | return (value + defaultTemplate); |
| 225 | } else { | |
| 226 | 0 | return value; |
| 227 | } | |
| 228 | } | |
| 229 | ||
| 230 | /** | |
| 231 | * Implementation for populating the context: handles a default per request | |
| 232 | * context. | |
| 233 | * <p> | |
| 234 | * Override as required. | |
| 235 | */ | |
| 236 | protected void loadRequestContext(WebContext context, String template, | |
| 237 | HttpServletRequest request, HttpServletResponse resp) | |
| 238 | throws ServletException { | |
| 239 | 0 | if (this.requestName != null) { |
| 240 | try { | |
| 241 | 0 | Context c = wm.getNewContext(); |
| 242 | 0 | wm.eval(c, requestTemplate, null); |
| 243 | 0 | context.put(this.requestName, c); |
| 244 | 0 | } catch (Exception e) { |
| 245 | 0 | this.log("Unable to evaluate request template " + requestName, |
| 246 | e); | |
| 247 | 0 | throw new ServletException(e.toString()); |
| 248 | 0 | } |
| 249 | } | |
| 250 | 0 | } |
| 251 | ||
| 252 | /** | |
| 253 | * Implementation for populating the context by a runtime defined delegate. | |
| 254 | * <p> | |
| 255 | * Override as required. | |
| 256 | */ | |
| 257 | protected void loadDelegationContext(WebContext context, String template, | |
| 258 | HttpServletRequest request, HttpServletResponse resp) | |
| 259 | throws ServletException { | |
| 260 | 0 | if (this.servletRouter != null) { |
| 261 | try { | |
| 262 | 0 | servletRouter.handleWebRequest(this, context, template); |
| 263 | 0 | } catch (Exception e) { |
| 264 | 0 | this.log("Unable to process router " + servletRouter.getClass().getName(), |
| 265 | e); | |
| 266 | 0 | throw new ServletException(e.toString()); |
| 267 | 0 | } |
| 268 | } | |
| 269 | 0 | } |
| 270 | ||
| 271 | /** | |
| 272 | * Loads the global context if present. | |
| 273 | */ | |
| 274 | private void loadGlobalContext(WebContext context) { | |
| 275 | 0 | if (globalName == null) |
| 276 | 0 | return; |
| 277 | 0 | context.put(globalName, globalContext); |
| 278 | 0 | } |
| 279 | ||
| 280 | /** | |
| 281 | * Call this to refresh the global context. | |
| 282 | */ | |
| 283 | protected void refreshGlobalContext() throws Exception { | |
| 284 | 0 | if (globalName == null) |
| 285 | 0 | return; |
| 286 | 0 | Context c = wm.getNewContext(); |
| 287 | 0 | wm.eval(c, globalTemplate, null); |
| 288 | 0 | globalContext = c; |
| 289 | 0 | } |
| 290 | ||
| 291 | } |