KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > infoglue > cms > applications > workflowtool > function > email > EmailFunction


1 /* ===============================================================================
2  *
3  * Part of the InfoGlue Content Management Platform (www.infoglue.org)
4  *
5  * ===============================================================================
6  *
7  * Copyright (C)
8  *
9  * This program is free software; you can redistribute it and/or modify it under
10  * the terms of the GNU General Public License version 2, as published by the
11  * Free Software Foundation. See the file LICENSE.html for more information.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY, including the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along with
18  * this program; if not, write to the Free Software Foundation, Inc. / 59 Temple
19  * Place, Suite 330 / Boston, MA 02111-1307 / USA.
20  *
21  * ===============================================================================
22  */

23 package org.infoglue.cms.applications.workflowtool.function.email;
24
25 import java.util.ArrayList JavaDoc;
26 import java.util.Collection JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.List JavaDoc;
29 import java.util.StringTokenizer JavaDoc;
30
31 import javax.activation.DataHandler JavaDoc;
32 import javax.mail.Address JavaDoc;
33 import javax.mail.BodyPart JavaDoc;
34 import javax.mail.Message JavaDoc;
35 import javax.mail.SendFailedException JavaDoc;
36 import javax.mail.internet.InternetAddress JavaDoc;
37 import javax.mail.internet.MimeBodyPart JavaDoc;
38 import javax.mail.internet.MimeMessage JavaDoc;
39 import javax.mail.internet.MimeMultipart JavaDoc;
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 /**
52  *
53  */

54 public class EmailFunction extends InfoglueFunction
55 {
56     private final static Logger logger = Logger.getLogger(EmailFunction.class.getName());
57
58     /**
59      *
60      */

61     private static final String JavaDoc ADDRESS_DELIMITER = ",";
62     
63     /**
64      *
65      */

66     private static final String JavaDoc EMAIL_PARAMETER_PREFIX = "email_";
67     
68     /**
69      *
70      */

71     public static final String JavaDoc ILLEGAL_ADDRESSES_PARAMETER = EMAIL_PARAMETER_PREFIX + "IllegalAddresses";
72     
73     /**
74      *
75      */

76     public static final String JavaDoc ILLEGAL_ADDRESSES_PROPERTYSET_KEY = "email_IllegalAddresses";
77     
78     /**
79      *
80      */

81     public static final String JavaDoc TO_PARAMETER = EMAIL_PARAMETER_PREFIX + "to";
82     
83     /**
84      *
85      */

86     public static final String JavaDoc FROM_PARAMETER = EMAIL_PARAMETER_PREFIX + "from";
87     
88     /**
89      *
90      */

91     public static final String JavaDoc ATTACHMENTS_PARAMETER = "attachments";
92     
93     /**
94      *
95      */

96     private static final String JavaDoc TO_ARGUMENT = "to";
97
98     /**
99      *
100      */

101     private static final String JavaDoc FROM_ARGUMENT = "from";
102
103     /**
104      *
105      */

106     private static final String JavaDoc SUBJECT_ARGUMENT = "subject";
107
108     /**
109      *
110      */

111     private static final String JavaDoc BODY_ARGUMENT = "body";
112
113     /**
114      *
115      */

116     private static final String JavaDoc BODY_TYPE_ARGUMENT = "type";
117     
118     /**
119      *
120      */

121     private static final String JavaDoc SILENT_MODE_ARGUMENT = "silent";
122     
123     /**
124      *
125      */

126     private static final String JavaDoc STATUS_OK = "status.email.ok";
127     
128     /**
129      *
130      */

131     private static final String JavaDoc STATUS_NOK = "status.email.nok";
132     
133     /**
134      *
135      */

136     private MailService service;
137     
138     /**
139      *
140      */

141     private MimeMessage JavaDoc message;
142     
143     /**
144      *
145      */

146     private MimeMultipart JavaDoc multipart;
147
148     /**
149      *
150      */

151     private Collection JavaDoc attachments = new ArrayList JavaDoc();
152     
153     /**
154      * The illegal addresses.
155      */

156     private Collection JavaDoc illegalAddresses; // type: <String>
157

158     /**
159      * Indicates if a failure should be ignored.
160      */

161     private boolean silentMode;
162     
163     /**
164      *
165      */

166     public EmailFunction()
167     {
168         super();
169     }
170
171     /**
172      *
173      */

174     protected void execute() throws WorkflowException
175     {
176         setFunctionStatus(silentMode ? STATUS_OK : STATUS_NOK);
177         try
178         {
179             process();
180         }
181         catch(Exception JavaDoc e)
182         {
183             if(!silentMode)
184             {
185                 throwException(e);
186             }
187             logger.warn("[silent mode]", e);
188         }
189         processIllegalAddresses();
190     }
191     
192     /**
193      *
194      */

195     private void processIllegalAddresses()
196     {
197         if(illegalAddresses.isEmpty())
198         {
199             removeFromPropertySet(ILLEGAL_ADDRESSES_PROPERTYSET_KEY);
200         }
201         else
202         {
203             final StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
204             for(final Iterator JavaDoc i = illegalAddresses.iterator(); i.hasNext(); )
205             {
206                 final String JavaDoc 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 JavaDoc());
212     }
213     
214     /**
215      *
216      */

217     private void process() throws WorkflowException
218     {
219         if(illegalAddresses.isEmpty())
220         {
221             initializeMailService();
222             createMessage();
223             sendMessage();
224         }
225     }
226     
227     /**
228      *
229      */

230     private void createMessage() throws WorkflowException
231     {
232         if(attachments.isEmpty())
233         {
234             createSimpleMessage();
235         }
236         else
237         {
238             createMultipartMessage();
239         }
240     }
241     
242     /**
243      *
244      */

245     private void createSimpleMessage() throws WorkflowException
246     {
247         logger.debug("Creating simple message.");
248         initializeMessage();
249         initializeSimpleBody();
250     }
251
252     /**
253      *
254      */

255     private void createMultipartMessage() throws WorkflowException
256     {
257         logger.debug("Creating message.");
258         initializeMessage();
259         initializeMultipart();
260         createMainBodyPart();
261         createAttachments();
262     }
263     
264     /**
265      *
266      */

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     /**
277      *
278      */

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 JavaDoc e)
287         {
288             throwException(e);
289         }
290     }
291     
292     /**
293      *
294      */

295     private void initializeMultipart() throws WorkflowException
296     {
297         logger.debug("Initializing multipart.");
298         try
299         {
300             multipart = new MimeMultipart JavaDoc();
301             message.setContent(multipart);
302         }
303         catch(Exception JavaDoc e)
304         {
305             throwException(e);
306         }
307     }
308     
309     /**
310      *
311      */

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 JavaDoc) getParameter(TO_PARAMETER)));
326             }
327         }
328         catch(Exception JavaDoc e)
329         {
330             throwException(e);
331         }
332     }
333     
334     /**
335      *
336      */

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 JavaDoc) getParameter(FROM_PARAMETER)));
351             }
352         }
353         catch(Exception JavaDoc e)
354         {
355             throwException(e);
356         }
357     }
358     
359     /**
360      *
361      */

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 JavaDoc e)
370         {
371             throwException(e);
372         }
373     }
374     
375     /**
376      *
377      */

378     private void createMainBodyPart() throws WorkflowException
379     {
380         logger.debug("Initializing main body part.");
381         try
382         {
383             final BodyPart JavaDoc part = new MimeBodyPart JavaDoc();
384             part.setDataHandler(getDataHandler(translate(getArgument(BODY_ARGUMENT)), translate(getArgument(BODY_TYPE_ARGUMENT))));
385             multipart.addBodyPart(part);
386         }
387         catch(Exception JavaDoc e)
388         {
389             throwException(e);
390         }
391     }
392     
393     /**
394      *
395      */

396     private void createAttachments() throws WorkflowException
397     {
398         logger.debug("Found " + attachments.size() + " attachments.");
399         for(final Iterator JavaDoc i = attachments.iterator(); i.hasNext(); )
400         {
401             createAttachment((Attachment) i.next());
402         }
403     }
404     
405     /**
406      *
407      */

408     private void createAttachment(final Attachment attachment) throws WorkflowException
409     {
410         try
411         {
412             final BodyPart JavaDoc part = new MimeBodyPart JavaDoc();
413             part.setDataHandler(getDataHandler(attachment.getBytes(), attachment.getContentType()));
414             part.setFileName(attachment.getName());
415             multipart.addBodyPart(part);
416         }
417         catch(Exception JavaDoc e)
418         {
419             throwException(e);
420         }
421     }
422
423     /**
424      *
425      */

426     private InternetAddress JavaDoc[] createAddresses(final String JavaDoc s) throws WorkflowException
427     {
428         final List JavaDoc addresses = new ArrayList JavaDoc();
429         for(final StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(s, ADDRESS_DELIMITER); st.hasMoreTokens(); )
430         {
431             final Address JavaDoc address = createAddress(st.nextToken());
432             if(address != null) // illegal address?
433
{
434                 addresses.add(address);
435             }
436         }
437         return addressesToArray(addresses);
438     }
439     
440     /**
441      *
442      */

443     private InternetAddress JavaDoc[] addressesToArray(final List JavaDoc list)
444     {
445         final InternetAddress JavaDoc[] addresses = new InternetAddress JavaDoc[list.size()];
446         for(int i = 0; i < list.size(); ++i)
447         {
448             addresses[i] = (InternetAddress JavaDoc) list.get(i);
449         }
450         return addresses;
451     }
452     
453     /**
454      *
455      */

456     private InternetAddress JavaDoc createAddress(final String JavaDoc email)
457     {
458         try
459         {
460             return new InternetAddress JavaDoc(email);
461         }
462         catch(Exception JavaDoc e)
463         {
464             illegalAddresses.add(email);
465         }
466         return null;
467     }
468     
469     /**
470      *
471      */

472     private void initializeMailService() throws WorkflowException
473     {
474         logger.debug("Initializing mail service.");
475         try
476         {
477             service = MailServiceFactory.getService();
478         }
479         catch(Exception JavaDoc e)
480         {
481             throwException(e);
482         }
483     }
484     
485     /**
486      *
487      */

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        /**
509     *
510     */

511     private boolean hasRecipients() throws WorkflowException
512     {
513         try
514         {
515             return (message.getAllRecipients() != null) && message.getAllRecipients().length > 0;
516         }
517         catch(Exception JavaDoc e)
518         {
519             throwException(e);
520         }
521         return false;
522     }
523    
524     /**
525      *
526      */

527     private void handleSendException(final SystemException e) throws WorkflowException
528     {
529         if(e.getCause() instanceof SendFailedException JavaDoc)
530         {
531             populateIllegalAddresses((SendFailedException JavaDoc) e.getCause());
532         }
533         else
534         {
535             throwException(e);
536         }
537     }
538     
539     /**
540      *
541      */

542     private void populateIllegalAddresses(final SendFailedException JavaDoc e)
543     {
544         final Address JavaDoc[] invalidAddresses = (e.getInvalidAddresses() == null) ? new Address JavaDoc[0] : e.getInvalidAddresses();
545         for(int i=0; i<invalidAddresses.length; ++i)
546         {
547             illegalAddresses.add(invalidAddresses[i].toString());
548         }
549     }
550     
551     /**
552      *
553      */

554     private DataHandler JavaDoc getDataHandler(final String JavaDoc content, final String JavaDoc type)
555     {
556         return new DataHandler JavaDoc(new StringDataSource(content, getContentType(type), UTF8_ENCODING));
557     }
558
559     /**
560      *
561      */

562     private DataHandler JavaDoc getDataHandler(final byte[] content, final String JavaDoc type)
563     {
564         return new DataHandler JavaDoc(new ByteDataSource(content, type));
565     }
566     
567     /**
568      *
569      */

570     private String JavaDoc getContentType(final String JavaDoc type)
571     {
572         return type + ";charset=" + UTF8_ENCODING;
573     }
574     
575     /**
576      * Method used for initializing the function; will be called before <code>execute</code> is called.
577      * <p><strong>Note</strong>! You must call <code>super.initialize()</code> first.</p>
578      *
579      * @throws WorkflowException if an error occurs during the initialization.
580      */

581     protected void initialize() throws WorkflowException
582     {
583         super.initialize();
584         this.illegalAddresses = (Collection JavaDoc) getParameter(EmailFunction.ILLEGAL_ADDRESSES_PARAMETER, new ArrayList JavaDoc());
585         this.silentMode = getArgument(SILENT_MODE_ARGUMENT, "false").equalsIgnoreCase("true");
586         this.attachments = (Collection JavaDoc) getParameter(ATTACHMENTS_PARAMETER, new ArrayList JavaDoc());
587     }
588 }
589
Popular Tags