1 package org.apache.fulcrum.velocity; 2 3 56 57 import java.util.List ; 58 import java.util.Vector ; 59 import java.util.Iterator ; 60 import java.util.Enumeration ; 61 import java.io.IOException ; 62 import java.io.OutputStream ; 63 import java.io.Writer ; 64 import java.io.OutputStreamWriter ; 65 import java.io.ByteArrayOutputStream ; 66 import org.apache.velocity.VelocityContext; 67 import org.apache.velocity.app.VelocityEngine; 68 import org.apache.velocity.app.event.EventCartridge; 69 import org.apache.velocity.app.event.ReferenceInsertionEventHandler; 70 import org.apache.velocity.app.event.NullSetEventHandler; 71 import org.apache.velocity.app.event.MethodExceptionEventHandler; 72 import org.apache.velocity.context.Context; 73 import org.apache.velocity.context.InternalEventContext; 74 import org.apache.velocity.exception.MethodInvocationException; 75 import org.apache.fulcrum.ServiceException; 76 import org.apache.fulcrum.InitializationException; 77 import org.apache.fulcrum.template.TemplateContext; 78 import org.apache.fulcrum.template.BaseTemplateEngineService; 79 import org.apache.commons.configuration.ConfigurationConverter; 80 81 106 public class TurbineVelocityService 107 extends BaseTemplateEngineService 108 implements VelocityService 109 { 110 113 private static final String RESOURCE_LOADER_PATH = 114 ".resource.loader.path"; 115 116 119 private static final String DEFAULT_CHAR_SET = "ISO-8859-1"; 120 121 124 private static final String JAR_PREFIX = "jar:"; 125 126 129 private static final String ABSOLUTE_PREFIX = "file://"; 130 131 134 private EventCartridge eventCartridge; 135 136 140 private boolean eventCartridgeEnabled = true; 141 142 145 private VelocityEngine velocityEngine = new VelocityEngine(); 146 147 150 public void init() 151 throws InitializationException 152 { 153 try 154 { 155 initVelocity(); 156 initEventCartridges(); 157 158 registerConfiguration("vm"); 160 setInit(true); 161 } 162 catch (Exception e) 163 { 164 e.printStackTrace(); 165 throw new InitializationException( 166 "Failed to initialize TurbineVelocityService", e); 167 } 168 } 169 170 173 public String handleRequest(TemplateContext context, String template) 174 throws ServiceException 175 { 176 return handleRequest(new ContextAdapter(context), template); 177 } 178 179 182 public String handleRequest(Context context, String filename) 183 throws ServiceException 184 { 185 return handleRequest(context, filename, (String )null, null); 186 } 187 188 191 public String handleRequest(Context context, String filename, 192 String charset, String encoding) 193 throws ServiceException 194 { 195 String results = null; 196 ByteArrayOutputStream bytes = null; 197 198 try 199 { 200 bytes = new ByteArrayOutputStream (); 201 charset = decodeRequest(context, filename, bytes, charset, 202 encoding); 203 results = bytes.toString(charset); 204 } 205 catch (Exception e) 206 { 207 renderingError(filename, e); 208 } 209 finally 210 { 211 try 212 { 213 if (bytes != null) 214 { 215 bytes.close(); 216 } 217 } 218 catch (IOException ignored) 219 { 220 } 221 } 222 return results; 223 } 224 225 228 public void handleRequest(TemplateContext context, String template, 229 OutputStream outputStream) 230 throws ServiceException 231 { 232 handleRequest(new ContextAdapter(context), template, outputStream); 233 } 234 235 238 public void handleRequest(Context context, String filename, 239 OutputStream output) 240 throws ServiceException 241 { 242 handleRequest(context, filename, output, null, null); 243 } 244 245 248 public void handleRequest(Context context, String filename, 249 OutputStream output, String charset, 250 String encoding) 251 throws ServiceException 252 { 253 decodeRequest(context, filename, output, charset, encoding); 254 } 255 256 259 public void handleRequest(TemplateContext context, 260 String template, Writer writer) 261 throws ServiceException 262 { 263 handleRequest(new ContextAdapter(context), template, writer); 264 } 265 266 269 public void handleRequest(Context context, String filename, 270 Writer writer) 271 throws ServiceException 272 { 273 handleRequest(context, filename, writer, null); 274 } 275 276 279 public void handleRequest(Context context, String filename, 280 Writer writer, String encoding) 281 throws ServiceException 282 { 283 try 284 { 285 291 Context eventContext; 292 293 if ( context instanceof InternalEventContext ) 294 { 295 eventContext = context; 296 } 297 else 298 { 299 eventContext = new VelocityContext( context ); 300 } 301 302 EventCartridge ec = getEventCartridge(); 304 if (ec != null && eventCartridgeEnabled) 305 { 306 ec.attachToContext(eventContext); 307 } 308 309 if (encoding != null) 310 { 311 velocityEngine.mergeTemplate(filename, encoding, 313 eventContext, writer); 314 } 315 else 316 { 317 velocityEngine.mergeTemplate(filename, eventContext, writer); 318 } 319 } 320 catch (Exception e) 321 { 322 renderingError(filename, e); 323 } 324 } 325 326 331 public void setEventCartridgeEnabled(boolean value) 332 { 333 this.eventCartridgeEnabled = value; 334 } 335 336 339 public EventCartridge getEventCartridge() 340 { 341 return eventCartridge; 342 } 343 344 359 private String decodeRequest(Context context, String filename, 360 OutputStream output, String charset, 361 String encoding) 362 throws ServiceException 363 { 364 369 if (charset == null) 370 { 371 charset = DEFAULT_CHAR_SET; 372 } 373 374 OutputStreamWriter writer = null; 375 try 376 { 377 try 378 { 379 writer = new OutputStreamWriter (output, charset); 380 } 381 catch (Exception e) 382 { 383 renderingError(filename, e); 384 } 385 handleRequest(context, filename, writer, encoding); 386 } 387 finally 388 { 389 try 390 { 391 if (writer != null) 392 { 393 writer.flush(); 394 } 395 } 396 catch (Exception ignored) 397 { 398 } 399 } 400 return charset; 401 } 402 403 412 private final void renderingError(String filename, Throwable e) 413 throws ServiceException 414 { 415 String err = "Error rendering Velocity template: " + filename; 416 getCategory().error(err + ": " + e.getMessage()); 417 if (e instanceof MethodInvocationException) 420 { 421 e = ((MethodInvocationException)e).getWrappedThrowable(); 422 } 423 424 throw new ServiceException(err, e); 425 } 426 427 436 private void initEventCartridges() 437 throws InitializationException 438 { 439 eventCartridge = new EventCartridge(); 440 441 List ecconfig = getConfiguration() 442 .getList("eventCartridge.classes", null); 443 if (ecconfig == null) 444 { 445 getCategory().info("No Velocity EventCartridges configured."); 446 return; 447 } 448 449 Object obj = null; 450 String className = null; 451 for (Iterator i = ecconfig.iterator() ; i.hasNext() ;) 452 { 453 className = (String ) i.next(); 454 try 455 { 456 boolean result = false; 457 458 obj = Class.forName(className).newInstance(); 459 460 if (obj instanceof ReferenceInsertionEventHandler) 461 { 462 result = getEventCartridge() 463 .addEventHandler((ReferenceInsertionEventHandler)obj); 464 } 465 else if (obj instanceof NullSetEventHandler) 466 { 467 result = getEventCartridge() 468 .addEventHandler((NullSetEventHandler)obj); 469 } 470 else if (obj instanceof MethodExceptionEventHandler) 471 { 472 result = getEventCartridge() 473 .addEventHandler((MethodExceptionEventHandler)obj); 474 } 475 getCategory().info("Added EventCartridge: " + 476 obj.getClass().getName() + " : " + result); 477 } 478 catch (Exception h) 479 { 480 throw new InitializationException( 481 "Could not initialize EventCartridge: " + 482 className, h); 483 } 484 } 485 } 486 487 493 private void initVelocity() 494 throws InitializationException 495 { 496 String path = getRealPath( 499 getConfiguration().getString(VelocityEngine.RUNTIME_LOG, null)); 500 501 if (path != null && path.length() > 0) 502 { 503 getConfiguration().setProperty(VelocityEngine.RUNTIME_LOG, path); 504 } 505 else 506 { 507 String msg = VelocityService.SERVICE_NAME + " runtime log file " + 508 "is misconfigured: '" + path + "' is not a valid log file"; 509 510 throw new Error (msg); 511 } 512 513 String key; 518 Vector keys = new Vector (); 519 for (Iterator i = getConfiguration().getKeys(); i.hasNext();) 520 { 521 key = (String ) i.next(); 522 if (key.endsWith(RESOURCE_LOADER_PATH)) 523 { 524 keys.add(key); 525 } 526 } 527 528 int ind; 531 List paths; 532 String entry; 533 for (Iterator i = keys.iterator(); i.hasNext();) 534 { 535 key = (String ) i.next(); 536 paths = getConfiguration().getList(key,null); 537 if (paths != null) 538 { 539 velocityEngine.clearProperty(key); 540 getConfiguration().clearProperty(key); 541 542 for (Iterator j = paths.iterator(); j.hasNext();) 543 { 544 path = (String ) j.next(); 545 if (path.startsWith(JAR_PREFIX + "file")) 546 { 547 ind = path.indexOf("!/"); 550 if (ind >= 0) 551 { 552 entry = path.substring(ind); 553 path = path.substring(9,ind); 554 } 555 else 556 { 557 entry = "!/"; 558 path = path.substring(9); 559 } 560 path = JAR_PREFIX + "file:" + getRealPath(path) + 561 entry; 562 } 563 else if (path.startsWith(ABSOLUTE_PREFIX)) 564 { 565 path = path.substring (ABSOLUTE_PREFIX.length(), 566 path.length()); 567 } 568 else if (!path.startsWith(JAR_PREFIX)) 569 { 570 path = getRealPath(path); 572 } 573 getConfiguration().addProperty(key,path); 575 } 576 } 577 } 578 579 try 580 { 581 velocityEngine.setExtendedProperties(ConfigurationConverter 582 .getExtendedProperties(getConfiguration())); 583 584 velocityEngine.init(); 585 } 586 catch(Exception e) 587 { 588 throw new InitializationException( 592 "Failed to set up TurbineVelocityService", e); 593 } 594 } 595 596 604 public boolean templateExists(String template) 605 { 606 return velocityEngine.templateExists(template); 607 } 608 } 609 | Popular Tags |