File Source: MailUtil.java
/*
P/P * Method: org.apache.roller.weblogger.util.MailUtil$MailingException__static_init
*/
1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. The ASF licenses this file to You
4 * under the Apache License, Version 2.0 (the "License"); you may not
5 * 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. For additional information regarding
15 * copyright in this work, please see the NOTICE file in the top level
16 * directory of this distribution.
17 */
18
19 package org.apache.roller.weblogger.util;
20
21 import java.text.MessageFormat;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.ResourceBundle;
28 import java.util.Set;
29 import java.util.TreeSet;
30 import javax.mail.Message;
31 import javax.mail.MessagingException;
32 import javax.mail.SendFailedException;
33 import javax.mail.Session;
34 import javax.mail.Transport;
35 import javax.mail.Address;
36 import javax.mail.internet.InternetAddress;
37 import javax.mail.internet.MimeMessage;
38 import org.apache.commons.lang.StringUtils;
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41 import org.apache.roller.weblogger.WebloggerException;
42 import org.apache.roller.weblogger.business.MailProvider;
43 import org.apache.roller.weblogger.business.WebloggerFactory;
44 import org.apache.roller.weblogger.business.UserManager;
45 import org.apache.roller.weblogger.business.startup.WebloggerStartup;
46 import org.apache.roller.weblogger.config.WebloggerConfig;
47 import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
48 import org.apache.roller.weblogger.pojos.WeblogPermission;
49 import org.apache.roller.weblogger.pojos.User;
50 import org.apache.roller.weblogger.pojos.WeblogEntry;
51 import org.apache.roller.weblogger.pojos.Weblog;
52 import org.apache.roller.weblogger.pojos.WeblogEntryComment;
53 import org.apache.roller.weblogger.util.RollerMessages.RollerMessage;
54
55
56 /**
57 * A utility class for helping with sending emails.
58 */
/*
P/P * Method: void org.apache.roller.weblogger.util.MailUtil()
*/
59 public class MailUtil {
60
/*
P/P * Method: org.apache.roller.weblogger.util.MailUtil__static_init
*
* Postconditions:
* init'ed(log)
*/
61 private static Log log = LogFactory.getLog(MailUtil.class);
62
63 private static final String EMAIL_ADDR_REGEXP = "^.*@.*[.].{2,}$";
64
65
66 /**
67 * Ideally mail senders should call this first to avoid errors that occur
68 * when mail is not properly configured. We'll complain about that at
69 * startup, no need to complain on every attempt to send.
70 */
71 public static boolean isMailConfigured() {
/*
P/P * Method: bool isMailConfigured()
*
* Postconditions:
* init'ed(return_value)
*/
72 return WebloggerStartup.getMailProvider() != null;
73 }
74
75 /**
76 * Send an email notice that a new pending entry has been submitted.
77 */
78 public static void sendPendingEntryNotice(WeblogEntry entry)
79 throws WebloggerException {
80
/*
P/P * Method: void sendPendingEntryNotice(WeblogEntry)
*
* Preconditions:
* (soft) entry != null
* (soft) log != null
*
* Presumptions:
* init'ed(java.lang.Boolean.TRUE)
* java.util.ArrayList:size(...)@113 >= 0
* java.util.Iterator:next(...)@105 != null
* java.util.ResourceBundle:getBundle(...)@118 != null
* org.apache.roller.weblogger.business.MailProvider:getSession(...)@81 != null
* ...
*
* Test Vectors:
* java.util.Iterator:hasNext(...)@104: {0}, {1}
* org.apache.roller.weblogger.pojos.User:getEmailAddress(...)@106: Addr_Set{null}, Inverse{null}
* org.apache.roller.weblogger.pojos.Weblog:hasUserPermissions(...)@106: {0}, {1}
*/
81 Session mailSession = WebloggerStartup.getMailProvider().getSession();
82 if(mailSession == null) {
83 throw new WebloggerException("Couldn't get mail Session");
84 }
85
86 try {
87 UserManager umgr = WebloggerFactory.getWeblogger().getUserManager();
88
89 String userName = entry.getCreator().getUserName();
90 String from = entry.getCreator().getEmailAddress();
91 String cc[] = new String[] {from};
92 String bcc[] = new String[0];
93 String to[];
94 String subject;
95 String content;
96
97 // list of enabled website authors and admins
98 ArrayList reviewers = new ArrayList();
99 List websiteUsers = umgr.getUsers(
100 entry.getWebsite(), Boolean.TRUE, null, null, 0, -1);
101
102 // build list of reviewers (website users with author permission)
103 Iterator websiteUserIter = websiteUsers.iterator();
104 while (websiteUserIter.hasNext()) {
105 User websiteUser = (User)websiteUserIter.next();
106 if (entry.getWebsite().hasUserPermissions(
107
108 websiteUser,WeblogPermission.AUTHOR)
109 && websiteUser.getEmailAddress() != null) {
110 reviewers.add(websiteUser.getEmailAddress());
111 }
112 }
113 to = (String[])reviewers.toArray(new String[reviewers.size()]);
114
115 // Figure URL to entry edit page
116 String editURL = WebloggerFactory.getWeblogger().getUrlStrategy().getEntryEditURL(entry.getWebsite().getHandle(), entry.getId(), true);
117
118 ResourceBundle resources = ResourceBundle.getBundle(
119 "ApplicationResources", entry.getWebsite().getLocaleInstance());
120 StringBuffer sb = new StringBuffer();
121 sb.append(
122 MessageFormat.format(
123 resources.getString("weblogEntry.pendingEntrySubject"),
124 new Object[] {
125 entry.getWebsite().getName(),
126 entry.getWebsite().getHandle()
127 }));
128 subject = sb.toString();
129 sb = new StringBuffer();
130 sb.append(
131 MessageFormat.format(
132 resources.getString("weblogEntry.pendingEntryContent"),
133 new Object[] { userName, userName, editURL })
134 );
135 content = sb.toString();
136 MailUtil.sendTextMessage(
137 from, to, cc, bcc, subject, content);
138 } catch (MessagingException e) {
139 log.error("ERROR: Problem sending pending entry notification email.");
140 }
141 }
142
143
144 /**
145 * Send a weblog invitation email.
146 */
147 public static void sendWeblogInvitation(Weblog website,
148 User user)
149 throws WebloggerException {
150
/*
P/P * Method: void sendWeblogInvitation(Weblog, User)
*
* Preconditions:
* user != null
* website != null
* (soft) log != null
*
* Presumptions:
* java.util.ResourceBundle:getBundle(...)@172 != null
* org.apache.roller.weblogger.business.MailProvider:getSession(...)@151 != null
* org.apache.roller.weblogger.business.WebloggerFactory:getWeblogger(...)@158 != null
* org.apache.roller.weblogger.business.startup.WebloggerStartup:getMailProvider(...)@151 != null
*/
151 Session mailSession = WebloggerStartup.getMailProvider().getSession();
152 if(mailSession == null) {
153 throw new WebloggerException("ERROR: Notification email(s) not sent, "
154 + "Roller's mail session not properly configured");
155 }
156
157 try {
+ 158 UserManager umgr = WebloggerFactory.getWeblogger().getUserManager();
159
+ 160 String userName = user.getUserName();
161 String from = website.getEmailAddress();
162 String cc[] = new String[] {from};
163 String bcc[] = new String[0];
164 String to[] = new String[] {user.getEmailAddress()};
165 String subject;
166 String content;
167
168 // Figure URL to entry edit page
169 String rootURL = WebloggerRuntimeConfig.getAbsoluteContextURL();
170 String url = rootURL + "/roller-ui/menu.rol";
171
172 ResourceBundle resources = ResourceBundle.getBundle(
173 "ApplicationResources",
174 website.getLocaleInstance());
175 StringBuffer sb = new StringBuffer();
176 sb.append(MessageFormat.format(
177 resources.getString("inviteMember.notificationSubject"),
178 new Object[] {
179 website.getName(),
180 website.getHandle()})
181 );
182 subject = sb.toString();
183 sb = new StringBuffer();
184 sb.append(MessageFormat.format(
185 resources.getString("inviteMember.notificationContent"),
186 new Object[] {
187 website.getName(),
188 website.getHandle(),
189 user.getUserName(),
190 url
191 }));
192 content = sb.toString();
193 MailUtil.sendTextMessage(
194 from, to, cc, bcc, subject, content);
195 } catch (MessagingException e) {
196 throw new WebloggerException("ERROR: Notification email(s) not sent, "
197 + "due to Roller configuration or mail server problem.", e);
198 }
199 }
200
201
202 /**
203 * Send a weblog invitation email.
204 */
205 public static void sendUserActivationEmail(User user)
206 throws WebloggerException {
207
/*
P/P * Method: void sendUserActivationEmail(User)
*
* Preconditions:
* user != null
* (soft) log != null
*
* Presumptions:
* java.util.ResourceBundle:getBundle(...)@215 != null
* org.apache.roller.weblogger.business.MailProvider:getSession(...)@208 != null
* org.apache.roller.weblogger.business.startup.WebloggerStartup:getMailProvider(...)@208 != null
*/
208 Session mailSession = WebloggerStartup.getMailProvider().getSession();
209 if(mailSession == null) {
210 throw new WebloggerException("ERROR: Notification email(s) not sent, "
211 + "Roller's mail session not properly configured");
212 }
213
214 try {
215 ResourceBundle resources = ResourceBundle.getBundle(
216 "ApplicationResources", I18nUtils.toLocale(user.getLocale()));
217
218 String from = WebloggerRuntimeConfig.getProperty(
219 "user.account.activation.mail.from");
220
221 String cc[] = new String[0];
222 String bcc[] = new String[0];
223 String to[] = new String[] { user.getEmailAddress() };
224 String subject = resources.getString(
225 "user.account.activation.mail.subject");
226 String content;
227
228 String rootURL = WebloggerRuntimeConfig.getAbsoluteContextURL();
229
230 StringBuffer sb = new StringBuffer();
231
232 // activationURL=
233 String activationURL = rootURL
234 + "/roller-ui/register!activate.rol?activationCode="
235 + user.getActivationCode();
236 sb.append(MessageFormat.format(
237 resources.getString("user.account.activation.mail.content"),
238 new Object[] { user.getFullName(), user.getUserName(),
239 activationURL }));
240 content = sb.toString();
241
242 sendHTMLMessage(from, to, cc, bcc, subject, content);
243 } catch (MessagingException e) {
244 throw new WebloggerException("ERROR: Problem sending activation email.", e);
245 }
246 }
247
248
249 /**
250 * Send email notification of new or newly approved comment.
251 * TODO: Make the addressing options configurable on a per-website basis.
252 *
253 * @param commentObject The new comment
254 * @param messages Messages to be included in e-mail (or null).
255 * Errors will be assumed to be "validation errors"
256 * and messages will be assumed to be "from the system"
257 */
258 public static void sendEmailNotification(WeblogEntryComment commentObject,
259 RollerMessages messages,
260 I18nMessages resources,
261 boolean notifySubscribers)
262 throws MailingException {
263
/*
P/P * Method: void sendEmailNotification(WeblogEntryComment, RollerMessages, I18nMessages, bool)
*
* Preconditions:
* commentObject != null
* (soft) log != null
* (soft) messages != null
* (soft) messages.mErrors != null
* (soft) messages.mMessages != null
* (soft) resources != null
* (soft) resources.bundle != null
*
* Presumptions:
* bcc.length@318 <= 232-1
* java.util.Iterator:next(...)@298 != null
* java.util.Iterator:next(...)@372 != null
* java.util.Iterator:next(...)@389 != null
* java.util.Set:toArray(...)@318 != null
* ...
*
* Test Vectors:
* notifySubscribers: {0}, {1}
* commenterAddrs.length@318: {0}, {1..+Inf}
* java.lang.Boolean:booleanValue(...)@270: {1}, {0}
* java.lang.Boolean:booleanValue(...)@302: {0}, {1}
* java.lang.String:matches(...)@304: {0}, {1}
* java.util.Iterator:hasNext(...)@371: {0}, {1}
* java.util.Iterator:hasNext(...)@388: {0}, {1}
* java.util.List:size(...)@70: {-231..0}, {1..232-1}
* java.util.List:size(...)@74: {-231..0}, {1..232-1}
* java.util.Set:size(...)@421: {2..232-1}, {-231..1}
* ...
*/
264 WeblogEntry entry = commentObject.getWeblogEntry();
265 Weblog weblog = entry.getWebsite();
266 User user = entry.getCreator();
267
268 // Only send email if email notificaiton is enabled
269 boolean notify = WebloggerRuntimeConfig.getBooleanProperty("users.comments.emailnotify");
270 if (!notify || !weblog.getEmailComments().booleanValue()) {
271 // notifications disabled, just bail
272 return;
273 }
274
275 log.debug("Comment notification enabled ... preparing email");
276
277 // Determine message and addressing options from init parameters
278 boolean hideCommenterAddrs = WebloggerConfig.getBooleanProperty(
279 "comment.notification.hideCommenterAddresses");
280
281 // use either the weblog configured from address or the site configured from address
282 String from = weblog.getEmailFromAddress();
283 if(StringUtils.isEmpty(from)) {
284 // TODO: this should not be the users email address
285 from = user.getEmailAddress();
286 }
287
288 // build list of email addresses to send notification to
289 Set subscribers = new TreeSet();
290
291 // If we are to notify subscribers, then...
292 if (notifySubscribers) {
293 log.debug("Sending notification email to all subscribers");
294
295 // Get all the subscribers to this comment thread
296 List comments = entry.getComments(true, true);
297 for (Iterator it = comments.iterator(); it.hasNext();) {
298 WeblogEntryComment comment = (WeblogEntryComment) it.next();
299 if (!StringUtils.isEmpty(comment.getEmail())) {
300 // If user has commented twice,
301 // count the most recent notify setting
302 if (comment.getNotify().booleanValue()) {
303 // only add those with valid email
304 if (comment.getEmail().matches(EMAIL_ADDR_REGEXP)) {
305 subscribers.add(comment.getEmail());
306 }
307 } else {
308 // remove user who doesn't want to be notified
309 subscribers.remove(comment.getEmail());
310 }
311 }
312 }
313 } else {
314 log.debug("Sending notification email only to weblog owner");
315 }
316
317 // Form array of commenter addrs
318 String[] commenterAddrs = (String[])subscribers.toArray(new String[0]);
319
320 //------------------------------------------
321 // --- Form the messages to be sent -
322 // Build separate owner and commenter (aka subscriber) messages
323
324 // Determine with mime type to use for e-mail
325 StringBuffer msg = new StringBuffer();
326 StringBuffer ownermsg = new StringBuffer();
327 boolean escapeHtml = !WebloggerRuntimeConfig.getBooleanProperty("users.comments.htmlenabled");
328
329 // first the commenter message
330
331 if (!escapeHtml) {
332 msg.append("<html><body style=\"background: white; ");
333 msg.append(" color: black; font-size: 12px\">");
334 }
335
336 if (!StringUtils.isEmpty(commentObject.getName())) {
337 msg.append(commentObject.getName() + " "
338 + resources.getString("email.comment.wrote")+": ");
339 } else {
340 msg.append(resources.getString("email.comment.anonymous")+": ");
341 }
342
343 msg.append((escapeHtml) ? "\n\n" : "<br /><br />");
344
345 msg.append((escapeHtml) ? Utilities.escapeHTML(commentObject.getContent())
346 : Utilities.transformToHTMLSubset(Utilities.escapeHTML(commentObject.getContent())));
347
348 msg.append((escapeHtml) ? "\n\n----\n"
349 : "<br /><br /><hr /><span style=\"font-size: 11px\">");
350 msg.append(resources.getString("email.comment.respond") + ": ");
351 msg.append((escapeHtml) ? "\n" : "<br />");
352
353 // Build link back to comment
354 String commentURL = WebloggerFactory.getWeblogger().getUrlStrategy().getWeblogCommentsURL(weblog, null, entry.getAnchor(), true);
355
356 if (escapeHtml) {
357 msg.append(commentURL);
358 } else {
359 msg.append("<a href=\""+commentURL+"\">"+commentURL+"</a></span>");
360 }
361
362 // next the owner message
363
364 // First, list any messages from the system that were passed in:
365 if (messages.getMessageCount() > 0) {
366 ownermsg.append((escapeHtml) ? "" : "<p>");
367 ownermsg.append(resources.getString("commentServlet.email.thereAreSystemMessages"));
368 ownermsg.append((escapeHtml) ? "\n\n" : "</p>");
369 ownermsg.append((escapeHtml) ? "" : "<ul>");
370 }
371 for (Iterator it = messages.getMessages(); it.hasNext();) {
372 RollerMessage rollerMessage = (RollerMessage)it.next();
373 ownermsg.append((escapeHtml) ? "" : "<li>");
374 ownermsg.append(MessageFormat.format(resources.getString(rollerMessage.getKey()), (Object[])rollerMessage.getArgs()) );
375 ownermsg.append((escapeHtml) ? "\n\n" : "</li>");
376 }
377 if (messages.getMessageCount() > 0) {
378 ownermsg.append((escapeHtml) ? "\n\n" : "</ul>");
379 }
380
381 // Next, list any validation error messages that were passed in:
382 if (messages.getErrorCount() > 0) {
383 ownermsg.append((escapeHtml) ? "" : "<p>");
384 ownermsg.append(resources.getString("commentServlet.email.thereAreErrorMessages"));
385 ownermsg.append((escapeHtml) ? "\n\n" : "</p>");
386 ownermsg.append((escapeHtml) ? "" : "<ul>");
387 }
388 for (Iterator it = messages.getErrors(); it.hasNext();) {
389 RollerMessage rollerMessage = (RollerMessage)it.next();
390 ownermsg.append((escapeHtml) ? "" : "<li>");
391 ownermsg.append(MessageFormat.format(resources.getString(rollerMessage.getKey()), (Object[])rollerMessage.getArgs()) );
392 ownermsg.append((escapeHtml) ? "\n\n" : "</li>");
393 }
394 if (messages.getErrorCount() > 0) {
395 ownermsg.append((escapeHtml) ? "\n\n" : "</ul>");
396 }
397
398 ownermsg.append(msg);
399
400 // add link to weblog edit page so user can login to manage comments
401 ownermsg.append((escapeHtml) ? "\n\n----\n" :
402 "<br /><br /><hr /><span style=\"font-size: 11px\">");
403 ownermsg.append("Link to comment management page:");
404 ownermsg.append((escapeHtml) ? "\n" : "<br />");
405
406 Map<String, String> parameters = new HashMap();
407 parameters.put("bean.entryId", entry.getId());
408 String deleteURL = WebloggerFactory.getWeblogger().getUrlStrategy().getActionURL(
409 "comments", "/roller-ui/authoring", weblog.getHandle(), parameters, true);
410
411 if (escapeHtml) {
412 ownermsg.append(deleteURL);
413 } else {
414 ownermsg.append(
415 "<a href=\"" + deleteURL + "\">" + deleteURL + "</a></span>");
416 msg.append("</Body></html>");
417 ownermsg.append("</Body></html>");
418 }
419
420 String subject = null;
421 if ((subscribers.size() > 1) ||
422 (StringUtils.equals(commentObject.getEmail(), user.getEmailAddress()))) {
423 subject= "RE: "+resources.getString("email.comment.title")+": ";
424 } else {
425 subject = resources.getString("email.comment.title") + ": ";
426 }
427 subject += entry.getTitle();
428
429 // send message to email recipients
430 try {
431 boolean isHtml = !escapeHtml;
432
433 // Send separate messages to owner and commenters
434 if(isHtml) {
435 sendHTMLMessage(
436 from,
437 new String[]{user.getEmailAddress()},
438 null,
439 null,
440 subject,
441 ownermsg.toString());
442 } else {
443 sendTextMessage(
444 from,
445 new String[]{user.getEmailAddress()},
446 null,
447 null,
448 subject,
449 ownermsg.toString());
450 }
451
452 // now send to subscribers
453 if (notifySubscribers && commenterAddrs.length > 0) {
454 // If hiding commenter addrs, they go in Bcc: otherwise in the To: of the second message
455 String[] to = hideCommenterAddrs ? null : commenterAddrs;
456 String[] bcc = hideCommenterAddrs ? commenterAddrs : null;
457
458 if(isHtml) {
459 sendHTMLMessage(
460 from,
461 to,
462 null,
463 bcc,
464 subject,
465 msg.toString());
466 } else {
467 sendTextMessage(
468 from,
469 to,
470 null,
471 bcc,
472 subject,
473 msg.toString());
474 }
475 }
476 } catch (Exception e) {
477 log.warn("Exception sending comment notification mail", e);
478 // This will log the stack trace if debug is enabled
479 if (log.isDebugEnabled()) {
480 log.debug(e);
481 }
482 }
483
484 log.debug("Done sending email message");
485 }
486
487
488 public static void sendEmailApprovalNotifications(List<WeblogEntryComment> comments,
489 I18nMessages resources)
490 throws MailingException {
491
/*
P/P * Method: void sendEmailApprovalNotifications(List, I18nMessages)
*
* Preconditions:
* comments != null
* (soft) log != null
* (soft) resources != null
* (soft) resources.bundle != null
*
* Presumptions:
* java.util.Iterator:next(...)@493 != null
*
* Test Vectors:
* java.util.Iterator:hasNext(...)@493: {0}, {1}
*/
492 RollerMessages messages = new RollerMessages();
493 for (WeblogEntryComment comment : comments) {
494
495 // Send email notifications because a new comment has been approved
496 sendEmailNotification(comment, messages, resources, true);
497
498 // Send approval notification to author of approved comment
499 sendEmailApprovalNotification(comment, resources);
500 }
501 }
502
503
504 /**
505 * Send message to author of approved comment
506 *
507 * TODO: Make the addressing options configurable on a per-website basis.
508 */
509 public static void sendEmailApprovalNotification(WeblogEntryComment cd,
510 I18nMessages resources)
511 throws MailingException {
512
/*
P/P * Method: void sendEmailApprovalNotification(WeblogEntryComment, I18nMessages)
*
* Preconditions:
* cd != null
* (soft) log != null
* (soft) resources != null
* (soft) resources.bundle != null
*
* Presumptions:
* org.apache.roller.weblogger.business.Weblogger:getUrlStrategy(...)@539 != null
* org.apache.roller.weblogger.business.WebloggerFactory:getWeblogger(...)@539 != null
* org.apache.roller.weblogger.pojos.Weblog:getEmailComments(...)@519 != null
* org.apache.roller.weblogger.pojos.WeblogEntry:getCreator(...)@515 != null
* org.apache.roller.weblogger.pojos.WeblogEntry:getWebsite(...)@514 != null
* ...
*
* Test Vectors:
* java.lang.Boolean:booleanValue(...)@519: {1}, {0}
* org.apache.commons.lang.StringUtils:isEmpty(...)@528: {0}, {1}
* org.apache.roller.weblogger.config.WebloggerRuntimeConfig:getBooleanProperty(...)@518: {0}, {1}
*/
513 WeblogEntry entry = cd.getWeblogEntry();
514 Weblog weblog = entry.getWebsite();
515 User user = entry.getCreator();
516
517 // Only send email if email notificaiton is enabled
518 boolean notify = WebloggerRuntimeConfig.getBooleanProperty("users.comments.emailnotify");
519 if (!notify || !weblog.getEmailComments().booleanValue()) {
520 // notifications disabled, just bail
521 return;
522 }
523
524 log.debug("Comment notification enabled ... preparing email");
525
526 // use either the weblog configured from address or the site configured from address
527 String from = weblog.getEmailFromAddress();
528 if(StringUtils.isEmpty(from)) {
529 // TODO: this should not be the users email address
530 from = user.getEmailAddress();
531 }
532
533 // form the message to be sent
534 String subject = resources.getString("email.comment.commentApproved");
535
536 StringBuffer msg = new StringBuffer();
537 msg.append(resources.getString("email.comment.commentApproved"));
538 msg.append("\n\n");
539 msg.append(WebloggerFactory.getWeblogger().getUrlStrategy().getWeblogCommentsURL(weblog, null, entry.getAnchor(), true));
540
541 // send message to author of approved comment
542 try {
543 sendTextMessage(
544 from, // from
545 new String[] {cd.getEmail()}, // to
546 null, // cc
547 null, // bcc
548 subject, // subject
549 msg.toString()); // message
550 } catch (Exception e) {
551 log.warn("Exception sending comment mail: " + e.getMessage());
552 // This will log the stack trace if debug is enabled
553 if (log.isDebugEnabled()) {
554 log.debug(e);
555 }
556 }
557
558 log.debug("Done sending email message");
559 }
560
561
562 // agangolli: Incorporated suggested changes from Ken Blackler.
563
564 /**
565 * This method is used to send a Message with a pre-defined
566 * mime-type.
567 *
568 * @param from e-mail address of sender
569 * @param to e-mail address(es) of recipients
570 * @param subject subject of e-mail
571 * @param content the body of the e-mail
572 * @param mimeType type of message, i.e. text/plain or text/html
573 * @throws MessagingException the exception to indicate failure
574 */
575 public static void sendMessage
576 (
577 String from,
578 String[] to,
579 String[] cc,
580 String[] bcc,
581 String subject,
582 String content,
583 String mimeType
584 )
585 throws MessagingException {
586
/*
P/P * Method: void sendMessage(String, String[], String[], String[], String, String, String)
*
* Preconditions:
* (soft) bcc.length <= 232-1
* (soft) init'ed(bcc[...])
* (soft) cc.length <= 232-1
* (soft) init'ed(cc[...])
* (soft) log != null
* (soft) to.length <= 232-1
* (soft) init'ed(to[...])
*
* Presumptions:
* init'ed(javax.mail.Message$RecipientType.BCC)
* init'ed(javax.mail.Message$RecipientType.CC)
* init'ed(javax.mail.Message$RecipientType.TO)
* javax.mail.Message:getAllRecipients(...)@636 != null
* org.apache.roller.weblogger.business.MailProvider:getTransport(...)@642 != null
* ...
*
* Test Vectors:
* bcc: Addr_Set{null}, Inverse{null}
* cc: Addr_Set{null}, Inverse{null}
* to: Addr_Set{null}, Inverse{null}
* org.apache.commons.lang.StringUtils:isEmpty(...)@596: {1}, {0}
* org.apache.commons.logging.Log:isDebugEnabled(...)@599: {0}, {1}
* org.apache.commons.logging.Log:isDebugEnabled(...)@607: {0}, {1}
* org.apache.commons.logging.Log:isDebugEnabled(...)@617: {0}, {1}
* org.apache.commons.logging.Log:isDebugEnabled(...)@627: {0}, {1}
* org.apache.roller.weblogger.business.startup.WebloggerStartup:getMailProvider(...)@587: Inverse{null}, Addr_Set{null}
*/
587 MailProvider mailProvider = WebloggerStartup.getMailProvider();
588 if(mailProvider == null) {
589 return;
590 }
591
592 Session session = mailProvider.getSession();
593 Message message = new MimeMessage(session);
594
595 // n.b. any default from address is expected to be determined by caller.
596 if (! StringUtils.isEmpty(from)) {
597 InternetAddress sentFrom = new InternetAddress(from);
598 message.setFrom(sentFrom);
599 if (log.isDebugEnabled()) log.debug("e-mail from: " + sentFrom);
600 }
601
602 if (to!=null) {
603 InternetAddress[] sendTo = new InternetAddress[to.length];
604
605 for (int i = 0; i < to.length; i++) {
606 sendTo[i] = new InternetAddress(to[i]);
607 if (log.isDebugEnabled()) log.debug("sending e-mail to: " + to[i]);
608 }
609 message.setRecipients(Message.RecipientType.TO, sendTo);
610 }
611
612 if (cc != null) {
613 InternetAddress[] copyTo = new InternetAddress[cc.length];
614
615 for (int i = 0; i < cc.length; i++) {
616 copyTo[i] = new InternetAddress(cc[i]);
617 if (log.isDebugEnabled()) log.debug("copying e-mail to: " + cc[i]);
618 }
619 message.setRecipients(Message.RecipientType.CC, copyTo);
620 }
621
622 if (bcc != null) {
623 InternetAddress[] copyTo = new InternetAddress[bcc.length];
624
625 for (int i = 0; i < bcc.length; i++) {
626 copyTo[i] = new InternetAddress(bcc[i]);
627 if (log.isDebugEnabled()) log.debug("blind copying e-mail to: " + bcc[i]);
628 }
629 message.setRecipients(Message.RecipientType.BCC, copyTo);
630 }
631 message.setSubject((subject == null) ? "(no subject)" : subject);
632 message.setContent(content, mimeType);
633 message.setSentDate(new java.util.Date());
634
635 // First collect all the addresses together.
636 Address[] remainingAddresses = message.getAllRecipients();
+ 637 int nAddresses = remainingAddresses.length;
638 boolean bFailedToSome = false;
639
640 SendFailedException sendex = new SendFailedException("Unable to send message to some recipients");
641
642 Transport transport = mailProvider.getTransport();
643
644 // Try to send while there remain some potentially good addresses
645 try {
646 do {
647 // Avoid a loop if we are stuck
648 nAddresses = remainingAddresses.length;
649
650 try {
651 // Send to the list of remaining addresses, ignoring the addresses attached to the message
652 transport.send(message, remainingAddresses);
653 } catch(SendFailedException ex) {
654 bFailedToSome=true;
655 sendex.setNextException(ex);
656
657 // Extract the remaining potentially good addresses
658 remainingAddresses=ex.getValidUnsentAddresses();
659 }
660 } while (remainingAddresses!=null && remainingAddresses.length>0 && remainingAddresses.length!=nAddresses);
661
662 } finally {
663 transport.close();
664 }
665
+ 666 if (bFailedToSome) throw sendex;
667 }
668
669
670 /**
671 * This method is used to send a Text Message.
672 *
673 * @param from e-mail address of sender
674 * @param to e-mail addresses of recipients
675 * @param subject subject of e-mail
676 * @param content the body of the e-mail
677 * @throws MessagingException the exception to indicate failure
678 */
679 public static void sendTextMessage
680 (
681 String from,
682 String[] to,
683 String[] cc,
684 String[] bcc,
685 String subject,
686 String content
687 )
688 throws MessagingException {
/*
P/P * Method: void sendTextMessage(String, String[], String[], String[], String, String)
*
* Preconditions:
* (soft) bcc.length <= 232-1
* (soft) init'ed(bcc[...])
* (soft) cc.length <= 232-1
* (soft) init'ed(cc[...])
* (soft) log != null
* (soft) to.length <= 232-1
* (soft) init'ed(to[...])
*/
689 sendMessage(from, to, cc, bcc, subject, content, "text/plain; charset=utf-8");
690 }
691
692
693 /**
694 * This method overrides the sendTextMessage to specify
695 * one receiver and mulitple cc recipients.
696 *
697 * @param from e-mail address of sender
698 * @param to e-mail addresses of recipients
699 * @param subject subject of e-mail
700 * @param content the body of the e-mail
701 * @throws MessagingException the exception to indicate failure
702 */
703 public static void sendTextMessage
704 (
705 String from,
706 String to,
707 String[] cc,
708 String[] bcc,
709 String subject,
710 String content
711 )
712 throws MessagingException {
/*
P/P * Method: void sendTextMessage(String, String, String[], String[], String, String)
*
* Preconditions:
* (soft) bcc.length <= 232-1
* (soft) init'ed(bcc[...])
* (soft) cc.length <= 232-1
* (soft) init'ed(cc[...])
* (soft) log != null
*
* Test Vectors:
* to: Addr_Set{null}, Inverse{null}
*/
713 String[] recipient = null;
714 if (to!=null) recipient = new String[] {to};
715
716 sendMessage(from, recipient, cc, bcc, subject, content, "text/plain; charset=utf-8");
717 }
718
719
720 /**
721 * This method overrides the sendTextMessage to specify
722 * only one receiver and cc recipients, rather than
723 * an array of recipients.
724 *
725 * @param from e-mail address of sender
726 * @param to e-mail address of recipient
727 * @param cc e-mail address of cc recipient
728 * @param subject subject of e-mail
729 * @param content the body of the e-mail
730 * @throws MessagingException the exception to indicate failure
731 */
732 public static void sendTextMessage
733 (
734 String from,
735 String to,
736 String cc,
737 String bcc,
738 String subject,
739 String content
740 )
741 throws MessagingException {
/*
P/P * Method: void sendTextMessage(String, String, String, String, String, String)
*
* Preconditions:
* (soft) log != null
*
* Test Vectors:
* bcc: Addr_Set{null}, Inverse{null}
* cc: Addr_Set{null}, Inverse{null}
* to: Addr_Set{null}, Inverse{null}
*/
742 String[] recipient = null;
743 String[] copy = null;
744 String[] bcopy = null;
745
746 if (to!=null) recipient = new String[] {to};
747 if (cc!=null) copy = new String[] {cc};
748 if (bcc!=null) bcopy = new String[] {bcc};
749
750 sendMessage(from, recipient, copy, bcopy, subject, content, "text/plain; charset=utf-8");
751 }
752
753
754 /**
755 * This method is used to send a HTML Message
756 *
757 * @param from e-mail address of sender
758 * @param to e-mail address(es) of recipients
759 * @param subject subject of e-mail
760 * @param content the body of the e-mail
761 * @throws MessagingException the exception to indicate failure
762 */
763 public static void sendHTMLMessage
764 (
765 String from,
766 String[] to,
767 String[] cc,
768 String[] bcc,
769 String subject,
770 String content
771 )
772 throws MessagingException {
/*
P/P * Method: void sendHTMLMessage(String, String[], String[], String[], String, String)
*
* Preconditions:
* (soft) bcc.length <= 232-1
* (soft) init'ed(bcc[...])
* (soft) cc.length <= 232-1
* (soft) init'ed(cc[...])
* (soft) log != null
* (soft) to.length <= 232-1
* (soft) init'ed(to[...])
*/
773 sendMessage(from, to, cc, bcc, subject, content, "text/html; charset=utf-8");
774 }
775
776
777 /**
778 * This method overrides the sendHTMLMessage to specify
779 * only one sender, rather than an array of senders.
780 *
781 * @param from e-mail address of sender
782 * @param to e-mail address of recipients
783 * @param subject subject of e-mail
784 * @param content the body of the e-mail
785 * @throws MessagingException the exception to indicate failure
786 */
787 public static void sendHTMLMessage
788 (
789 String from,
790 String to,
791 String cc,
792 String bcc,
793 String subject,
794 String content
795 )
796 throws MessagingException {
/*
P/P * Method: void sendHTMLMessage(String, String, String, String, String, String)
*
* Preconditions:
* (soft) log != null
*
* Test Vectors:
* bcc: Addr_Set{null}, Inverse{null}
* cc: Addr_Set{null}, Inverse{null}
* to: Addr_Set{null}, Inverse{null}
*/
797 String[] recipient = null;
798 String[] copy = null;
799 String[] bcopy = null;
800
801 if (to!=null) recipient = new String[] {to};
802 if (cc!=null) copy = new String[] {cc};
803 if (bcc!=null) bcopy = new String[] {bcc};
804
805 sendMessage(from, recipient, copy, bcopy, subject, content, "text/html; charset=utf-8");
806 }
807
808
809 /**
810 * This method overrides the sendHTMLMessage to specify
811 * one receiver and mulitple cc recipients.
812 *
813 * @param from e-mail address of sender
814 * @param to e-mail address of recipient
815 * @param cc e-mail addresses of recipients
816 * @param subject subject of e-mail
817 * @param content the body of the e-mail
818 * @throws MessagingException the exception to indicate failure
819 */
820 public static void sendHTMLMessage
821 (
822 String from,
823 String to,
824 String[] cc,
825 String[] bcc,
826 String subject,
827 String content
828 )
829 throws MessagingException {
/*
P/P * Method: void sendHTMLMessage(String, String, String[], String[], String, String)
*
* Preconditions:
* (soft) bcc.length <= 232-1
* (soft) init'ed(bcc[...])
* (soft) cc.length <= 232-1
* (soft) init'ed(cc[...])
* (soft) log != null
*
* Test Vectors:
* to: Addr_Set{null}, Inverse{null}
*/
830 String[] recipient = null;
831 if (to!=null) recipient = new String[] {to};
832
833 sendMessage(from, recipient, cc, bcc, subject, content, "text/html; charset=utf-8");
834 }
835
836
837 /**
838 * An exception thrown if there is a problem sending an email.
839 */
840 public class MailingException extends WebloggerException {
/*
P/P * Method: void org.apache.roller.weblogger.util.MailUtil$MailingException(MailUtil, Throwable)
*/
841 public MailingException(Throwable t) {
842 super(t);
843 }
844 }
845 }
SofCheck Inspector Build Version : 2.18479
| MailUtil.java |
2009-Jan-02 14:25:34 |
| MailUtil.class |
2009-Sep-04 03:12:32 |
| MailUtil$MailingException.class |
2009-Sep-04 03:12:32 |