1 package org.apache.fulcrum.template; 2 3 4 /* 5 * Licensed to the Apache Software Foundation (ASF) under one 6 * or more contributor license agreements. See the NOTICE file 7 * distributed with this work for additional information 8 * regarding copyright ownership. The ASF licenses this file 9 * to you under the Apache License, Version 2.0 (the 10 * "License"); you may not use this file except in compliance 11 * with the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, 16 * software distributed under the License is distributed on an 17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18 * KIND, either express or implied. See the License for the 19 * specific language governing permissions and limitations 20 * under the License. 21 */ 22 23 24 import java.util.ArrayList; 25 import java.util.List; 26 import java.util.Iterator; 27 import java.io.StringWriter; 28 import javax.mail.internet.InternetAddress; 29 import org.apache.commons.mail.SimpleEmail; 30 import org.apache.fulcrum.util.WordWrapUtils; 31 32 /** 33 * This is a simple class for sending email from within the TemplateService. 34 * Essentially, the body of the email is processed with a 35 * TemplateContext object. 36 * The beauty of this is that you can send email from within your 37 * template layer or from your business logic in your Java code. 38 * The body of the email is just a TemplateService template so you can use 39 * all the template functionality of your TemplateService within your emails! 40 * 41 * <p>Example Usage (This all needs to be on one line in your 42 * template): 43 * 44 * <p>Setup your imports: 45 * 46 * <p>import org.apache.fulcrum.template.TemplateEmail; 47 * <p>import org.apache.turbine.modules.ContextAdapter; 48 * 49 * <p>Setup your context: 50 * 51 * <p>context.put ("TemplateEmail", new TemplateEmail() ); 52 * <p>context.put ("contextAdapter", new ContextAdapter(context) ); 53 * 54 * <p>Then, in your template (Velocity Example): 55 * 56 * <pre> 57 * $TemplateEmail.setTo("Jon Stevens", "jon@latchkey.com") 58 * .setFrom("Mom", "mom@mom.com").setSubject("Eat dinner") 59 * .setTemplate("email/momEmail.vm") 60 * .setContext($contextAdapter) 61 * </pre> 62 * 63 * The email/momEmail.vm template will then be parsed with the 64 * Context that was defined with setContext(). 65 * 66 * <p>If you want to use this class from within your Java code all you 67 * have to do is something like this: 68 * 69 * <p>import org.apache.fulcrum.template.TemplateEmail; 70 * <p>import org.apache.turbine.modules.ContextAdapter; 71 * 72 * <pre> 73 * TemplateEmail ve = new TemplateEmail(); 74 * ve.setTo("Jon Stevens", "jon@latchkey.com"); 75 * ve.setFrom("Mom", "mom@mom.com").setSubject("Eat dinner"); 76 * ve.setContext(new ContextAdapter(context)); 77 * ve.setTemplate("email/momEmail.vm") 78 * ve.send(); 79 * </pre> 80 * 81 * <p>(Note that when used within a Velocity template, the send method 82 * will be called for you when Velocity tries to convert the 83 * TemplateEmail to a string by calling toString()).</p> 84 * 85 * <p>If you need your email to be word-wrapped, you can add the 86 * following call to those above: 87 * 88 * <pre> 89 * ve.setWordWrap (60); 90 * </pre> 91 * 92 * <p>This class is just a wrapper around the SimpleEmail class. 93 * Thus, it uses the JavaMail API and also depends on having the 94 * mail.host property set in the System.properties(). 95 * 96 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a> 97 * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a> 98 * @author <a href="mailto:elicia@collab.net">Elicia David</a> 99 * @version $Id: TemplateEmail.java 535465 2007-05-05 06:58:06Z tv $ 100 */ 101 public class TemplateEmail 102 { 103 /** The to name field. */ 104 private String toName = null; 105 106 /** The to email field. */ 107 private String toEmail = null; 108 109 /** The from name field. */ 110 private String fromName = null; 111 112 /** The from email field. */ 113 private String fromEmail = null; 114 115 /** The cc name field. */ 116 private String ccName = null; 117 118 /** The cc email field. */ 119 private String ccEmail = null; 120 121 /** The subject of the message. */ 122 private String subject = null; 123 124 /** The to email list. */ 125 private List toList = null; 126 127 /** The cc list. */ 128 private List ccList = null; 129 130 /** The cc list. */ 131 private List replyToList = null; 132 133 /** The column to word-wrap at. <code>0</code> indicates no wrap. */ 134 private int wordWrap = 0; 135 136 /** 137 * The template to process, relative to the TemplateService template 138 * directory. 139 */ 140 private String template = null; 141 142 /** 143 * A Context 144 */ 145 private TemplateContext context = null; 146 147 /** 148 * The charset 149 */ 150 private String charset = null; 151 152 /** 153 * The templateService to use in generating text 154 * 155 */ 156 private TemplateService templateService; 157 158 /** 159 * Constructor 160 */ 161 public TemplateEmail() 162 { 163 this(null); 164 } 165 166 /** 167 * Constructor 168 */ 169 public TemplateEmail(TemplateContext context) 170 { 171 this.context = context; 172 } 173 174 /** Add a recipient TO to the email. 175 * 176 * @param email A String. 177 * @param name A String. 178 */ 179 public void addTo(String email, String name) 180 throws Exception 181 { 182 try 183 { 184 if ((name == null) || (name.trim().equals(""))) 185 { 186 name = email; 187 } 188 189 if (toList == null) 190 { 191 toList = new ArrayList(); 192 } 193 194 toList.add(new InternetAddress(email, name)); 195 } 196 catch (Exception e) 197 { 198 throw new Exception("Cannot add 'To' recipient: " + e); 199 } 200 } 201 202 /** 203 * Add a recipient CC to the email. 204 * 205 * @param email A String. 206 * @param name A String. 207 */ 208 public void addCc(String email, String name) 209 throws Exception 210 { 211 try 212 { 213 if ((name == null) || (name.trim().equals(""))) 214 { 215 name = email; 216 } 217 218 if (ccList == null) 219 { 220 ccList = new ArrayList(); 221 } 222 223 ccList.add(new InternetAddress(email, name)); 224 } 225 catch (Exception e) 226 { 227 throw new Exception("Cannot add 'CC' recipient: " + e); 228 } 229 } 230 231 232 /** 233 * The given Unicode string will be charset-encoded using the specified 234 * charset. The charset is also used to set the "charset" parameter. 235 * 236 * @param charset a <code>String</code> value 237 */ 238 public void setCharset(String charset) 239 { 240 this.charset = charset; 241 } 242 243 /** 244 * To: name, email 245 * 246 * @param to A String with the TO name. 247 * @param email A String with the TO email. 248 * @return A TemplateEmail (self). 249 */ 250 public TemplateEmail setTo(String to, 251 String email) 252 { 253 this.toName = to; 254 this.toEmail = email; 255 return (this); 256 } 257 258 /** 259 * From: name, email. 260 * 261 * @param from A String with the FROM name. 262 * @param email A String with the FROM email. 263 * @return A TemplateEmail (self). 264 */ 265 public TemplateEmail setFrom(String from, 266 String email) 267 { 268 this.fromName = from; 269 this.fromEmail = email; 270 return (this); 271 } 272 273 /** 274 * CC: name, email. 275 * 276 * @param from A String with the CC name. 277 * @param email A String with the CC email. 278 * @return A TemplateEmail (self). 279 */ 280 public TemplateEmail setCC(String cc, 281 String email) 282 { 283 this.ccName = cc; 284 this.ccEmail = email; 285 return (this); 286 } 287 288 289 /** 290 * Add a reply to address to the email. 291 * 292 * @param email A String. 293 * @param name A String. 294 * @return An Email. 295 * @exception MessagingException. 296 */ 297 public TemplateEmail addReplyTo( String name, String email) 298 { 299 String[] emailName = new String[2]; 300 emailName[0] = email; 301 emailName[1] = name; 302 if (replyToList == null) 303 { 304 replyToList = new ArrayList(3); 305 } 306 replyToList.add(emailName); 307 return this; 308 } 309 310 private List headersList; 311 public TemplateEmail addHeader(String name, String value) 312 { 313 String[] pair = new String[2]; 314 pair[0] = name; 315 pair[1] = value; 316 if (headersList == null) 317 { 318 headersList = new ArrayList(3); 319 } 320 headersList.add(pair); 321 return this; 322 } 323 324 /** 325 * Subject. 326 * 327 * @param subject A String with the subject. 328 * @return A TemplateEmail (self). 329 */ 330 public TemplateEmail setSubject(String subject) 331 { 332 if (subject == null) 333 { 334 this.subject = ""; 335 } 336 else 337 { 338 this.subject = subject; 339 } 340 return (this); 341 } 342 343 /** 344 * TemplateService template to execute. Path is relative to the 345 * TemplateService templates directory. 346 * 347 * @param template A String with the template. 348 * @return A TemplateEmail (self). 349 */ 350 public TemplateEmail setTemplate(String template) 351 { 352 this.template = template; 353 return (this); 354 } 355 356 /** 357 * Set the column at which long lines of text should be word- 358 * wrapped. Setting to zero turns off word-wrap (default). 359 * 360 * NOTE: don't use tabs in your email template document, 361 * or your word-wrapping will be off for the lines with tabs 362 * in them. 363 * 364 * @param wordWrap The column at which to wrap long lines. 365 * @return A TemplateEmail (self). 366 */ 367 public TemplateEmail setWordWrap(int wordWrap) 368 { 369 this.wordWrap = wordWrap; 370 return (this); 371 } 372 373 /** 374 * Set the context object that will be merged with the 375 * template. 376 * 377 * @param context A TemplateContext context object. 378 * @return A TemplateEmail (self). 379 */ 380 public TemplateEmail setContext(TemplateContext context) 381 { 382 this.context = context; 383 return (this); 384 } 385 386 /** 387 * Get the context object that will be merged with the 388 * template. 389 * 390 * @return A TemplateContext. 391 */ 392 public TemplateContext getContext() 393 { 394 return this.context; 395 } 396 397 /** 398 * This method sends the email. It will throw an exception 399 * if the To name or To Email values are null. 400 */ 401 public void send() 402 throws Exception 403 { 404 if (toEmail == null || toName == null) 405 { 406 throw new Exception ("Must set a To:"); 407 } 408 409 // this method is only supposed to send to one user (additional cc: 410 // users are ok.) 411 toList = null; 412 addTo(toEmail, toName); 413 sendMultiple(); 414 } 415 416 /** 417 * This method sends the email to multiple addresses. 418 */ 419 public void sendMultiple() 420 throws Exception 421 { 422 if (toList == null || toList.isEmpty()) 423 { 424 throw new Exception ("Must set a To:"); 425 } 426 427 // Process the template. 428 StringWriter sw = new StringWriter(); 429 templateService.handleRequest(context,template, sw); 430 String body = sw.toString(); 431 432 // If the caller desires word-wrapping, do it here 433 if (wordWrap > 0) 434 { 435 body = WordWrapUtils.wrapText (body, 436 System.getProperty("line.separator"), 437 wordWrap); 438 } 439 440 SimpleEmail se = new SimpleEmail(); 441 if (charset != null) 442 { 443 se.setCharset(charset); 444 } 445 se.setFrom(fromEmail, fromName); 446 se.setTo(toList); 447 if (ccList != null && !ccList.isEmpty()) 448 { 449 se.setCc(ccList); 450 } 451 addReplyTo(se); 452 se.setSubject(subject); 453 se.setMsg(body); 454 455 if (headersList != null) 456 { 457 Iterator i = headersList.iterator(); 458 while (i.hasNext()) 459 { 460 String[] pair = (String[])i.next(); 461 se.addHeader(pair[0], pair[1]); 462 } 463 } 464 465 se.send(); 466 } 467 468 469 470 /** 471 * A javabean style setter for passing in manually a templateservice 472 * @param templateService The templateService to set. 473 */ 474 public void setTemplateService(TemplateService templateService) { 475 this.templateService = templateService; 476 } 477 /** 478 * if any reply-to email addresses exist, add them to the SimpleEmail 479 * 480 * @param se a <code>SimpleEmail</code> value 481 * @exception Exception if an error occurs 482 */ 483 private void addReplyTo(SimpleEmail se) 484 throws Exception 485 { 486 if (replyToList != null) 487 { 488 Iterator i = replyToList.iterator(); 489 while (i.hasNext()) 490 { 491 String[] emailName = (String[])i.next(); 492 se.addReplyTo(emailName[0], emailName[1]); 493 } 494 } 495 } 496 497 /** 498 * The method toString() calls send() for ease of use within a 499 * TemplateService template (see example usage above). 500 * 501 * @return An empty string. 502 */ 503 public String toString() 504 { 505 try 506 { 507 send(); 508 } 509 catch (Exception e) 510 { 511 // Log.error ("TemplateEmail error", e); 512 } 513 return ""; 514 } 515 }