View Javadoc
1 package org.apache.turbine.services.freemarker; 2 3 /* ==================================================================== 4 * The Apache Software License, Version 1.1 5 * 6 * Copyright (c) 2001 The Apache Software Foundation. All rights 7 * reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. The end-user documentation included with the redistribution, 22 * if any, must include the following acknowledgment: 23 * "This product includes software developed by the 24 * Apache Software Foundation (http://www.apache.org/)." 25 * Alternately, this acknowledgment may appear in the software itself, 26 * if and wherever such third-party acknowledgments normally appear. 27 * 28 * 4. The names "Apache" and "Apache Software Foundation" and 29 * "Apache Turbine" must not be used to endorse or promote products 30 * derived from this software without prior written permission. For 31 * written permission, please contact apache@apache.org. 32 * 33 * 5. Products derived from this software may not be called "Apache", 34 * "Apache Turbine", nor may "Apache" appear in their name, without 35 * prior written permission of the Apache Software Foundation. 36 * 37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 48 * SUCH DAMAGE. 49 * ==================================================================== 50 * 51 * This software consists of voluntary contributions made by many 52 * individuals on behalf of the Apache Software Foundation. For more 53 * information on the Apache Software Foundation, please see 54 * <http://www.apache.org/>;. 55 */ 56 57 58 import freemarker.template.CacheEvent; 59 import freemarker.template.CacheListener; 60 import freemarker.template.FileTemplateCache; 61 import freemarker.template.SimpleHash; 62 import freemarker.template.SimpleList; 63 import freemarker.template.Template; 64 import freemarker.template.TemplateServletUtils; 65 import java.io.File; 66 import java.io.IOException; 67 import java.io.PrintWriter; 68 import java.io.StringWriter; 69 import java.util.Enumeration; 70 import java.util.Iterator; 71 import java.util.StringTokenizer; 72 import javax.servlet.ServletRequest; 73 import org.apache.commons.configuration.Configuration; 74 import org.apache.turbine.om.security.Permission; 75 import org.apache.turbine.om.security.Role; 76 import org.apache.turbine.services.InitializationException; 77 import org.apache.turbine.services.TurbineBaseService; 78 import org.apache.turbine.services.servlet.TurbineServlet; 79 import org.apache.turbine.util.DynamicURI; 80 import org.apache.turbine.util.Log; 81 import org.apache.turbine.util.ParameterParser; 82 import org.apache.turbine.util.RunData; 83 import org.apache.turbine.util.TurbineException; 84 85 86 /*** 87 * This is a Service that can process FreeMarker templates from within 88 * a Turbine Screen. Here's an example of how you might use it from a 89 * screen: 90 * 91 * <br> 92 * 93 * FreeMarkerService fm = (FreeMarkerService)TurbineServices.getInstance() 94 * .getService(FreeMarkerService.SERVICE_NAME); 95 * SimpleHash context = fm.getContext(data); 96 * context.put("message", "Hello from Turbine!"); 97 * String results = fm.handleRequest(context,"helloWorld.wm"); 98 * data.getPage().getBody().addElement(results); 99 * 100 * @author <a href="mailto:john.mcnally@clearink.com">John D. McNally</a> 101 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> 102 * @version $Id: TurbineFreeMarkerService.java,v 1.6 2002/07/16 16:38:13 henning Exp $ 103 * @deprecated 104 */ 105 public class TurbineFreeMarkerService 106 extends TurbineBaseService 107 implements FreeMarkerService, CacheListener 108 { 109 /*** A cache to store parsed templates. */ 110 private FileTemplateCache templateCache; 111 112 /*** The base path prepended to filenames given in arguments. */ 113 private String path; 114 115 /*** 116 * Constructor. 117 */ 118 public TurbineFreeMarkerService() 119 { 120 } 121 122 /*** 123 * Called during Turbine.init() 124 * 125 * @param config A ServletConfig. 126 */ 127 public void init() throws InitializationException 128 { 129 try 130 { 131 initFreeMarker(); 132 setInit(true); 133 } 134 catch (Exception e) 135 { 136 throw new InitializationException( 137 "TurbineFreeMarkerService failed to initialize", e); 138 } 139 } 140 141 /*** 142 * Create a context needed by the FreeMarker template. This 143 * method just returns an SimpleHash with the request parameters 144 * copied into a model called request. 145 * 146 * @return SimpleHash which can be used as the model for a 147 * template. 148 */ 149 public SimpleHash getContext() 150 { 151 return new SimpleHash(); 152 } 153 154 /*** 155 * Create a context needed by the FreeMarker template. This 156 * method just returns an SimpleHash with the request parameters 157 * copied into a model called request. 158 * 159 * @param req A ServletRequest. 160 * @return SimpleHash which can be used as the model for a 161 * template. 162 */ 163 public SimpleHash getContext(ServletRequest req) 164 { 165 return (SimpleHash)TemplateServletUtils.copyRequest(req); 166 } 167 168 /*** 169 * Create a context from the RunData object. Values found in 170 * RunData are copied into the modelRoot under similar names as 171 * they can be found in RunData. e.g. data.serverName, 172 * data.parameters.form_field_name 173 * data.acl.permissions.can_write_file. Some default links are 174 * also made available under links. 175 * 176 * @param data The Turbine RunData object. 177 * @return a SimpleHash populated with RunData data. 178 */ 179 public SimpleHash getContext(RunData data) 180 { 181 SimpleHash modelRoot = new SimpleHash(); 182 SimpleHash modelLinks = new SimpleHash(); 183 modelRoot.put("link", new DynamicURIModel(data)); 184 modelRoot.put("links", modelLinks); 185 // modelLinks.put("default", new DynamicURI(data, "FreeMarkerScreen").toString()); 186 // modelLinks.put("no_cache", new DynamicURI(data, "FreeMarkerNoCacheScreen").toString()); 187 // modelLinks.put("simple", new DynamicURI(data).toString()); 188 if (data.getUser() != null && data.getUser().hasLoggedIn()) 189 { 190 modelRoot.put("loginout_link", new DynamicURI(data, "Login", "LogoutUser").toString()); 191 modelRoot.put("loginout_text", "Logout"); 192 } 193 else 194 { 195 modelRoot.put("loginout_link", new DynamicURI(data, "Login").toString()); 196 modelRoot.put("loginout_text", "Login"); 197 } 198 199 // Add default. 200 SimpleHash modelData = new SimpleHash(); 201 SimpleHash modelParameters = new SimpleHash(); 202 SimpleHash modelACL = new SimpleHash(); 203 SimpleHash modelRoles = new SimpleHash(); 204 SimpleHash modelPermissions = new SimpleHash(); 205 modelRoot.put("data", modelData); 206 modelData.put("parameters", modelParameters); 207 modelData.put("acl", modelACL); 208 modelACL.put("roles", modelRoles); 209 modelACL.put("permissions", modelPermissions); 210 211 modelData.put("serverName", data.getServerName() ); 212 modelData.put("serverPort", String.valueOf(data.getServerPort()) ); 213 modelData.put("serverScheme", data.getServerScheme() ); 214 modelData.put("scriptName", data.getScriptName() ); 215 modelData.put("screen", data.getScreen() ); 216 modelData.put("action", data.getAction() ); 217 modelData.put("title", data.getTitle() ); 218 modelData.put("message", data.getMessage() ); 219 220 ParameterParser params = data.getParameters(); 221 Enumeration e = params.keys(); 222 while (e.hasMoreElements() ) 223 { 224 String key = (String)e.nextElement(); 225 String[] values = params.getStrings(key); 226 if (values.length==1) 227 { 228 modelParameters.put(key, values[0]); 229 } 230 else 231 { 232 SimpleList listModel = new SimpleList(); 233 modelParameters.put(key, listModel); 234 for (int i=0; i<values.length; i++) 235 { 236 listModel.add(values[i]); 237 } 238 } 239 } 240 241 if (data.getACL() != null) 242 { 243 Iterator roles = data.getACL().getRoles().elements(); 244 while (roles.hasNext() ) 245 { 246 String key = ((Role)roles.next()).getName(); 247 modelRoles.put(key, true); 248 } 249 Iterator permissions = data.getACL().getPermissions().elements(); 250 while (permissions.hasNext() ) 251 { 252 String key = ((Permission)permissions.next()).getName(); 253 modelPermissions.put(key, true); 254 } 255 } 256 257 modelRoot.put("setTitle", new SetTitleModel(data)); 258 modelRoot.put("addToHead", new AddToHeadModel(data)); 259 modelRoot.put("addTemplatesToHead", new AddTemplatesToHeadModel(data)); 260 modelRoot.put("setBodyAttributes", new SetBodyAttributesModel(data)); 261 262 String templatePath = params.getString("template", null); 263 if (templatePath != null) 264 { 265 StringTokenizer st = new StringTokenizer(templatePath, "/"); 266 int max = st.countTokens() - 1; 267 for (int i=0; i<max; i++) 268 { 269 modelRoot.put("template_path_" + (i+1), st.nextToken()); 270 } 271 } 272 273 return modelRoot; 274 } 275 276 /*** 277 * Process the request and fill in the template with the values 278 * you set in the WebContext. 279 * 280 * @param context A SimpleHash with the context. 281 * @param templateName A String with the filename of the template. 282 * @param cache True if the parsed template should be cached. 283 * @return The processed template as a String. 284 * @throws TurbineException Any exception trown while processing will be 285 * wrapped into a TurbineException and rethrown. 286 */ 287 public String handleRequest(SimpleHash context, 288 String filename, 289 boolean cache) 290 throws TurbineException 291 { 292 String results = null; 293 StringWriter sw = null; 294 PrintWriter out = null; 295 try 296 { 297 sw = new StringWriter(); 298 out = new PrintWriter(sw); 299 Template template = null; 300 if (cache) 301 { 302 template = getCachedTemplate(filename); 303 } 304 else 305 { 306 template = getNonCachedTemplate(filename); 307 } 308 309 template.process(context, out); 310 results = sw.toString(); 311 } 312 catch(Exception e) 313 { 314 throw new TurbineException( 315 "Error encountered processing a template: " + filename, e); 316 } 317 finally 318 { 319 try 320 { 321 if (out != null) out.close(); 322 if (sw != null) sw.close(); 323 } 324 catch (Exception e) {} 325 } 326 return results; 327 } 328 329 /*** 330 * Gets the base path for the FreeMarker templates. 331 * 332 * @return The base path for the FreeMarker templates. 333 */ 334 public String getBasePath() 335 { 336 return path; 337 } 338 339 /*** 340 * Return a FreeMarker template from the cache. If the template 341 * has not been cached yet, it will be added to the cache. 342 * 343 * @param templateName A String with the name of the template. 344 * @return A Template. 345 */ 346 public Template getCachedTemplate(String templateName) 347 { 348 Template template = templateCache.getTemplate(templateName); 349 // if (template == null) 350 // { 351 // Exception e = new Exception("Template " + templateName + 352 // " is not available."); 353 // Log.error ( e ); 354 // throw e; 355 // } 356 return template; 357 } 358 359 /*** 360 * Return a FreeMarker template. It will not be added to the 361 * cache. 362 * 363 * @param templateName A String with the name of the template. 364 * @return A Template. 365 * @exception IOException, if there was an I/O problem. 366 */ 367 public Template getNonCachedTemplate(String templateName) 368 throws IOException 369 { 370 templateName = templateName.replace('/', File.separatorChar); 371 File file = new File(path, templateName); 372 if (file.canRead()) 373 { 374 return new Template(file); 375 } 376 // else 377 // { 378 // Exception e = new Exception("Template " + templateName + 379 // " could not be read."); 380 // Log.error ( e ); 381 // throw e; 382 // } 383 return null; 384 } 385 386 /*** 387 * This method sets up the FreeMarker template cache. 388 * 389 * @param config A ServletConfig. 390 * @exception Exception, a generic exception. 391 */ 392 private void initFreeMarker() throws Exception 393 { 394 Configuration config = getConfiguration(); 395 396 path = config.getString("templates", "/templates"); 397 398 // If possible, transform paths to be webapp root relative. 399 path = TurbineServlet.getRealPath(path); 400 401 // Store the converted path in service properties for Turbine 402 // based providers. 403 config.setProperty("templates", path); 404 405 templateCache = new FileTemplateCache(path); 406 templateCache.addCacheListener(this); 407 templateCache.startAutoUpdate(); 408 } 409 410 /*** 411 * Method called by templateCache. 412 * 413 * @param e A CacheEvent. 414 */ 415 public void cacheUnavailable(CacheEvent e) 416 { 417 Log.error("Cache unavailable: " + e.getException().toString()); 418 } 419 420 /*** 421 * Method called by templateCache. 422 * 423 * @param e A CacheEvent. 424 */ 425 public void elementUpdated(CacheEvent e) 426 { 427 Log.info("Template updated: " + e.getElementName()); 428 } 429 430 /*** 431 * Method called by templateCache. 432 * 433 * @param e A CacheEvent. 434 */ 435 public void elementUpdateFailed(CacheEvent e) 436 { 437 Log.error("Update of template " + e.getElementName() + 438 " failed: " + e.getException().toString()); 439 } 440 441 /*** 442 * Method called by templateCache. 443 * 444 * @param e A CacheEvent. 445 */ 446 public void elementRemoved(CacheEvent e) 447 { 448 Log.warn("Template removed: " + e.getElementName()); 449 } 450 }

This page was automatically generated by Maven