1 23 package org.infoglue.cms.applications.workflowtool.function.email; 24 25 import java.util.ArrayList ; 26 import java.util.Collection ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 import java.util.StringTokenizer ; 30 31 import javax.activation.DataHandler ; 32 import javax.mail.Address ; 33 import javax.mail.BodyPart ; 34 import javax.mail.Message ; 35 import javax.mail.SendFailedException ; 36 import javax.mail.internet.InternetAddress ; 37 import javax.mail.internet.MimeBodyPart ; 38 import javax.mail.internet.MimeMessage ; 39 import javax.mail.internet.MimeMultipart ; 40 41 import org.apache.log4j.Logger; 42 import org.infoglue.cms.applications.workflowtool.function.InfoglueFunction; 43 import org.infoglue.cms.exception.SystemException; 44 import org.infoglue.cms.util.mail.ByteDataSource; 45 import org.infoglue.cms.util.mail.MailService; 46 import org.infoglue.cms.util.mail.MailServiceFactory; 47 import org.infoglue.cms.util.mail.StringDataSource; 48 49 import com.opensymphony.workflow.WorkflowException; 50 51 54 public class EmailFunction extends InfoglueFunction 55 { 56 private final static Logger logger = Logger.getLogger(EmailFunction.class.getName()); 57 58 61 private static final String ADDRESS_DELIMITER = ","; 62 63 66 private static final String EMAIL_PARAMETER_PREFIX = "email_"; 67 68 71 public static final String ILLEGAL_ADDRESSES_PARAMETER = EMAIL_PARAMETER_PREFIX + "IllegalAddresses"; 72 73 76 public static final String ILLEGAL_ADDRESSES_PROPERTYSET_KEY = "email_IllegalAddresses"; 77 78 81 public static final String TO_PARAMETER = EMAIL_PARAMETER_PREFIX + "to"; 82 83 86 public static final String FROM_PARAMETER = EMAIL_PARAMETER_PREFIX + "from"; 87 88 91 public static final String ATTACHMENTS_PARAMETER = "attachments"; 92 93 96 private static final String TO_ARGUMENT = "to"; 97 98 101 private static final String FROM_ARGUMENT = "from"; 102 103 106 private static final String SUBJECT_ARGUMENT = "subject"; 107 108 111 private static final String BODY_ARGUMENT = "body"; 112 113 116 private static final String BODY_TYPE_ARGUMENT = "type"; 117 118 121 private static final String SILENT_MODE_ARGUMENT = "silent"; 122 123 126 private static final String STATUS_OK = "status.email.ok"; 127 128 131 private static final String STATUS_NOK = "status.email.nok"; 132 133 136 private MailService service; 137 138 141 private MimeMessage message; 142 143 146 private MimeMultipart multipart; 147 148 151 private Collection attachments = new ArrayList (); 152 153 156 private Collection illegalAddresses; 158 161 private boolean silentMode; 162 163 166 public EmailFunction() 167 { 168 super(); 169 } 170 171 174 protected void execute() throws WorkflowException 175 { 176 setFunctionStatus(silentMode ? STATUS_OK : STATUS_NOK); 177 try 178 { 179 process(); 180 } 181 catch(Exception e) 182 { 183 if(!silentMode) 184 { 185 throwException(e); 186 } 187 logger.warn("[silent mode]", e); 188 } 189 processIllegalAddresses(); 190 } 191 192 195 private void processIllegalAddresses() 196 { 197 if(illegalAddresses.isEmpty()) 198 { 199 removeFromPropertySet(ILLEGAL_ADDRESSES_PROPERTYSET_KEY); 200 } 201 else 202 { 203 final StringBuffer sb = new StringBuffer (); 204 for(final Iterator i = illegalAddresses.iterator(); i.hasNext(); ) 205 { 206 final String address = i.next().toString(); 207 sb.append((sb.length() > 0 ? "," : "") + address); 208 } 209 setPropertySetDataString(ILLEGAL_ADDRESSES_PROPERTYSET_KEY, sb.toString()); 210 } 211 setParameter(ILLEGAL_ADDRESSES_PARAMETER, new ArrayList ()); 212 } 213 214 217 private void process() throws WorkflowException 218 { 219 if(illegalAddresses.isEmpty()) 220 { 221 initializeMailService(); 222 createMessage(); 223 sendMessage(); 224 } 225 } 226 227 230 private void createMessage() throws WorkflowException 231 { 232 if(attachments.isEmpty()) 233 { 234 createSimpleMessage(); 235 } 236 else 237 { 238 createMultipartMessage(); 239 } 240 } 241 242 245 private void createSimpleMessage() throws WorkflowException 246 { 247 logger.debug("Creating simple message."); 248 initializeMessage(); 249 initializeSimpleBody(); 250 } 251 252 255 private void createMultipartMessage() throws WorkflowException 256 { 257 logger.debug("Creating message."); 258 initializeMessage(); 259 initializeMultipart(); 260 createMainBodyPart(); 261 createAttachments(); 262 } 263 264 267 private void initializeMessage() throws WorkflowException 268 { 269 logger.debug("Initializing message."); 270 message = service.createMessage(); 271 initializeTo(); 272 initializeFrom(); 273 initializeSubject(); 274 } 275 276 279 private void initializeSimpleBody() throws WorkflowException 280 { 281 logger.debug("Initializing simple body."); 282 try 283 { 284 message.setDataHandler(getDataHandler(translate(getArgument(BODY_ARGUMENT)), translate(getArgument(BODY_TYPE_ARGUMENT)))); 285 } 286 catch(Exception e) 287 { 288 throwException(e); 289 } 290 } 291 292 295 private void initializeMultipart() throws WorkflowException 296 { 297 logger.debug("Initializing multipart."); 298 try 299 { 300 multipart = new MimeMultipart (); 301 message.setContent(multipart); 302 } 303 catch(Exception e) 304 { 305 throwException(e); 306 } 307 } 308 309 312 private void initializeTo() throws WorkflowException 313 { 314 logger.debug("Initializing to."); 315 try 316 { 317 if(argumentExists(TO_ARGUMENT)) 318 { 319 logger.debug("Adding 'to' from argument [" + getArgument(TO_ARGUMENT) + "]."); 320 message.addRecipients(Message.RecipientType.TO, createAddresses(getArgument(TO_ARGUMENT))); 321 } 322 if(parameterExists(TO_PARAMETER)) 323 { 324 logger.debug("Adding 'to' from parameters"); 325 message.addRecipients(Message.RecipientType.TO, addressesToArray((List ) getParameter(TO_PARAMETER))); 326 } 327 } 328 catch(Exception e) 329 { 330 throwException(e); 331 } 332 } 333 334 337 private void initializeFrom() throws WorkflowException 338 { 339 logger.debug("Initializing from."); 340 try 341 { 342 if(argumentExists(FROM_ARGUMENT)) 343 { 344 logger.debug("Adding 'from' from argument [" + getArgument(FROM_ARGUMENT) + "]."); 345 message.addFrom(createAddresses(getArgument(FROM_ARGUMENT))); 346 } 347 if(parameterExists(FROM_PARAMETER)) 348 { 349 logger.debug("Adding 'from' from parameter."); 350 message.addFrom(addressesToArray((List ) getParameter(FROM_PARAMETER))); 351 } 352 } 353 catch(Exception e) 354 { 355 throwException(e); 356 } 357 } 358 359 362 private void initializeSubject() throws WorkflowException 363 { 364 logger.debug("Initializing subject."); 365 try 366 { 367 message.setSubject(translate(getArgument(SUBJECT_ARGUMENT)), UTF8_ENCODING); 368 } 369 catch(Exception e) 370 { 371 throwException(e); 372 } 373 } 374 375 378 private void createMainBodyPart() throws WorkflowException 379 { 380 logger.debug("Initializing main body part."); 381 try 382 { 383 final BodyPart part = new MimeBodyPart (); 384 part.setDataHandler(getDataHandler(translate(getArgument(BODY_ARGUMENT)), translate(getArgument(BODY_TYPE_ARGUMENT)))); 385 multipart.addBodyPart(part); 386 } 387 catch(Exception e) 388 { 389 throwException(e); 390 } 391 } 392 393 396 private void createAttachments() throws WorkflowException 397 { 398 logger.debug("Found " + attachments.size() + " attachments."); 399 for(final Iterator i = attachments.iterator(); i.hasNext(); ) 400 { 401 createAttachment((Attachment) i.next()); 402 } 403 } 404 405 408 private void createAttachment(final Attachment attachment) throws WorkflowException 409 { 410 try 411 { 412 final BodyPart part = new MimeBodyPart (); 413 part.setDataHandler(getDataHandler(attachment.getBytes(), attachment.getContentType())); 414 part.setFileName(attachment.getName()); 415 multipart.addBodyPart(part); 416 } 417 catch(Exception e) 418 { 419 throwException(e); 420 } 421 } 422 423 426 private InternetAddress [] createAddresses(final String s) throws WorkflowException 427 { 428 final List addresses = new ArrayList (); 429 for(final StringTokenizer st = new StringTokenizer (s, ADDRESS_DELIMITER); st.hasMoreTokens(); ) 430 { 431 final Address address = createAddress(st.nextToken()); 432 if(address != null) { 434 addresses.add(address); 435 } 436 } 437 return addressesToArray(addresses); 438 } 439 440 443 private InternetAddress [] addressesToArray(final List list) 444 { 445 final InternetAddress [] addresses = new InternetAddress [list.size()]; 446 for(int i = 0; i < list.size(); ++i) 447 { 448 addresses[i] = (InternetAddress ) list.get(i); 449 } 450 return addresses; 451 } 452 453 456 private InternetAddress createAddress(final String email) 457 { 458 try 459 { 460 return new InternetAddress (email); 461 } 462 catch(Exception e) 463 { 464 illegalAddresses.add(email); 465 } 466 return null; 467 } 468 469 472 private void initializeMailService() throws WorkflowException 473 { 474 logger.debug("Initializing mail service."); 475 try 476 { 477 service = MailServiceFactory.getService(); 478 } 479 catch(Exception e) 480 { 481 throwException(e); 482 } 483 } 484 485 488 private void sendMessage() throws WorkflowException 489 { 490 logger.debug("Sending message."); 491 if(illegalAddresses.isEmpty()) 492 { 493 try 494 { 495 if(hasRecipients()) 496 { 497 service.send(message); 498 } 499 setFunctionStatus(STATUS_OK); 500 } 501 catch(SystemException e) 502 { 503 handleSendException(e); 504 } 505 } 506 } 507 508 511 private boolean hasRecipients() throws WorkflowException 512 { 513 try 514 { 515 return (message.getAllRecipients() != null) && message.getAllRecipients().length > 0; 516 } 517 catch(Exception e) 518 { 519 throwException(e); 520 } 521 return false; 522 } 523 524 527 private void handleSendException(final SystemException e) throws WorkflowException 528 { 529 if(e.getCause() instanceof SendFailedException ) 530 { 531 populateIllegalAddresses((SendFailedException ) e.getCause()); 532 } 533 else 534 { 535 throwException(e); 536 } 537 } 538 539 542 private void populateIllegalAddresses(final SendFailedException e) 543 { 544 final Address [] invalidAddresses = (e.getInvalidAddresses() == null) ? new Address [0] : e.getInvalidAddresses(); 545 for(int i=0; i<invalidAddresses.length; ++i) 546 { 547 illegalAddresses.add(invalidAddresses[i].toString()); 548 } 549 } 550 551 554 private DataHandler getDataHandler(final String content, final String type) 555 { 556 return new DataHandler (new StringDataSource(content, getContentType(type), UTF8_ENCODING)); 557 } 558 559 562 private DataHandler getDataHandler(final byte[] content, final String type) 563 { 564 return new DataHandler (new ByteDataSource(content, type)); 565 } 566 567 570 private String getContentType(final String type) 571 { 572 return type + ";charset=" + UTF8_ENCODING; 573 } 574 575 581 protected void initialize() throws WorkflowException 582 { 583 super.initialize(); 584 this.illegalAddresses = (Collection ) getParameter(EmailFunction.ILLEGAL_ADDRESSES_PARAMETER, new ArrayList ()); 585 this.silentMode = getArgument(SILENT_MODE_ARGUMENT, "false").equalsIgnoreCase("true"); 586 this.attachments = (Collection ) getParameter(ATTACHMENTS_PARAMETER, new ArrayList ()); 587 } 588 } 589 | Popular Tags |