KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > taglibs > mailer > SendTag


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
17 package org.apache.taglibs.mailer;
18
19 import java.util.ArrayList JavaDoc;
20 import java.util.Date JavaDoc;
21 import java.util.ListIterator JavaDoc;
22 import javax.mail.Message JavaDoc;
23 import javax.mail.MessagingException JavaDoc;
24 import javax.mail.Transport JavaDoc;
25 import javax.mail.internet.AddressException JavaDoc;
26 import javax.mail.internet.InternetAddress JavaDoc;
27 import javax.mail.internet.MimeBodyPart JavaDoc;
28 import javax.mail.internet.MimeMessage JavaDoc;
29 import javax.mail.internet.MimeMultipart JavaDoc;
30 import javax.servlet.jsp.JspException JavaDoc;
31 import javax.servlet.jsp.tagext.BodyTagSupport JavaDoc;
32
33 /**
34  * SendTag - JSP tag <b>Send</b> is used to send the created email.
35  *
36  * <tag>
37  * <name>send</name>
38  * <tagclass>org.apache.taglibs.mailer.SendTag</tagclass>
39  * <bodycontent>JSP</bodycontent>
40  * <info>Send the email</info>
41  * </tag>
42  *
43  * @author Rich Catlett
44  *
45  * @version 1.0
46  *
47  */

48
49 public class SendTag extends BodyTagSupport JavaDoc {
50
51     ArrayList JavaDoc error = null; // error messages made accessable to user
52

53     /**
54      * implementation of method from the Tag interface that tells the JSP what
55      * to do upon encountering the start tag for this tag set
56      *
57      * @return integer value telling the JSP engine to evaluate the rest of the
58      * jsp page
59      *
60      * @throws JspException thrown when error occurs in processing the body of
61      * this method
62      *
63      */

64     public int doStartTag() throws JspException JavaDoc {
65
66         error = null;
67     int i = 0; // counter for list of extra header name/value pairs
68
MimeMessage JavaDoc message; // message object that contains this message
69
// Added by Jayson Falkner - 5/8/2001 --------------------------
70
MimeMultipart JavaDoc multipart; // multipart for this message
71
// End of added.
72
ListIterator JavaDoc iterate; // iterator for the list of attachments
73
String JavaDoc to = null; // the to address for this e-mail message
74
String JavaDoc cc = null; // the cc address for this e-mail message
75
String JavaDoc bcc = null; // the bcc address for this e-mail message
76

77     // parent tag must be a MailTag, gives access to methods in parent
78
MailTag myparent = (MailTag)findAncestorWithClass(this, MailTag.class);
79
80     if (myparent == null)
81         throw new JspException JavaDoc("send tag not nested within mail tag");
82
83     // get message from parent tag
84
message = myparent.getMessage();
85
86     // get the list of name and values for the headers to be added
87
ArrayList JavaDoc name = myparent.getHeaderName();
88     ArrayList JavaDoc value = myparent.getHeaderValue();
89
90     try {
91         // set extra headers if any
92
if (name.size() > 0)
93         for (i = 0; i < name.size(); i++)
94             message.addHeader((String JavaDoc)name.get(i),
95                            (String JavaDoc)value.get(i));
96     } catch (MessagingException JavaDoc me) {
97         throw new JspException JavaDoc("Header " + name.get(i).toString()
98               + " was not able to be set");
99     }
100
101     // get the to address(es)
102
if ((to = myparent.getTo()) != null) {
103
104         try {
105         // set the to address for this message
106
// catch any errors in the format of the addresses
107
message.setRecipients(Message.RecipientType.TO,
108                       InternetAddress.parse(to));
109         } catch (AddressException JavaDoc ae) {
110         // get the address that the error occured with
111
String JavaDoc ref = ae.getRef();
112
113         // check for more than one address
114
if (ref.indexOf(',') != -1) {
115             // position of the start of the error inducing address
116
int pos = ref.substring(0, ae.getPos()).indexOf(',') + 1;
117             // extract the error inducing address
118
ref = ref.substring(pos, ref.indexOf(','));
119         }
120
121         // check for existence of error if it does not exist create it
122
if (error == null)
123             error = new ArrayList JavaDoc();
124
125             String JavaDoc errorinput = "The to address " + ref + " is not in"
126                   + " the proper format.";
127
128         error.add(errorinput);
129         } catch (MessagingException JavaDoc me) {
130         // check for existence of error if it does not exist create it
131
if (error == null)
132             error = new ArrayList JavaDoc();
133
134         // exception occurs when any of the addresses cannot be
135
// properly set in the message
136
String JavaDoc errorinput = "Messaging Exception: To address/es could"
137                   + " not be set in the message." + me.getMessage();
138
139         error.add(errorinput);
140         }
141     } else {
142         // if no to address has been given through an error
143
String JavaDoc errorinput = "A to address must be supplied.";
144
145         // check for existence of error if it does not exist create it
146
if (error == null)
147         error = new ArrayList JavaDoc();
148
149         error.add(errorinput);
150     }
151
152     // set the Reply-to address if it hax been supplied
153
if (myparent.getReplyTo() != null) {
154
155         try {
156         message.setReplyTo(InternetAddress.parse(myparent.getReplyTo()));
157         } catch (AddressException JavaDoc ae) {
158         // check for existence of error if it does not exist create it
159
if (error == null)
160             error = new ArrayList JavaDoc();
161
162         // exception occurs when the cc address cannot be parsed
163
String JavaDoc errorinput = "The Reply-To address was incorrectly set";
164
165         error.add(errorinput);
166         } catch (MessagingException JavaDoc me) {
167         // check for existence of error if it does not exist create it
168
if (error == null)
169             error = new ArrayList JavaDoc();
170
171         // exception occurs when any of the addresses cannot be
172
// properly set in the message
173
String JavaDoc errorinput = "Messaging Exception: Reply-To address/es"
174                 + " could not be set in the message." + me.getMessage();
175
176         error.add(errorinput);
177         }
178     }
179
180     try {
181
182         // get from address from the parent tag
183
String JavaDoc from = myparent.getFrom();
184
185         // set from address for this message
186
// check for user entered from address
187
if ((from == null) || (from.length() < 2)) {
188
189         // check to see if from is set at the level of the Session
190
if (myparent.getSessionObj().getProperty("mail.from") != null)
191
192                 message.setFrom(new InternetAddress JavaDoc(
193                    myparent.getSessionObj().getProperty("mail.from")));
194         }
195         else
196         message.setFrom(new InternetAddress JavaDoc(from));
197
198     } catch (MessagingException JavaDoc me) {
199         // check for existence of error if it does not exist create it
200
if (error == null)
201         error = new ArrayList JavaDoc();
202
203         // add exception to the list of errors in the e-mail
204
String JavaDoc errorinput = "The from address was not set or is not in"
205             + " the proper format for an email address.";
206
207         error.add(errorinput);
208     }
209
210     // check for and set cc addresses
211
if ((cc = myparent.getCc()) != null) {
212
213         try {
214                 message.setRecipients(Message.RecipientType.CC,
215                        InternetAddress.parse(cc));
216         } catch (AddressException JavaDoc ae) {
217         // get the address that the error occured with
218
String JavaDoc ref = ae.getRef();
219
220         // check for more than one address
221
if (ref.indexOf(',') != -1) {
222             // position of the start of the error inducing address
223
int pos = ref.substring(0, ae.getPos()).indexOf(',') + 1;
224             // extract the error inducing address
225
ref = ref.substring(pos, ref.indexOf(','));
226         }
227
228         // check for existence of error if it does not exist create it
229
if (error == null)
230             error = new ArrayList JavaDoc();
231
232         // exception occurs when the to address cannot be parsed
233
String JavaDoc errorinput = "The cc address " + ref + " is not in"
234                   + " the proper format.";
235
236         error.add(errorinput);
237         } catch (MessagingException JavaDoc me) {
238         // check for existence of error if it does not exist create it
239
if (error == null)
240             error = new ArrayList JavaDoc();
241
242         // exception occurs when any of the addresses cannot be
243
// properly set in the message
244
String JavaDoc errorinput = "Messaging Exception: Some cc address/es"
245                             + " could not be set in the message."
246                             + me.getMessage();
247
248         error.add(errorinput);
249         }
250     }
251
252     // check for and set bcc addresses
253
if ((bcc = myparent.getBcc()) != null) {
254
255         try {
256                 message.setRecipients(Message.RecipientType.BCC,
257                       InternetAddress.parse(bcc));
258         } catch (AddressException JavaDoc ae) {
259         // get the address that the error occured with
260
String JavaDoc ref = ae.getRef();
261
262         // check for more than one address
263
if (ref.indexOf(',') != -1) {
264             // position of the start of the error inducing address
265
int pos = ref.substring(0, ae.getPos()).indexOf(',') + 1;
266             // extract the error inducing address
267
ref = ref.substring(pos, ref.indexOf(','));
268         }
269
270         // check for existence of error if it does not exist create it
271
if (error == null)
272             error = new ArrayList JavaDoc();
273
274         // exception occurs when the to address cannot be parsed
275
String JavaDoc errorinput = "The bcc address " + ref + " is not in"
276                   + " the proper format.";
277
278         error.add(errorinput);
279         } catch (MessagingException JavaDoc me) {
280         // check for existence of error if it does not exist create it
281
if (error == null)
282             error = new ArrayList JavaDoc();
283
284         // exception occurs when any of the addresses cannot be
285
// properly set in the message
286
String JavaDoc errorinput = "Messaging Exception: Some bcc address/es"
287                             + " could not be set in the message."
288                             + me.getMessage();
289
290         error.add(errorinput);
291         }
292     }
293
294     try {
295         // set the subject in the message
296
message.setSubject(myparent.getSubject());
297
298         // add the sent date time to the message
299
message.setSentDate(new Date JavaDoc());
300     } catch (MessagingException JavaDoc me) {
301         // error occured while adding one of the above to the message
302
}
303
304     // check if there are attachments
305
if (myparent.getAttachments()) {
306         // create a multipart object and set the message as the first
307
// part then add the attachments
308
multipart = new MimeMultipart JavaDoc();
309
310         try {
311
312         // create a mimebodypart for the body of the e-mail message
313
MimeBodyPart JavaDoc mbp = new MimeBodyPart JavaDoc();
314
315         // set the content in the bodypart
316
mbp.setContent(myparent.getBody(), getContentType(myparent));
317
318         // add the message as the first bodypart in the multipart object
319
multipart.addBodyPart(mbp);
320
321         // get the list of attachments
322
iterate = myparent.getBodyParts().listIterator();
323
324         // loop through the list of attachments and add them to the
325
// multipart object
326
while (iterate.hasNext()) {
327             multipart.addBodyPart((MimeBodyPart JavaDoc) iterate.next());
328         }
329
330         // add the multipart object with the attachments to the message
331
message.setContent(multipart);
332
333         } catch (MessagingException JavaDoc me) {
334         // error occured while adding the message to the multipart
335
// content
336
throw new JspException JavaDoc("An error occured while trying to add" +
337                        "the attachments to the e-mail, please"
338                        +" to send the e-mail again.");
339         }
340     } else {
341         try {
342         // set the message with a mimetype according to type set by user
343
message.setContent(myparent.getBody(), getContentType(myparent));
344         } catch (MessagingException JavaDoc me) {
345         // this error is not very likely to occur
346
throw new JspException JavaDoc("The message could not be set in " +
347                    "the e-mail, please back up and try again.");
348         }
349     }
350     // check if errors have occured in creating the message
351
if (error != null)
352         // taglibs 1.1
353
return EVAL_BODY_TAG;
354         // taglibs 1.2
355
//return EVAL_BODY_BUFFERED;
356
else {
357         // create the thread to mail the messge
358
Mail mail = new Mail(message, pageContext.getServletContext(), to);
359
360         mail.start(); // send the mail
361

362         return SKIP_BODY;
363     }
364     }
365
366     /**
367      * implementation of the method from the tag interface that tells the JSP
368      * page what to do after the body of this tag
369      *
370      * @throws JspException thrown when an error occurs while processing the
371      * body of this method
372      *
373      * @return - int telling the tag handler whether or not to evaluate the
374      * rest of the JSP
375      *
376      */

377     public int doEndTag() throws JspException JavaDoc {
378
379     // an error has occured write error page out
380
if (error != null) {
381         // get error page from body
382
try {
383             if (bodyContent != null)
384             bodyContent.writeOut(bodyContent.getEnclosingWriter());
385         } catch(java.io.IOException JavaDoc e) {
386              throw new JspException JavaDoc("IO Error: " + e.getMessage());
387         }
388         error = null; // reset error
389
}
390     return EVAL_PAGE;
391     }
392
393     /**
394      * get the error message from the final caught JspException
395      *
396      * @return - Error message telling where problem occured
397      *
398      */

399     public ArrayList JavaDoc getError() {
400         return error;
401     }
402
403     /**
404      * get the content type, possibly including character set
405      *
406      * @return - complete encoded content type
407      */

408     public String JavaDoc getContentType(MailTag parent) {
409         String JavaDoc type = parent.getType();
410         String JavaDoc charset = parent.getCharset();
411
412         if (charset == null) {
413             return type;
414         }
415
416         return type + ";charset=" + charset;
417     }
418 }
419
420  /**
421   * Thread to actually send the mail. It could conceivably take some time
422   * for the mail to be sent. This thread allows for that so that the user will
423   * not be bogged down waiting for the mail to be sent before they can use
424   * their webbrowser again. Notification will also be sent to the from address
425   * of the message of mail that could not be delivered, and which address it
426   * could not be delivered to. If the mail does not contain a from address
427   * mail will be sent to user.from property.
428   */

429 class Mail extends Thread JavaDoc {
430
431     private MimeMessage JavaDoc message = null; // the message to be sent
432
// used to get the servlet context for logging
433
private javax.servlet.ServletContext JavaDoc sc = null;
434     String JavaDoc mailto; // list of to address this message is being sent to
435

436     Mail (MimeMessage JavaDoc mail, javax.servlet.ServletContext JavaDoc servletcontext,
437       String JavaDoc to) {
438     message = mail;
439     sc = servletcontext;
440     mailto = to;
441     }
442
443     public void run() {
444
445     try {
446         // send the message
447
Transport.send(message);
448
449     } catch (MessagingException JavaDoc me) {
450         // exception occurs when the e-mail cannot be sent to anyone of the
451
// to addresses in the message depending on the mail properties set
452
// this may or may not cause transmission of the message to end.
453
// This error will be logged and a message will be sent to the from
454
// address explaining that the message could not be sent.
455
// Since the JSP has already finished executing this exception will
456
// do nothing visible, however the errors should be dealt with by
457
// the SMTP host if it is configured correctly
458
sc.log("Could not send the e-mail sent to " + mailto + ": " +
459            me.getMessage());
460     }
461     }
462 }
463
Popular Tags