KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > mail > transformation > SendMailTransformer


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.mail.transformation;
17
18 import java.io.IOException JavaDoc;
19 import java.io.InputStream JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Map JavaDoc;
24 import java.util.Properties JavaDoc;
25 import java.util.StringTokenizer JavaDoc;
26
27 import javax.activation.DataHandler JavaDoc;
28 import javax.activation.DataSource JavaDoc;
29 import javax.mail.Address JavaDoc;
30 import javax.mail.BodyPart JavaDoc;
31 import javax.mail.Message JavaDoc;
32 import javax.mail.Multipart JavaDoc;
33 import javax.mail.SendFailedException JavaDoc;
34 import javax.mail.Session JavaDoc;
35 import javax.mail.Transport 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.avalon.framework.configuration.Configuration;
42 import org.apache.avalon.framework.configuration.ConfigurationException;
43 import org.apache.avalon.framework.parameters.Parameters;
44 import org.apache.cocoon.ProcessingException;
45 import org.apache.cocoon.environment.SourceResolver;
46 import org.apache.cocoon.mail.datasource.SourceDataSource;
47 import org.apache.cocoon.transformation.AbstractSAXTransformer;
48 import org.apache.excalibur.source.Source;
49 import org.xml.sax.Attributes JavaDoc;
50 import org.xml.sax.SAXException JavaDoc;
51 import org.xml.sax.helpers.AttributesImpl JavaDoc;
52
53 /**
54  * The SendMailTransformer send mails with optional attachments using a SMTP
55  * server and delivers furthermore a status report of each sent mail.
56  *
57  * <p>
58  * The SendMailTransformer requires the Sun's JavaMail API implementation. Please
59  * download and copy the following files to the Cocoon lib directory:
60  * <ul>
61  * <li><code>mail.jar</code> from
62  * <a HREF="http://java.sun.com/products/javamail/">http://java.sun.com/products/javamail/</a>
63  * </li>
64  * <li><code>activation.jar</code> from
65  * <a HREF="http://java.sun.com/products/javabeans/glasgow/jaf.html">http://java.sun.com/products/javabeans/glasgow/jaf.html</a>
66  * </li>
67  * </p>
68  *
69  * <p>
70  * Use the following sitemap component declaration to define, configure and
71  * parameterize the transformer.
72  * in the <code>map:sitemap/map:components/map:transformers</code>:
73
74  * <pre>
75  * &lt;map:transformer name=&quot;sendmail&quot; SRC=&quot;org.apache.cocoon.mail.transformation.SendMailTransformer&quot;&gt;
76  * &lt;smtphost&gt;smtp.foo.com&lt;/smtphost&gt;
77  * &lt;from&gt;sender@localhost&lt;/from&gt;
78  * &lt;/map:transformer&gt;
79  * </pre>
80  *
81  * where
82  * <ul>
83  * <li>
84  * &lt;smtphost&gt; is the SMTP server host name, e.g. smtp.foo.com
85  * </li>
86  * <li>
87  * &lt;from&gt; is the sender e-mail address
88  * </li>
89  * </ul>
90  * </p>
91  *
92  * <p>
93  * Furthermore, these parameters can be defined in the sitemap pipeline section:
94  * <ul>
95  * <li>
96  * <b>smtphost</b>, <b>from</b> - If they are defined, this values overwrite
97  * the values from component section described above.
98  * </li>
99  * <li>
100  * <b>to</b> - email addresses of recipients
101  * e.g.: <code>&lt;map:parameter name="to" value="customer1@target.com,customer2@target.com"/&gt;</code>
102  * </li>
103  * <li>
104  * <b>subject</b> - a string, can also come from an input module
105  * e.g.; &lt;map:parameter name="subject" value="{request-param:subject}"/&gt;
106  * </li>
107  * <li>
108  * <b>body</b> - a string, can also come from an input module
109  * e.g.; &lt;map:parameter name="body" value="{request-param:body}"/&gt;
110  * </li>
111  * <li>
112  * <b>sendpartial</b> - a boolean, define how to send the mails. When mail is being send
113  * to more than one recipient and the parameter is set to false, then all email addresses
114  * will appear concatenated in the address field at the mail client of the recipient.
115  * The default is true.
116  * </li>
117  * </ul>
118  * </p>
119  *
120  * <p>
121  * More configurations can be made in a specific configuration file, which
122  * can be retrieved with a
123  * <a HREF="http://cocoon.apache.org/2.1/userdocs/generators/generators.html">generator</a> as
124  * the input document. The input document should have the following configuration entities:
125  * <ul>
126  * <li>
127  * <b>&lt;email:smtphost&gt;</b>, <b>&lt;email:from&gt;</b> and
128  * <b>&lt;email:subject&gt;</b> can be set to overwrite values from the
129  * sitemap
130  * </li>
131  * <li>
132  * <b>&lt;email:to&gt;</b> - each entry will be append to the list of
133  * email addresses
134  * </li>
135  * <li>
136  * <b>&lt;email:body&gt;</b> - Overwrites the value from the sitemap.
137  * If there is a <b>src</b> attribute, the transformer will try to retrieve
138  * the file and place it instead of a text-string as the mail body.
139  * </li>
140  * <li>
141  * <b>&lt;email:attachment&gt;</b> - each entry defines a attachment.
142  * The attribute <b>name</b> defines the name of the attachment. The <b>mime-type</b> attribute
143  * defines the content of the attachment.
144  * If there is a nested &lt;email:content&gt; - element, text can be included and the
145  * attachment will then be a plain text-file.
146  * Is there a <b>url</b> attribute, the transformer tries to retrieve the
147  * appropriate file and handle it as an attachment.
148  * To use a file as an attachment, retrieved over a protocol like http or
149  * cocoon, use the <b>src</b> attribute.
150  * </li>
151  * </ul>
152  * </p>
153  *
154  * <p>
155  * Input document sample:
156  * <pre>
157  * &lt;?xml version="1.0" encoding="UTF-8"?&gt;
158  * &lt;document xmlns:email="http://apache.org/cocoon/transformation/sendmail"&gt;
159  * &lt;email:sendmail&gt;
160  * &lt;email:smtphost&gt;hostname.company.com&lt;/email:smtphost&gt;
161  * &lt;email:from&gt;info@company.com&lt;/email:from&gt;
162  * &lt;email:to&gt;customer3@target.com&lt;/email:to&gt;
163  * &lt;email:to&gt;customer4@target.com&lt;/email:to&gt;
164  * &lt;email:to&gt;customer5@target.com&lt;/email:to&gt;
165  * &lt;email:to&gt;customer6@target.com&lt;/email:to&gt;
166  * &lt;email:subject&gt;subject-content&lt;/email:subject&gt;
167  * &lt;email:body SRC="cocoon:/softwareupdate.html?locale=en&amp;country=UK"/&gt;
168  * &lt;!-- &lt;email:body&gt;some Text&lt;/email:body&gt; --&gt;
169  * &lt;email:attachment name="hello.html" mime-type="text/html"&gt;
170  * &lt;email:content&gt;
171  * Dear Customer, please visit out new Product-Shop.
172  * &lt;/email:content&gt;
173  * &lt;/email:attachment&gt;
174  * &lt;email:attachment name="hello2.html" mime-type="text/html" SRC="cocoon:/src1"/&gt;
175  * &lt;email:attachment name="hello3.html" mime-type="text/html"
176  * url="C:\path\softwareupdate.html"/&gt;
177  * &lt;email:attachment name="hello.gif" mime-type="image/gif"
178  * url="c:\path\powered.gif"/&gt;
179  * &lt;/email:sendmail&gt;
180  * &lt;/document&gt;
181  * </pre>
182  * </p>
183  *
184  * <p>
185  * After the transformation a report will be generated, where the state for each sent mail can be seen.
186  * In case of an exception, the exception-message and a stacktrace will be reported.
187  * </p>
188  *
189  * <p>
190  * <b style="color: red;">FIXME: Known Issues:</b>
191  * <ul>
192  * <li>Refactor to use MailSender component</li>
193  * <li>No support for <a HREF="http://www.ietf.org/rfc/rfc2554.txt">RFC 2554:
194  * SMTP Service Extension for Authentication</a></li>
195  * <li>No support for different mail servers, first one will always be used</li>
196  * </ul>
197  * </p>
198  *
199  * @author <a HREF="mailto:pklassen@s-und-n.de">Peter Klassen</a>
200  * @version CVS $Id: SendMailTransformer.java 263833 2005-08-28 06:13:41Z antonio $
201  */

202 public class SendMailTransformer extends AbstractSAXTransformer {
203
204     /*
205      * constants, related to elements in configuration-file
206      */

207     public static final String JavaDoc NAMESPACE = "http://apache.org/cocoon/transformation/sendmail";
208     public static final String JavaDoc ELEMENT_SENDMAIL = "sendmail";
209     public static final String JavaDoc ELEMENT_SMTPHOST = "smtphost";
210     public static final String JavaDoc ELEMENT_SMTPPORT = "smtpport";
211     public static final String JavaDoc ELEMENT_MAILFROM = "from";
212     public static final String JavaDoc ELEMENT_MAILTO = "to";
213     public static final String JavaDoc ELEMENT_REPLYTO = "reply-to";
214     public static final String JavaDoc ELEMENT_MAILSUBJECT = "subject";
215     public static final String JavaDoc ELEMENT_MAILBODY = "body";
216     public static final String JavaDoc ELEMENT_ATTACHMENT = "attachment";
217     public static final String JavaDoc ELEMENT_ATTACHMENT_CONTENT = "content";
218     public static final String JavaDoc ELEMENT_EMAIL_PREFIX = "email";
219     public static final String JavaDoc ELEMENT_ERROR = "error";
220     public static final String JavaDoc ELEMENT_SUCCESS = "success";
221     public static final String JavaDoc ELEMENT_FAILURE = "failure";
222     public static final String JavaDoc ELEMENT_RESULT = "result";
223
224     public static final String JavaDoc DEFAULT_BODY_MIMETYPE = "text/html";
225
226     /*
227      * mode-constants
228      */

229     protected static final int MODE_NONE = 0;
230     protected static final int MODE_SMTPHOST = 1;
231     protected static final int MODE_FROM = 2;
232     protected static final int MODE_TO = 3;
233     protected static final int MODE_SUBJECT = 4;
234     protected static final int MODE_BODY = 5;
235     protected static final int MODE_ATTACHMENT = 6;
236     protected static final int MODE_ATTACHMENT_CONTENT = 7;
237     protected static final int MODE_REPLY_TO = 8;
238     protected static final int MODE_SMTPPORT = 9;
239
240     /*
241      * constants, related to parameter from request
242      */

243     public final static String JavaDoc PARAM_SMTPHOST = "smtphost";
244     public final static String JavaDoc PARAM_SMTPPORT = "smtpport";
245     public final static String JavaDoc PARAM_FROM = "from";
246     public final static String JavaDoc PARAM_TO = "to";
247     public final static String JavaDoc PARAM_REPLY_TO = "reply-to";
248     public final static String JavaDoc PARAM_SUBJECT = "subject";
249     public final static String JavaDoc PARAM_BODY = "body";
250     public final static String JavaDoc PARAM_SENDPARTIAL = "sendpartial";
251     protected int mode;
252
253     /*
254      * communication parameters, which will be used to send mails
255      */

256     protected List JavaDoc toAddresses;
257     protected List JavaDoc replyToAddresses;
258     protected List JavaDoc defaultToAddresses;
259     protected List JavaDoc defaultReplyToAddresses;
260     protected List JavaDoc attachments;
261     protected String JavaDoc subject;
262     protected String JavaDoc body;
263     protected String JavaDoc bodyURI;
264     protected String JavaDoc bodyMimeType;
265     protected String JavaDoc mailHost;
266     protected int mailPort;
267     protected String JavaDoc fromAddress;
268     protected AttachmentDescriptor attachmentDescriptor;
269     protected int port;
270     protected String JavaDoc contextPath;
271     protected boolean sendPartial;
272     protected Message JavaDoc smtpMessage;
273
274     protected String JavaDoc defaultSmtpHost;
275     protected int defaultSmtpPort;
276     protected String JavaDoc defaultFromAddress;
277
278     protected List JavaDoc usedSources = new ArrayList JavaDoc();
279
280     /**
281      * create a new Transformer
282      */

283     public SendMailTransformer() {
284         this.defaultNamespaceURI = NAMESPACE;
285     }
286
287     /* (non-Javadoc)
288      * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
289      */

290     public void configure(Configuration configuration)
291     throws ConfigurationException {
292         super.configure(configuration);
293         this.defaultSmtpHost = configuration.getChild("smtphost").getValue("");
294         this.defaultSmtpPort = configuration.getChild("smtpport").getValueAsInteger(25);
295         this.defaultFromAddress = configuration.getChild("from").getValue("");
296     }
297
298     /**
299      * invoked every time when the transformer is triggered by the pipeline
300      */

301     public void setup(SourceResolver resolver, Map JavaDoc objectModel, String JavaDoc src,
302                       Parameters par)
303    throws ProcessingException, SAXException JavaDoc, IOException JavaDoc {
304         super.setup(resolver, objectModel, src, par);
305
306         this.mailHost = par.getParameter(PARAM_SMTPHOST, this.defaultSmtpHost);
307         this.mailPort = par.getParameterAsInteger(PARAM_SMTPPORT, this.defaultSmtpPort);
308         this.fromAddress = par.getParameter(PARAM_FROM, this.defaultFromAddress);
309         this.port = this.request.getServerPort();
310         this.contextPath = this.request.getContextPath();
311         this.sendPartial = par.getParameterAsBoolean(PARAM_SENDPARTIAL, true);
312
313         if (getLogger().isDebugEnabled()) {
314             getLogger().debug("Using host " + mailHost + " on port " + mailPort + ", from address " + fromAddress);
315         }
316
317         this.attachments = new ArrayList JavaDoc();
318         this.defaultToAddresses = new ArrayList JavaDoc();
319         appendToAddress(this.defaultToAddresses, par.getParameter(PARAM_TO, ""));
320         this.defaultReplyToAddresses = new ArrayList JavaDoc();
321         appendToAddress(this.defaultReplyToAddresses, par.getParameter(PARAM_REPLY_TO, ""));
322
323         this.subject = par.getParameter(PARAM_SUBJECT, null);
324         this.body = par.getParameter(PARAM_BODY, null);
325     }
326
327     /* (non-Javadoc)
328      * @see org.apache.cocoon.transformation.AbstractSAXTransformer#startTransformingElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
329      */

330     public void startTransformingElement(String JavaDoc uri, String JavaDoc name, String JavaDoc raw,
331                                          Attributes JavaDoc attr)
332     throws SAXException JavaDoc {
333         if (name.equals(ELEMENT_SENDMAIL)) {
334             // Clean from possible previous usage
335
this.toAddresses = new ArrayList JavaDoc(this.defaultToAddresses);
336             this.replyToAddresses = new ArrayList JavaDoc(this.defaultReplyToAddresses);
337             this.attachments.clear();
338         } else if (name.equals(ELEMENT_SMTPHOST)) {
339             startTextRecording();
340             this.mode = MODE_SMTPHOST;
341         } else if (name.equals(ELEMENT_SMTPPORT)) {
342             this.startTextRecording();
343             this.mode = MODE_SMTPPORT;
344         } else if (name.equals(ELEMENT_MAILFROM)) {
345             startTextRecording();
346             this.mode = MODE_FROM;
347         } else if (name.equals(ELEMENT_MAILTO)) {
348             startTextRecording();
349             this.mode = MODE_TO;
350         } else if (name.equals(ELEMENT_REPLYTO)) {
351             startTextRecording();
352             this.mode = MODE_REPLY_TO;
353         } else if (name.equals(ELEMENT_MAILSUBJECT)) {
354             startTextRecording();
355             this.mode = MODE_SUBJECT;
356         } else if (name.equals(ELEMENT_MAILBODY)) {
357             String JavaDoc strBody = attr.getValue("src");
358             if (strBody != null) {
359                 this.bodyURI = strBody;
360             }
361
362             String JavaDoc mType = attr.getValue("mime-type");
363             if (mType != null) {
364                 this.bodyMimeType = mType;
365             } else {
366                 this.bodyMimeType = DEFAULT_BODY_MIMETYPE;
367             }
368
369             startTextRecording();
370             this.mode = MODE_BODY;
371         } else if (name.equals(ELEMENT_ATTACHMENT)) {
372             this.attachmentDescriptor = new AttachmentDescriptor(attr.getValue("name"),
373                                                                  attr.getValue("mime-type"),
374                                                                  attr.getValue("src"),
375                                                                  attr.getValue("url"));
376             this.mode = MODE_ATTACHMENT;
377         } else if (name.equals(ELEMENT_ATTACHMENT_CONTENT)) {
378             startSerializedXMLRecording(new Properties JavaDoc());
379             this.mode = MODE_ATTACHMENT_CONTENT;
380         } else {
381             throw new SAXException JavaDoc("Unknown element <" + name + ">");
382         }
383     }
384
385     /* (non-Javadoc)
386      * @see org.apache.cocoon.transformation.AbstractSAXTransformer#endTransformingElement(java.lang.String, java.lang.String, java.lang.String)
387      */

388     public void endTransformingElement(String JavaDoc uri, String JavaDoc name, String JavaDoc raw)
389                                 throws SAXException JavaDoc, ProcessingException {
390         if (name.equals(ELEMENT_SENDMAIL)) {
391             if (getLogger().isInfoEnabled()) {
392                 getLogger().info("Mail Subject: " + this.subject + "\n" +
393                                  "Body: " + this.body);
394             }
395             sendMail();
396         } else if (name.equals(ELEMENT_SMTPHOST) ) {
397             this.mailHost = endTextRecording();
398             this.mode = MODE_NONE;
399         } else if (name.equals(ELEMENT_SMTPPORT) ) {
400             this.mailPort = Integer.parseInt(this.endTextRecording());
401             this.mode = MODE_NONE;
402         } else if (name.equals(ELEMENT_MAILFROM)) {
403             this.fromAddress = endTextRecording();
404             this.mode = MODE_NONE;
405         } else if (name.equals(ELEMENT_MAILTO)) {
406             this.toAddresses.add(endTextRecording());
407             this.mode = MODE_NONE;
408         } else if (name.equals(ELEMENT_REPLYTO)) {
409             this.replyToAddresses.add(endTextRecording());
410             this.mode = MODE_NONE;
411         } else if (name.equals(ELEMENT_MAILSUBJECT)) {
412             String JavaDoc strSubject = endTextRecording();
413             if (strSubject != null) {
414                 this.subject = strSubject;
415             } else {
416                 getLogger().debug("Mail: No Subject");
417             }
418             this.mode = MODE_NONE;
419         } else if (name.equals(ELEMENT_ATTACHMENT)) {
420             this.attachments.add(this.attachmentDescriptor.copy());
421             this.attachmentDescriptor = null;
422             this.mode = MODE_NONE;
423         } else if (name.equals(ELEMENT_ATTACHMENT_CONTENT)) {
424             this.attachmentDescriptor.setContent(endSerializedXMLRecording());
425             this.mode = MODE_NONE;
426         } else if (name.equals(ELEMENT_MAILBODY)) {
427             String JavaDoc strB = null;
428             try {
429                 strB = endTextRecording();
430             } catch (Exception JavaDoc e) {
431                 if (getLogger().isDebugEnabled()) {
432                     getLogger().debug("Mail: No Body as String in config-file available");
433                 }
434             }
435             if (strB != null) {
436                 this.body = strB;
437             }
438             this.mode = MODE_NONE;
439         } else {
440             throw new SAXException JavaDoc("Unknown element <" + name + ">");
441         }
442     }
443
444     private static void appendToAddress(List JavaDoc addresses, String JavaDoc s) {
445         StringTokenizer JavaDoc t = new StringTokenizer JavaDoc(s.trim(), ";");
446         while (t.hasMoreElements()) {
447             addresses.add(t.nextToken());
448         }
449     }
450
451     /**
452      *
453      */

454     private void sendMail() {
455         try {
456             Properties JavaDoc props = new Properties JavaDoc();
457             props.put("mail.smtp.host", this.mailHost);
458             props.put("mail.smtp.port", String.valueOf(this.mailPort));
459
460             if (this.subject == null) {
461                 this.ignoreHooksCount++;
462                 super.sendStartElementEventNS(ELEMENT_ERROR);
463                 super.sendTextEvent("Subject not available - sending mail aborted");
464                 super.sendEndElementEventNS(ELEMENT_ERROR);
465                 this.ignoreHooksCount--;
466                 return;
467             }
468
469             if (this.body == null && this.bodyURI == null) {
470                 this.ignoreHooksCount++;
471                 super.sendStartElementEventNS(ELEMENT_ERROR);
472                 super.sendTextEvent("Mailbody not available - sending mail aborted");
473                 super.sendEndElementEventNS(ELEMENT_ERROR);
474                 this.ignoreHooksCount--;
475                 return;
476             }
477
478             Session JavaDoc session = Session.getDefaultInstance(props, null);
479             Transport JavaDoc trans = session.getTransport("smtp");
480             trans.connect();
481
482             this.smtpMessage = setUpMessage(session);
483
484             this.ignoreHooksCount++;
485             super.sendStartElementEventNS(ELEMENT_RESULT);
486
487             if (this.sendPartial) {
488                 for (int i = 0; i < this.toAddresses.size(); i++) {
489                     List JavaDoc v = new ArrayList JavaDoc(1);
490                     v.add(this.toAddresses.get(i));
491                     sendMail(v, trans);
492                 }
493             } else {
494                 sendMail(this.toAddresses, trans);
495             }
496
497             trans.close();
498             super.sendEndElementEventNS(ELEMENT_RESULT);
499             this.ignoreHooksCount--;
500         } catch (Exception JavaDoc e) {
501             getLogger().error("Exception sending mail", e);
502             sendExceptionElement(e);
503         }
504     }
505
506     /**
507      * @see <a HREF="http://java.sun.com/products/javamail/1.3/docs/javadocs/com/sun/mail/smtp/package-summary.html">Sun Javamail Javadoc</a>
508      * @throws Exception
509      */

510     private void sendMail(List JavaDoc newAddresses, Transport JavaDoc trans)
511                    throws Exception JavaDoc {
512         AddressHandler[] iA = new AddressHandler[newAddresses.size()];
513
514         for (int i = 0; i < newAddresses.size(); i++) {
515             InternetAddress JavaDoc inA = new InternetAddress JavaDoc((String JavaDoc) newAddresses.get(i));
516             iA[i] = new AddressHandler(inA);
517         }
518
519         try {
520             InternetAddress JavaDoc[] iaArr = SendMailTransformer.getAddresses(iA);
521             this.smtpMessage.setRecipients(Message.RecipientType.TO, iaArr);
522             trans.sendMessage(this.smtpMessage, iaArr);
523         } catch (SendFailedException JavaDoc e) {
524             getLogger().error("Exception during sending of mail", e);
525
526             Address JavaDoc[] adr = e.getInvalidAddresses();
527             for (int isfEx = 0; isfEx < iA.length; isfEx++) {
528                 String JavaDoc tmpAddress = iA[isfEx].getAddress().getAddress();
529                 for (int sei = 0; sei < adr.length; sei++) {
530                     if (((InternetAddress JavaDoc) adr[sei]).getAddress()
531                              .equalsIgnoreCase(tmpAddress)) {
532                         iA[isfEx].setSendMailResult("Invalid address");
533                     }
534                 }
535             }
536
537             Address JavaDoc[] ad = e.getValidUnsentAddresses();
538             for (int isfEx = 0; isfEx < iA.length; isfEx++) {
539                 String JavaDoc tmpAddress = iA[isfEx].getAddress().getAddress();
540                 for (int sei = 0; sei < ad.length; sei++) {
541                     if (((InternetAddress JavaDoc) ad[sei]).getAddress()
542                              .equalsIgnoreCase(tmpAddress)) {
543                         iA[isfEx].setSendMailResult("Recipient not found");
544                     }
545                 }
546             }
547         } catch (Exception JavaDoc e) {
548             getLogger().error("Exception sending mail", e);
549             sendExceptionElement(e);
550             return;
551         }
552
553         generateSAXReportStatements(iA);
554     }
555
556     private Message JavaDoc setUpMessage(Session JavaDoc session) throws Exception JavaDoc {
557         Message JavaDoc sm = new MimeMessage JavaDoc(session);
558
559         //sm.setAllow8bitMIME(true);
560
Address JavaDoc[] replyTo = new Address JavaDoc[this.replyToAddresses.size()];
561         for (int i = 0 ; i < this.replyToAddresses.size(); i++) {
562             replyTo[i] = new InternetAddress JavaDoc((String JavaDoc) this.replyToAddresses.get(i));
563         }
564         sm.setReplyTo(replyTo);
565         sm.setFrom(new InternetAddress JavaDoc(this.fromAddress));
566         sm.setSubject(this.subject);
567
568         // process mail-body
569
BodyPart JavaDoc messageBodyPart = new MimeBodyPart JavaDoc();
570
571         // decide, if to take content from source or plain text
572
// from variable to build mailbody
573
if (this.bodyURI != null) {
574             Source JavaDoc inSrc = resolver.resolveURI(this.bodyURI);
575             this.usedSources.add(inSrc);
576             InputStream JavaDoc inStr = inSrc.getInputStream();
577             byte[] byteArr = new byte[inStr.available()];
578             inStr.read(byteArr);
579
580             String JavaDoc mailBody = new String JavaDoc(byteArr);
581             messageBodyPart.setContent(mailBody, this.bodyMimeType);
582         } else {
583             messageBodyPart.setContent(this.body, this.bodyMimeType);
584         }
585
586         Multipart JavaDoc multipart = new MimeMultipart JavaDoc();
587         multipart.addBodyPart(messageBodyPart);
588
589         // process attachments
590
Iterator JavaDoc iterAtt = this.attachments.iterator();
591
592         while (iterAtt.hasNext()) {
593             AttachmentDescriptor aD = (AttachmentDescriptor) iterAtt.next();
594             messageBodyPart = new MimeBodyPart JavaDoc();
595
596             if (!aD.isTextContent()) {
597                 Source JavaDoc inputSource = null;
598                 DataSource JavaDoc dataSource = null;
599
600                 inputSource = resolver.resolveURI(aD.isURLSource() ? aD.strAttrSrc : aD.strAttrFile);
601                 this.usedSources.add(inputSource);
602
603                 dataSource = new SourceDataSource(inputSource, aD.strAttrMimeType, aD.strAttrName);
604
605                 messageBodyPart.setDataHandler(new DataHandler JavaDoc(dataSource));
606             } else {
607                 messageBodyPart.setContent(aD.strContent, aD.strAttrMimeType);
608             }
609
610             messageBodyPart.setFileName(aD.strAttrName);
611             multipart.addBodyPart(messageBodyPart);
612         }
613
614         sm.setContent(multipart);
615
616         //sm.setReturnOption(SMTPMessage.RETURN_FULL);
617
sm.saveChanges();
618
619         return sm;
620     }
621
622     private void generateSAXReportStatements(AddressHandler[] addressArr)
623                                       throws SAXException JavaDoc {
624         AttributesImpl JavaDoc impl = new AttributesImpl JavaDoc();
625
626         for (int i = 0; i < addressArr.length; i++) {
627             String JavaDoc tmpAddress = addressArr[i].getAddress().getAddress();
628
629             if (addressArr[i].getSendMailResult() == null) {
630                 impl.addAttribute("", "to", "to",
631                                   "CDATA", tmpAddress);
632                 super.sendStartElementEventNS(ELEMENT_SUCCESS, impl);
633                 super.sendTextEvent("Mail sent");
634                 super.sendEndElementEventNS(ELEMENT_SUCCESS);
635             } else {
636                 impl.addAttribute("", "to", "to",
637                                   "CDATA", tmpAddress);
638                 super.sendStartElementEventNS(ELEMENT_FAILURE, impl);
639                 super.sendTextEvent(addressArr[i].getSendMailResult());
640                 super.sendEndElementEventNS(ELEMENT_FAILURE);
641             }
642         }
643     }
644
645     private void sendExceptionElement(Exception JavaDoc ex) {
646         try {
647             this.ignoreHooksCount++;
648             super.sendStartElementEventNS("exception");
649             super.sendStartElementEventNS("message");
650             super.sendTextEvent(ex.getMessage());
651             super.sendEndElementEventNS("message");
652
653             /* only with jdk 1.4
654             super.sendStartElementEvent("email:stacktrace");
655
656             for (int i = 0; i < ex.getStackTrace().length; i++) {
657                 String s = ((StackTraceElement) ex.getStackTrace()[i]).toString();
658                 super.sendTextEvent(s + "\n");
659             }
660
661             super.sendEndElementEvent("email:stacktrace");*/

662
663             super.sendEndElementEventNS("exception");
664             this.ignoreHooksCount--;
665         } catch (SAXException JavaDoc e) {
666             getLogger().error("Error while sending a SAX-Event", e);
667         }
668     }
669
670     public static InternetAddress JavaDoc[] getAddresses(AddressHandler[] handlerArr) {
671         InternetAddress JavaDoc[] iaArr = new InternetAddress JavaDoc[handlerArr.length];
672
673         for (int i = 0; i < handlerArr.length; i++) {
674             iaArr[i] = handlerArr[i].getAddress();
675         }
676
677         return iaArr;
678     }
679
680     /**
681      * @see org.apache.avalon.excalibur.pool.Recyclable#recycle()
682      */

683     public void recycle() {
684         this.toAddresses = null;
685         this.defaultToAddresses = null;
686         this.attachments = null;
687         this.subject = null;
688         this.body = null;
689         this.bodyURI = null;
690         this.mailHost = null;
691         this.mailPort = 0;
692         this.fromAddress = null;
693         this.attachmentDescriptor = null;
694         this.port = 0;
695         this.contextPath = null;
696         this.sendPartial = true;
697         this.smtpMessage = null;
698         final Iterator JavaDoc i = this.usedSources.iterator();
699         while ( i.hasNext() ) {
700             final Source JavaDoc source = (Source JavaDoc)i.next();
701             this.resolver.release(source);
702         }
703         this.usedSources.clear();
704         super.recycle();
705     }
706
707     static class AttachmentDescriptor {
708         String JavaDoc strAttrName;
709         String JavaDoc strAttrMimeType;
710         String JavaDoc strAttrSrc;
711         String JavaDoc strAttrFile;
712         String JavaDoc strContent;
713
714         protected AttachmentDescriptor(String JavaDoc newAttrName,
715                                        String JavaDoc newAttrMimeType,
716                                        String JavaDoc newAttrSrc, String JavaDoc newAttrFile) {
717             this.strAttrName = newAttrName;
718             this.strAttrMimeType = newAttrMimeType;
719             this.strAttrSrc = newAttrSrc;
720             this.strAttrFile = newAttrFile;
721         }
722
723         protected void setContent(String JavaDoc newContent) {
724             this.strContent = newContent;
725         }
726
727         protected AttachmentDescriptor copy() {
728             AttachmentDescriptor aD = new AttachmentDescriptor(this.strAttrName,
729                                                                this.strAttrMimeType,
730                                                                this.strAttrSrc,
731                                                                this.strAttrFile);
732             aD.setContent(this.strContent);
733
734             return aD;
735         }
736
737         protected boolean isURLSource() {
738             return (this.strAttrSrc != null);
739         }
740
741         protected boolean isFileSource() {
742             return (this.strAttrFile != null);
743         }
744
745         protected boolean isTextContent() {
746             return (this.strContent != null);
747         }
748     }
749
750     static class AddressHandler {
751         private InternetAddress JavaDoc address;
752         private String JavaDoc sendMailResult;
753
754         protected AddressHandler(InternetAddress JavaDoc newAddress) {
755             this.address = newAddress;
756         }
757
758         protected void setSendMailResult(String JavaDoc newSendMailResult) {
759             this.sendMailResult = newSendMailResult;
760         }
761
762         /**
763          * @return mail-address
764          */

765         public InternetAddress JavaDoc getAddress() {
766             return address;
767         }
768
769         /**
770          * @return sendMailResult as String
771          */

772         public String JavaDoc getSendMailResult() {
773             return sendMailResult;
774         }
775     }
776 }
777
Popular Tags