1 package org.tigris.scarab.util; 2 3 48 49 import java.util.ArrayList ; 50 import java.util.Collection ; 51 import java.util.HashMap ; 52 import java.util.Iterator ; 53 import java.util.List ; 54 import java.util.Locale ; 55 import java.util.Map ; 56 import java.util.StringTokenizer ; 57 58 import javax.mail.SendFailedException ; 59 import javax.mail.internet.InternetAddress ; 60 61 import org.apache.fulcrum.ServiceException; 62 import org.apache.fulcrum.template.TemplateContext; 63 import org.apache.fulcrum.template.TemplateEmail; 64 import org.apache.fulcrum.velocity.ContextAdapter; 65 import org.apache.turbine.Turbine; 66 import org.tigris.scarab.om.GlobalParameter; 67 import org.tigris.scarab.om.GlobalParameterManager; 68 import org.tigris.scarab.om.Module; 69 import org.tigris.scarab.om.ScarabUser; 70 import org.tigris.scarab.services.email.VelocityEmail; 71 import org.tigris.scarab.tools.ScarabLocalizationTool; 72 import org.tigris.scarab.tools.localization.L10NKeySet; 73 74 82 public class Email extends TemplateEmail 83 { 84 private static final int TO = 0; 85 private static final int CC = 1; 86 87 91 public static void sendEmail(EmailContext context, Module module, 92 Object fromUser, Object replyToUser, 93 ScarabUser toUser, String template) 94 throws Exception 95 { 96 Collection toUsers = new ArrayList (2); 97 toUsers.add(toUser); 98 sendEmail(context, module, fromUser, replyToUser, toUsers, null, 99 template); 100 } 101 102 106 public static void sendEmail(EmailContext context, Module module, 107 Object fromUser, Object replyToUser, 108 Collection toUsers, Collection ccUsers, 109 String template) 110 throws Exception 111 { 112 if (!GlobalParameterManager.getBoolean(GlobalParameter.EMAIL_ENABLED, 113 module)) 114 { 115 return; 116 } 117 118 if (toUsers == null) 124 { 125 toUsers = new ArrayList (); 126 } 127 128 if (ccUsers == null) 129 { 130 ccUsers = new ArrayList (); 131 } 132 133 ccUsers.removeAll(toUsers); 137 138 String archiveEmail = module.getArchiveEmail(); 139 if (archiveEmail != null && archiveEmail.trim().length() == 0) 140 { 141 archiveEmail = null; 142 } 143 144 Map userLocaleMap = groupAddressesByLocale(module, toUsers, ccUsers, 145 archiveEmail); 146 147 for (Iterator i = userLocaleMap.keySet().iterator(); i.hasNext();) 148 { 149 Locale locale = (Locale ) i.next(); 150 List [] toAndCC = (List []) userLocaleMap.get(locale); 151 List to = toAndCC[TO]; 152 List cc = toAndCC[CC]; 153 154 sendEmailInLocale(context, module, fromUser, replyToUser, to, cc, 155 template, locale); 156 } 157 158 } 159 160 161 private static void sendEmailInLocale(EmailContext context, Module module, 162 Object fromUser, Object replyToUser, 163 List toAddresses, List ccAddresses, 164 String template, Locale locale) 165 throws Exception 166 { 167 Log.get().debug("Sending email for locale=" + locale); 168 169 ScarabLocalizationTool l10n = new ScarabLocalizationTool(); 171 context.setLocalizationTool(l10n); 172 l10n.init(locale); 173 174 Email te = getEmail(context, module, fromUser, replyToUser, template); 175 te.setCharset(getCharset(locale)); 176 177 boolean atLeastOneTo = false; 178 for (Iterator iTo = toAddresses.iterator(); iTo.hasNext();) 179 { 180 InternetAddress a = (InternetAddress ) iTo.next(); 181 te.addTo(a.getAddress(), a.getPersonal()); 182 atLeastOneTo = true; 183 Log.get().debug("Added To: " + a.getAddress()); 184 } 185 for (Iterator iCC = ccAddresses.iterator(); iCC.hasNext();) 186 { 187 InternetAddress a = (InternetAddress ) iCC.next(); 188 String email = a.getAddress(); 189 String name = a.getPersonal(); 190 191 if (atLeastOneTo) 196 { 197 te.addCc(email, name); 198 } 199 else 200 { 201 te.addTo(email, name); 202 atLeastOneTo = true; 205 } 206 Log.get().debug("Added CC: " + email); 207 } 208 209 try{ 210 te.sendMultiple(); 211 } 212 catch(SendFailedException sfe) 213 { 214 Throwable t = sfe.getNextException(); 215 throw new ScarabException(L10NKeySet.ExceptionEmailFailure,t); 216 } 217 } 218 219 private static List expandMultipleAddresses(String addresses) 220 { 221 List expanded = new ArrayList (); 222 StringTokenizer st = new StringTokenizer (addresses, ",;"); 223 while (st.hasMoreTokens()) 224 expanded.add(st.nextToken().trim()); 225 return expanded; 226 } 227 228 238 private static Map groupAddressesByLocale(Module module, 239 Collection toUsers, 240 Collection ccUsers, 241 String archiveEmail) 242 throws Exception 243 { 244 Map result = new HashMap (); 245 for (Iterator iter = toUsers.iterator(); iter.hasNext();) 246 { 247 fileUser(result, (ScarabUser) iter.next(), module, TO); 248 } 249 250 for (Iterator iter = ccUsers.iterator(); iter.hasNext();) 251 { 252 fileUser(result, (ScarabUser) iter.next(), module, CC); 253 } 254 if (archiveEmail != null) 255 { 256 List expandedArchive = expandMultipleAddresses(archiveEmail); 257 for (Iterator iter = expandedArchive.iterator(); iter.hasNext(); ) 258 fileAddress(result, new InternetAddress ((String )iter.next()), 259 chooseLocale(null, module), CC); 260 } 261 return result; 262 } 263 264 private static void fileAddress(Map userLocaleMap, InternetAddress address, 265 Locale locale, int toOrCC) 266 { 267 List [] toAndCC = (List []) userLocaleMap.get(locale); 268 if (toAndCC == null) 269 { 270 toAndCC = new List [2]; 271 toAndCC[0] = new ArrayList (); 272 toAndCC[1] = new ArrayList (); 273 userLocaleMap.put(locale, toAndCC); 274 } 275 toAndCC[toOrCC].add(address); 276 } 277 278 private static void fileUser(Map userLocaleMap, ScarabUser user, 279 Module module, int toOrCC) throws Exception 280 { 281 fileAddress(userLocaleMap, new InternetAddress (user.getEmail(), user 282 .getName()), chooseLocale(user, module), toOrCC); 283 } 284 285 294 protected String handleRequest() throws ServiceException 295 { 296 String result = null; 297 try 298 { 299 result = VelocityEmail.handleRequest(new ContextAdapter( 300 getContext()), getTemplate()); 301 } 302 catch (Exception e) 303 { 304 throw new ServiceException(e); } 306 return result; 307 } 308 309 319 private static Email getEmail(EmailContext context, Module module, 320 Object fromUser, Object replyToUser, 321 String template) throws Exception 322 { 323 Email te = new Email(); 324 if (context == null) 325 { 326 context = new EmailContext(); 327 } 328 te.setContext(context); 329 330 EmailLink el = EmailLinkFactory.getInstance(module); 331 context.setLinkTool(el); 332 333 String [] nameAndAddr = getNameAndAddress(fromUser); 334 te.setFrom(nameAndAddr[0], nameAndAddr[1]); 335 336 nameAndAddr = getNameAndAddress(replyToUser); 337 te.addReplyTo(nameAndAddr[0], nameAndAddr[1]); 338 339 if (template == null) 340 { 341 template = Turbine.getConfiguration().getString( 342 "scarab.email.default.template", "Default.vm"); 343 } 344 te.setTemplate(prependDir(template)); 345 String subjectTemplate = context.getSubjectTemplate(); 346 if (subjectTemplate == null) 347 { 348 int templateLength = template.length(); 349 StringBuffer templateSB = new StringBuffer (templateLength + 7); 351 templateSB.append(template.substring(0, templateLength - 3)); 353 subjectTemplate = templateSB.append("Subject.vm").toString(); 354 } 355 356 te.setSubject(getSubject(context, subjectTemplate)); 357 return te; 358 } 359 360 365 private static String [] getNameAndAddress(Object input) 366 { 367 String [] nameAndAddr; 368 if (input instanceof ScarabUser) 369 { 370 ScarabUser u = (ScarabUser) input; 371 nameAndAddr = new String []{u.getName(), u.getEmail()}; 372 } 373 else if (input instanceof String []) 374 { 375 nameAndAddr = (String []) input; 376 } 377 else 378 { 379 String keyBase = (String ) input; 382 if (keyBase == null) 383 { 384 keyBase = "scarab.email.default"; 385 } 386 387 390 nameAndAddr = new String [2]; 391 nameAndAddr[0] = Turbine.getConfiguration().getString( 392 keyBase + ".fromName", "Scarab System"); 393 nameAndAddr[1] = Turbine.getConfiguration().getString( 394 keyBase + ".fromAddress", "help@localhost"); 395 } 396 return nameAndAddr; 397 } 398 399 private static String getSubject(TemplateContext context, String template) 400 { 401 template = prependDir(template); 402 String result = null; 403 try 404 { 405 result = VelocityEmail.handleRequest(new ContextAdapter(context), 407 template); 408 if (result != null) 409 { 410 result = result.trim(); 411 } 412 String subject = (String ) context.get("emailSubject"); 416 if (subject != null) 417 { 418 result = subject.trim(); 419 } 420 } 421 catch (Exception e) 422 { 423 Log.get() 424 .error("Error rendering subject for " + template + ". ", e); 425 result = "Scarab System Notification"; 426 } 427 return result; 428 } 429 430 private static String prependDir(String template) 431 { 432 boolean b = false; 433 try 434 { 435 b = GlobalParameterManager 436 .getBoolean(GlobalParameter.EMAIL_INCLUDE_ISSUE_DETAILS); 437 } 438 catch (Exception e) 439 { 440 Log.get().debug("", e); 441 } 443 return b ? "email/" + template : "basic_email/" + template; 444 } 445 446 458 public static String getCharset(Locale locale) 459 { 460 String charset = Turbine.getConfiguration().getString( 461 ScarabConstants.DEFAULT_EMAIL_ENCODING_KEY, "").trim(); 462 if (charset.length() == 0 || "native".equalsIgnoreCase(charset)) 463 { 464 if ("ja".equals(locale.getLanguage())) 465 { 466 charset = "ISO-2022-JP"; 467 } 468 else 469 { 470 charset = ComponentLocator.getMimeTypeService().getCharSet(locale); 471 } 472 } 473 474 return charset; 475 } 476 477 private static Locale chooseLocale(ScarabUser user, Module module) 478 { 479 Locale locale = null; 480 if (user != null) 481 { 482 try 483 { 484 locale = user.getPreferredLocale(); 485 } 486 catch (Exception e) 487 { 488 Log.get().error( 489 "Couldn't determine locale for user " + user 490 .getUserName(), e); 491 } 492 } 493 if (locale == null) 494 { 495 if (module != null && module.getLocale() != null) 496 { 497 locale = module.getLocale(); 498 } 499 else 500 { 501 locale = ScarabConstants.DEFAULT_LOCALE; 502 } 503 } 504 return locale; 505 } 506 } 507 | Popular Tags |