1 package org.tigris.scarab.services.email; 2 3 56 57 import java.io.ByteArrayOutputStream ; 58 import java.io.IOException ; 59 import java.io.OutputStream ; 60 import java.io.OutputStreamWriter ; 61 import java.io.StringWriter ; 62 import java.io.Writer ; 63 import java.util.ArrayList ; 64 import java.util.Iterator ; 65 import java.util.List ; 66 67 import org.apache.commons.configuration.ConfigurationConverter; 68 import org.apache.fulcrum.InitializationException; 69 import org.apache.fulcrum.ServiceException; 70 import org.apache.fulcrum.template.BaseTemplateEngineService; 71 import org.apache.fulcrum.template.TemplateContext; 72 import org.apache.fulcrum.velocity.ContextAdapter; 73 import org.apache.velocity.VelocityContext; 74 import org.apache.velocity.app.VelocityEngine; 75 import org.apache.velocity.context.Context; 76 import org.apache.velocity.context.InternalEventContext; 77 import org.apache.velocity.exception.MethodInvocationException; 78 import org.tigris.scarab.tools.ScarabLocalizationTool; 79 import org.tigris.scarab.util.ScarabConstants; 80 81 110 public class VelocityEmailService 111 extends BaseTemplateEngineService 112 implements EmailService 113 { 114 117 private static final String RESOURCE_LOADER_PATH = 118 ".resource.loader.path"; 119 120 123 private static final String DEFAULT_CHAR_SET = "ISO-8859-1"; 124 125 128 private static final String JAR_PREFIX = "jar:"; 129 130 133 private static final String ABSOLUTE_PREFIX = "file://"; 134 135 138 private VelocityEngine velocityEngine = new VelocityEngine(); 139 140 143 public void init() 144 throws InitializationException 145 { 146 try 147 { 148 initVelocity(); 149 registerConfiguration("ve"); 151 setInit(true); 152 } 153 catch (Exception e) 154 { 155 e.printStackTrace(); 156 throw new InitializationException( 157 "Failed to initialize VelocityEmailService", e); } 159 } 160 161 164 public String handleRequest(TemplateContext context, String template) 165 throws ServiceException 166 { 167 return handleRequest(new ContextAdapter(context), template); 168 } 169 170 173 public String handleRequest(Context context, String filename) 174 throws ServiceException 175 { 176 return handleRequest(context, filename, (String )null, null); 177 } 178 179 182 public String handleRequest(Context context, String filename, 183 String charset, String encoding) 184 throws ServiceException 185 { 186 String results = null; 187 if (charset == null) 188 { 189 StringWriter writer = null; 190 try 191 { 192 writer = new StringWriter (); 193 handleRequest(context, filename, writer, encoding); 194 results = writer.toString(); 195 } 196 catch (Exception e) 197 { 198 renderingError(filename, e); 199 } 200 finally 201 { 202 try 203 { 204 if (writer != null) 205 { 206 writer.close(); 207 } 208 } 209 catch (IOException ignored) 210 { 211 } 212 } 213 } 214 else 215 { 216 ByteArrayOutputStream bytes = null; 217 try 218 { 219 bytes = new ByteArrayOutputStream (); 220 charset = decodeRequest(context, filename, bytes, charset, 221 encoding); 222 results = bytes.toString(charset); 223 } 224 catch (Exception e) 225 { 226 renderingError(filename, e); 227 } 228 finally 229 { 230 try 231 { 232 if (bytes != null) 233 { 234 bytes.close(); 235 } 236 } 237 catch (IOException ignored) 238 { 239 } 240 } 241 } 242 243 return results; 244 } 245 246 249 public void handleRequest(TemplateContext context, String template, 250 OutputStream outputStream) 251 throws ServiceException 252 { 253 handleRequest(new ContextAdapter(context), template, outputStream); 254 } 255 256 259 public void handleRequest(Context context, String filename, 260 OutputStream output) 261 throws ServiceException 262 { 263 handleRequest(context, filename, output, null, null); 264 } 265 266 269 public void handleRequest(Context context, String filename, 270 OutputStream output, String charset, 271 String encoding) 272 throws ServiceException 273 { 274 decodeRequest(context, filename, output, charset, encoding); 275 } 276 277 280 public void handleRequest(TemplateContext context, 281 String template, Writer writer) 282 throws ServiceException 283 { 284 handleRequest(new ContextAdapter(context), template, writer); 285 } 286 287 290 public void handleRequest(Context context, String filename, 291 Writer writer) 292 throws ServiceException 293 { 294 handleRequest(context, filename, writer, null); 295 } 296 297 300 public void handleRequest(Context context, String filename, 301 Writer writer, String encoding) 302 throws ServiceException 303 { 304 ScarabLocalizationTool l10n = null; 305 try 306 { 307 313 Context eventContext; 314 315 if ( context instanceof InternalEventContext ) 316 { 317 eventContext = context; 318 } 319 else 320 { 321 eventContext = new VelocityContext( context ); 322 } 323 324 if (encoding == null) 325 { 326 encoding = DEFAULT_CHAR_SET; 327 } 328 329 l10n = (ScarabLocalizationTool) 331 context.get(ScarabConstants.LOCALIZATION_TOOL); 332 if (l10n != null) 333 { 334 l10n.setFilterEnabled(false); 335 } 336 velocityEngine.mergeTemplate(filename, encoding, 338 eventContext, writer); 339 } 340 catch (Exception e) 341 { 342 renderingError(filename, e); 343 } 344 finally 345 { 346 if (l10n != null) 347 { 348 l10n.setFilterEnabled(true); 349 } 350 } 351 } 352 353 368 private String decodeRequest(Context context, String filename, 369 OutputStream output, String charset, 370 String encoding) 371 throws ServiceException 372 { 373 if (charset == null) 374 { 375 charset = DEFAULT_CHAR_SET; 376 } 377 378 OutputStreamWriter writer = null; 379 try 380 { 381 try 382 { 383 writer = new OutputStreamWriter (output, charset); 384 } 385 catch (Exception e) 386 { 387 renderingError(filename, e); 388 } 389 handleRequest(context, filename, writer, encoding); 390 } 391 finally 392 { 393 try 394 { 395 if (writer != null) 396 { 397 writer.flush(); 398 } 399 } 400 catch (Exception ignored) 401 { 402 } 403 } 404 return charset; 405 } 406 407 416 private final void renderingError(String filename, Throwable e) 417 throws ServiceException 418 { 419 String err = "Error rendering Velocity template: " + filename; 420 getCategory().error(err + ": " + e.getMessage()); 421 if (e instanceof MethodInvocationException) 424 { 425 e = ((MethodInvocationException)e).getWrappedThrowable(); 426 } 427 428 throw new ServiceException(err, e); } 430 431 437 private void initVelocity() 438 throws InitializationException 439 { 440 String path = getRealPath( 443 getConfiguration().getString(VelocityEngine.RUNTIME_LOG, null)); 444 445 if (path != null && path.length() > 0) 446 { 447 getConfiguration().setProperty(VelocityEngine.RUNTIME_LOG, path); 448 } 449 else 450 { 451 String msg = EmailService.SERVICE_NAME + " runtime log file " + 452 "is misconfigured: '" + path + "' is not a valid log file"; 453 454 throw new Error (msg); } 456 457 String key; 462 List keys = new ArrayList (); 463 for (Iterator i = getConfiguration().getKeys(); i.hasNext();) 464 { 465 key = (String ) i.next(); 466 if (key.endsWith(RESOURCE_LOADER_PATH)) 467 { 468 keys.add(key); 469 } 470 } 471 472 int ind; 475 List paths; 476 String entry; 477 for (Iterator i = keys.iterator(); i.hasNext();) 478 { 479 key = (String ) i.next(); 480 paths = getConfiguration().getList(key,null); 481 if (paths != null) 482 { 483 velocityEngine.clearProperty(key); 484 getConfiguration().clearProperty(key); 485 486 for (Iterator j = paths.iterator(); j.hasNext();) 487 { 488 path = (String ) j.next(); 489 if (path.startsWith(JAR_PREFIX + "file")) 490 { 491 ind = path.indexOf("!/"); 494 if (ind >= 0) 495 { 496 entry = path.substring(ind); 497 path = path.substring(9,ind); 498 } 499 else 500 { 501 entry = "!/"; 502 path = path.substring(9); 503 } 504 path = JAR_PREFIX + "file:" + getRealPath(path) + 505 entry; 506 } 507 else if (path.startsWith(ABSOLUTE_PREFIX)) 508 { 509 path = path.substring (ABSOLUTE_PREFIX.length(), 510 path.length()); 511 } 512 else if (!path.startsWith(JAR_PREFIX)) 513 { 514 path = getRealPath(path); 516 } 517 getConfiguration().addProperty(key,path); 519 } 520 } 521 } 522 523 try 524 { 525 velocityEngine.setExtendedProperties(ConfigurationConverter 526 .getExtendedProperties(getConfiguration())); 527 528 velocityEngine.init(); 529 } 530 catch(Exception e) 531 { 532 throw new InitializationException( 536 "Failed to set up VelocityEmailService", e); } 538 } 539 540 548 public boolean templateExists(String template) 549 { 550 return velocityEngine.templateExists(template); 551 } 552 } 553 | Popular Tags |