1 39 package groovy.servlet; 40 41 import groovy.text.SimpleTemplateEngine; 42 import groovy.text.Template; 43 import groovy.text.TemplateEngine; 44 45 import java.io.BufferedReader ; 46 import java.io.File ; 47 import java.io.FileReader ; 48 import java.io.IOException ; 49 import java.io.StringReader ; 50 import java.io.Writer ; 51 import java.util.Map ; 52 import java.util.WeakHashMap ; 53 54 import javax.servlet.ServletConfig ; 55 import javax.servlet.ServletException ; 56 import javax.servlet.http.HttpServletRequest ; 57 import javax.servlet.http.HttpServletResponse ; 58 59 89 public class TemplateServlet extends AbstractHttpServlet { 90 91 97 private static class TemplateCacheEntry { 98 99 long lastModified; 100 long length; 101 Template template; 102 103 public TemplateCacheEntry(File file, Template template) { 104 if (file == null) { 105 throw new NullPointerException ("file"); 106 } 107 if (template == null) { 108 throw new NullPointerException ("template"); 109 } 110 this.lastModified = file.lastModified(); 111 this.length = file.length(); 112 this.template = template; 113 } 114 115 122 public boolean validate(File file) { 123 if (file == null) { 124 throw new NullPointerException ("file"); 125 } 126 if (file.lastModified() != this.lastModified) { 127 return false; 128 } 129 if (file.length() != this.length) { 130 return false; 131 } 132 return true; 133 } 134 135 } 136 137 140 private static final boolean VERBOSE = true; 141 142 145 private final Map cache; 147 148 151 private TemplateEngine engine; 152 153 156 private boolean generatedBy; 157 158 161 public TemplateServlet() { 162 this.cache = new WeakHashMap (); 164 this.engine = null; this.generatedBy = true; } 168 169 179 private Template createTemplate(int bufferCapacity, FileReader fileReader) 180 throws Exception { 181 StringBuffer sb = new StringBuffer (bufferCapacity); 182 BufferedReader reader = new BufferedReader (fileReader); 183 try { 184 String line = reader.readLine(); 185 while (line != null) { 186 sb.append(line); 187 line = reader.readLine(); 191 } 192 } 193 finally { 194 if (reader != null) { 195 reader.close(); 196 } 197 } 198 StringReader stringReader = new StringReader (sb.toString()); 199 Template template = engine.createTemplate(stringReader); 200 stringReader.close(); 201 return template; 202 } 203 204 223 protected Template getTemplate(File file) throws ServletException { 224 225 String key = file.getAbsolutePath(); 226 Template template = null; 227 228 TemplateCacheEntry entry = (TemplateCacheEntry) cache.get(key); 232 if (entry != null) { 233 if (entry.validate(file)) { template = entry.template; 235 } } 238 if (template == null) { 242 if (VERBOSE) { 243 log("Creating new template from file " + file + "..."); 244 } 245 FileReader reader = null; 246 try { 247 reader = new FileReader (file); 248 template = createTemplate((int) file.length(), reader); 257 } 258 catch (Exception e) { 259 throw new ServletException ("Creation of template failed: " + e, e); 260 } 261 finally { 262 if (reader != null) { 263 try { 264 reader.close(); 265 } 266 catch (IOException ignore) { 267 } 269 } 270 } 271 cache.put(key, new TemplateCacheEntry(file, template)); 272 if (VERBOSE) { 273 log("Created and added template to cache. [key=" + key + "]"); 274 } 275 } 276 277 if (template == null) { 281 throw new ServletException ("Template is null? Should not happen here!"); 282 } 283 284 return template; 285 286 } 287 288 304 public void init(ServletConfig config) throws ServletException { 305 super.init(config); 306 this.engine = initTemplateEngine(config); 307 if (engine == null) { 308 throw new ServletException ("Template engine not instantiated."); 309 } 310 String value = config.getInitParameter("generatedBy"); 311 if (value != null) { 312 this.generatedBy = Boolean.valueOf(value).booleanValue(); 313 } 314 if (VERBOSE) { 315 log(getClass().getName() + " initialized on " + engine.getClass()); 316 } 317 } 318 319 333 protected TemplateEngine initTemplateEngine(ServletConfig config) { 334 String name = config.getInitParameter("templateEngine"); 335 if (name == null) { 336 return new SimpleTemplateEngine(); 337 } 338 try { 339 return (TemplateEngine) Class.forName(name).newInstance(); 340 } 341 catch (InstantiationException e) { 342 log("Could not instantiate template engine: " + name, e); 343 } 344 catch (IllegalAccessException e) { 345 log("Could not access template engine class: " + name, e); 346 } 347 catch (ClassNotFoundException e) { 348 log("Could not find template engine class: " + name, e); 349 } 350 return null; 351 } 352 353 370 public void service(HttpServletRequest request, 371 HttpServletResponse response) throws ServletException , IOException { 372 373 if (VERBOSE) { 374 log("Creating/getting cached template..."); 375 } 376 377 File file = super.getScriptUriAsFile(request); 381 if (!file.exists()) { 382 response.sendError(HttpServletResponse.SC_NOT_FOUND); 383 return; } 385 if (!file.canRead()) { 386 response.sendError(HttpServletResponse.SC_FORBIDDEN, "Can not read!"); 387 return; } 389 390 long getMillis = System.currentTimeMillis(); 394 Template template = getTemplate(file); 395 getMillis = System.currentTimeMillis() - getMillis; 396 397 ServletBinding binding = new ServletBinding(request, response, servletContext); 401 setVariables(binding); 402 403 response.setContentType(CONTENT_TYPE_TEXT_HTML); 407 408 Writer out = (Writer ) binding.getVariable("out"); 412 if (out == null) { 413 out = response.getWriter(); 414 } 415 416 if (VERBOSE) { 420 log("Making template..."); 421 } 422 long makeMillis = System.currentTimeMillis(); 425 template.make(binding.getVariables()).writeTo(out); 426 makeMillis = System.currentTimeMillis() - makeMillis; 427 428 if (generatedBy) { 429 StringBuffer sb = new StringBuffer (100); 430 sb.append("\n<!-- Generated by Groovy TemplateServlet [create/get="); 431 sb.append(Long.toString(getMillis)); 432 sb.append(" ms, make="); 433 sb.append(Long.toString(makeMillis)); 434 sb.append(" ms] -->\n"); 435 out.write(sb.toString()); 436 } 437 438 response.setStatus(HttpServletResponse.SC_OK); 442 response.flushBuffer(); 443 444 if (VERBOSE) { 445 log("Template request responded. [create/get=" + getMillis 446 + " ms, make=" + makeMillis + " ms]"); 447 } 448 449 } 450 451 505 protected void setVariables(ServletBinding binding) { 506 } 508 509 } 510 | Popular Tags |