KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > myvietnam > mvncore > util > MailUtil


1 /*
2  * $Header: /cvsroot/mvnforum/myvietnam/src/net/myvietnam/mvncore/util/MailUtil.java,v 1.38 2006/04/15 02:59:20 minhnn Exp $
3  * $Author: minhnn $
4  * $Revision: 1.38 $
5  * $Date: 2006/04/15 02:59:20 $
6  *
7  * ====================================================================
8  *
9  * Copyright (C) 2002-2006 by MyVietnam.net
10  *
11  * All copyright notices regarding MyVietnam and MyVietnam CoreLib
12  * MUST remain intact in the scripts and source code.
13  *
14  * This library is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU Lesser General Public
16  * License as published by the Free Software Foundation; either
17  * version 2.1 of the License, or (at your option) any later version.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27  *
28  * Correspondence and Marketing Questions can be sent to:
29  * info at MyVietnam net
30  *
31  * @author: Minh Nguyen
32  * @author: Mai Nguyen
33  */

34 package net.myvietnam.mvncore.util;
35
36 import java.io.UnsupportedEncodingException JavaDoc;
37 import java.util.*;
38
39 import javax.mail.*;
40 import javax.mail.internet.*;
41 import javax.naming.InitialContext JavaDoc;
42 import javax.naming.NamingException JavaDoc;
43
44 import net.myvietnam.mvncore.MVNCoreConfig;
45 import net.myvietnam.mvncore.exception.BadInputException;
46 import net.myvietnam.mvncore.filter.DisableHtmlTagFilter;
47 import org.apache.commons.logging.Log;
48 import org.apache.commons.logging.LogFactory;
49
50 public final class MailUtil {
51
52     public static final int MAX_MESSAGES_PER_TRANSPORT = 100;
53
54     private static Log log = LogFactory.getLog(MailUtil.class);
55
56     private MailUtil() {// prevent instantiation
57
}
58
59     //private static MailOptions mailOption = new MailOptions();
60

61     /**
62      * Get the user name part of an email. Ex: input: test@yahoo.com => output: test
63      * @param email String the email
64      * @return String the user name part of an email
65      */

66     public static String JavaDoc getEmailUsername(String JavaDoc email) {
67         if (email == null) return "";
68         int atIndex = email.indexOf('@');
69         if (atIndex == -1) {
70             return "";
71         }
72         return email.substring(0, atIndex);
73     }
74
75     /**
76      * Get the domain part of an email. Ex: input: test@yahoo.com => output: yahoo.com
77      * @param email String the email
78      * @return String the user name part of an email
79      */

80     public static String JavaDoc getEmailDomain(String JavaDoc email) {
81         if (email == null) return "";
82         int atIndex = email.indexOf('@');
83         if (atIndex == -1) {
84             return "";
85         }
86         return email.substring(atIndex + 1);
87     }
88
89     /**
90      * Check if an email is good and safe or not.
91      * This method should be use for all email input from user
92      * @param input String
93      * @throws BadInputException if email is not good
94      */

95     public static void checkGoodEmail(String JavaDoc input) throws BadInputException {
96         if (input == null) throw new BadInputException("Sorry, null string is not a good email.");//@todo : localize me
97
int atIndex = input.indexOf('@');
98         int dotIndex = input.lastIndexOf('.');
99         if ((atIndex == -1) || (dotIndex == -1) || (atIndex >= dotIndex)) {
100             //@todo : localize me
101
throw new BadInputException("Error: '" + DisableHtmlTagFilter.filter(input) + "' is not a valid email value. Please try again.");
102         }
103
104         // now check for content of the string
105
int length = input.length();
106         char c = 0;
107
108         for (int i = 0; i < length; i++) {
109             c = input.charAt(i);
110             if ((c >= 'a') && (c <= 'z')) {
111                 // lower char
112
} else if ((c >= 'A') && (c <= 'Z')) {
113                 // upper char
114
} else if ((c >= '0') && (c <= '9')/* && (i != 0)*/) {
115                 // as of 31 Jan 2004, i relax the email checking
116
// so that the email can start with an numeric char
117
// hopefully it does not introduce a security bug
118
// because this value will be inserted into sql script
119

120                 // numeric char
121
} else if ( ( (c=='_') || (c=='-') || (c=='.') || (c=='@') ) && (i != 0) ) {
122                 // _ char
123
} else {
124                 // not good char, throw an BadInputException
125
//@todo : localize me
126
throw new BadInputException(input + " is not a valid email. Reason: character '" + c + "' is not accepted in an email.");
127             }
128         }// for
129

130         // last check
131
try {
132             new javax.mail.internet.InternetAddress JavaDoc(input);
133         } catch (Exception JavaDoc ex) {
134             log.error("Error when running checkGoodEmail", ex);
135             throw new BadInputException("Assertion: dont want to occur in Util.checkGoodEmail");
136         }
137     }
138
139     /**
140      * NOTE: param to, cc, bcc cannot be all empty. At least one must have a valid value
141      * @param from : must be a valid email. However, if this param is null,
142      * then the default mail in config file will be use
143      * @param to : can be null
144      * @param cc : can be null
145      * @param bcc: can be null
146      * @param subject
147      * @param message
148      * @throws MessagingException
149      * @throws BadInputException
150      */

151     public static void sendMail(String JavaDoc from, String JavaDoc to, String JavaDoc cc, String JavaDoc bcc, String JavaDoc subject, String JavaDoc message)
152         throws MessagingException, BadInputException, UnsupportedEncodingException JavaDoc {
153
154         MailMessageStruct mailItem = new MailMessageStruct();
155         mailItem.setFrom(from);
156         mailItem.setTo(to);
157         mailItem.setCc(cc);
158         mailItem.setBcc(bcc);
159         mailItem.setSubject(subject);
160         mailItem.setMessage(message);
161
162         sendMail(mailItem);
163     }
164
165     public static void sendMail(MailMessageStruct mailItem)
166         throws MessagingException, BadInputException, UnsupportedEncodingException JavaDoc {
167
168         ArrayList mailList = new ArrayList(1);
169         mailList.add(mailItem);
170         try {
171             sendMail(mailList);
172         } catch (MessagingException mex) {
173             log.error("MessagingException has occured.", mex);
174             log.debug("MessagingException has occured. Detail info:");
175             log.debug("from = " + mailItem.getFrom());
176             log.debug("to = " + mailItem.getTo());
177             log.debug("cc = " + mailItem.getCc());
178             log.debug("bcc = " + mailItem.getBcc());
179             log.debug("subject = " + mailItem.getSubject());
180             log.debug("message = " + mailItem.getMessage());
181             throw mex;// this may look redundant, but it is not :-)
182
}
183     }
184
185     public static void sendMail(Collection mailStructCollection)
186         throws MessagingException, BadInputException, UnsupportedEncodingException JavaDoc {
187
188         Session session = null;
189         Transport transport = null;
190         int totalEmails = mailStructCollection.size();
191         int count = 0;
192         int sendFailedExceptionCount = 0;
193
194         String JavaDoc server = "";
195         String JavaDoc userName = "";
196         String JavaDoc password = "";
197         int port = 25;
198
199         boolean useMailsource = MVNCoreConfig.isUseMailSource();
200
201         try {
202             for (Iterator iter = mailStructCollection.iterator(); iter.hasNext(); ) {
203                 count++;
204
205                 if ((transport == null) || (session == null)) {
206                     if (useMailsource) {
207                         try {
208                             InitialContext JavaDoc ic = new InitialContext JavaDoc();
209                             // mailSourceName = "java:comp/env/mail/mailSession";
210
String JavaDoc mailSourceName = MVNCoreConfig.getMailSourceName();
211                             log.debug("MailUtil : use mailsource = " + mailSourceName);
212                             session = (Session) ic.lookup("java:comp/env/" + mailSourceName);
213                             transport = session.getTransport("smtp");
214                         } catch (NamingException JavaDoc e) {
215                             log.error("Cannot get Mail session", e);
216                             throw new MessagingException("Cannot get the mail session from JNDI. Send mail failed.");
217                         }
218                     } else {// does not use datasourse
219
Properties props = new Properties();
220
221                         server = MVNCoreConfig.getMailServer();
222                         port = MVNCoreConfig.getMailServerPort();
223                         userName = MVNCoreConfig.getMailUserName();
224                         password = MVNCoreConfig.getMailPassword();
225
226                         props.put("mail.smtp.host", server);
227                         props.put("mail.smtp.port", String.valueOf(port));
228                         if ((userName != null) && (userName.length() > 0)) {
229                             props.put("mail.smtp.auth", "true");
230                         }
231                         //props.put("mail.debug", "true");
232
session = Session.getDefaultInstance(props, null);
233                         transport = session.getTransport("smtp");
234                     }// end of does not use datasource
235

236                     if ((userName != null) && (userName.length() > 0)) {
237                         transport.connect(server, userName, password);
238                     } else {
239                         transport.connect();
240                     }
241                 }
242
243                 MailMessageStruct mailItem = (MailMessageStruct)iter.next();
244
245                 String JavaDoc from = mailItem.getFrom();
246                 String JavaDoc to = mailItem.getTo();
247                 String JavaDoc cc = mailItem.getCc();
248                 String JavaDoc bcc = mailItem.getBcc();
249                 String JavaDoc subject = mailItem.getSubject();
250                 String JavaDoc message = mailItem.getMessage();
251
252                 //if (from == null) from = mailOption.defaultMailFrom;
253
if (from == null) from = MVNCoreConfig.getDefaultMailFrom();
254
255                 try {
256                     // this will also check for email error
257
checkGoodEmail(from);
258                     InternetAddress fromAddress = new InternetAddress(from);
259                     InternetAddress[] toAddress = getInternetAddressEmails(to);
260                     InternetAddress[] ccAddress = getInternetAddressEmails(cc);
261                     InternetAddress[] bccAddress = getInternetAddressEmails(bcc);
262                     if ((toAddress == null) && (ccAddress == null) && (bccAddress == null)) {
263                         //@todo : localize me
264
throw new BadInputException("Cannot send mail since all To, Cc, Bcc addresses are empty.");
265                     }
266
267                     // create a message
268
MimeMessage msg = new MimeMessage(session);
269                     msg.setSentDate(new Date());
270                     msg.setFrom(fromAddress);
271
272                     if (toAddress != null) {
273                         msg.setRecipients(Message.RecipientType.TO, toAddress);
274                     }
275                     if (ccAddress != null) {
276                         msg.setRecipients(Message.RecipientType.CC, ccAddress);
277                     }
278                     if (bccAddress != null) {
279                         msg.setRecipients(Message.RecipientType.BCC, bccAddress);
280                     }
281                     //This code is use to display unicode in Subject
282
//msg.setSubject(MimeUtility.encodeText(subject, "iso-8859-1", "Q"));
283
//msg.setText(message);
284
//String content = new String(message.getBytes(""), "UTF-8");
285
msg.setSubject(subject, "UTF-8");
286                     msg.setText(message, "UTF-8");
287
288                     /*
289                      //Below code is use for unicode
290                      MimeBodyPart messageBodyPart = new MimeBodyPart();
291                      messageBodyPart.setText(message);
292                      messageBodyPart.setHeader("Content-Type", "text/html;charset=iso-8859-1");
293                      messageBodyPart.setHeader("Content-Transfer-Encoding", "quoted-printable");
294                      MimeMultipart multipart = new MimeMultipart("alternative");
295                      multipart.addBodyPart(messageBodyPart);
296                      msg.setContent(multipart);
297                      */

298                     msg.saveChanges();
299
300                     transport.sendMessage(msg, msg.getAllRecipients());
301
302                     // now check if sent 100 emails, then close connection (transport)
303
if ((count % MAX_MESSAGES_PER_TRANSPORT) == 0) {
304                         try {
305                             if (transport != null) transport.close();
306                         } catch (MessagingException ex) {}
307                         transport = null;
308                         session = null;
309                     }
310
311                 } catch (SendFailedException ex) {
312                     sendFailedExceptionCount++;
313                     log.error("SendFailedException has occured.", ex);
314                     log.warn("SendFailedException has occured. Detail info:");
315                     log.warn("from = " + from);
316                     log.warn("to = " + to);
317                     log.warn("cc = " + cc);
318                     log.warn("bcc = " + bcc);
319                     log.warn("subject = " + subject);
320                     log.info("message = " + message);
321                     if ((totalEmails != 1) && (sendFailedExceptionCount > 10)) {
322                         throw ex;// this may look redundant, but it is not :-)
323
}
324                 } catch (MessagingException mex) {
325                     log.error("MessagingException has occured.", mex);
326                     log.warn("MessagingException has occured. Detail info:");
327                     log.warn("from = " + from);
328                     log.warn("to = " + to);
329                     log.warn("cc = " + cc);
330                     log.warn("bcc = " + bcc);
331                     log.warn("subject = " + subject);
332                     log.info("message = " + message);
333                     throw mex;// this may look redundant, but it is not :-)
334
}
335             }//for
336
} finally {
337             try {
338                 if (transport != null) transport.close();
339             } catch (MessagingException ex) { }
340             if (totalEmails != 1) {
341                 log.info("sendMail: totalEmails = " + totalEmails + " sent count = " + count);
342             }
343         }
344     }
345
346     /**
347      * This method trim the email variable, so if it contains only spaces,
348      * then it will be empty string, then we have 0 token :-)
349      * The returned value is never null
350      */

351     public static String JavaDoc[] getEmails(String JavaDoc email) throws BadInputException {
352         if (email == null) email = "";
353         email = email.trim();// very important
354
email = email.replace(',', ';');// replace all occurrence of ',' to ';'
355
StringTokenizer t = new StringTokenizer(email, ";");
356         String JavaDoc[] ret = new String JavaDoc[t.countTokens()];
357         int index = 0;
358         while(t.hasMoreTokens()) {
359             String JavaDoc mail = t.nextToken().trim();
360             checkGoodEmail(mail);
361             ret[index] = mail;
362             //log.debug(ret[index]);
363
index++;
364         }
365         return ret;
366     }
367
368     public static String JavaDoc[] getEmails(String JavaDoc to, String JavaDoc cc, String JavaDoc bcc) throws BadInputException {
369         String JavaDoc[] toMail = getEmails(to);
370         String JavaDoc[] ccMail = getEmails(cc);
371         String JavaDoc[] bccMail= getEmails(bcc);
372         String JavaDoc[] ret = new String JavaDoc[toMail.length + ccMail.length + bccMail.length];
373         int index = 0;
374         for (int i = 0; i < toMail.length; i++) {
375             ret[index] = toMail[i];
376             index++;
377         }
378         for (int i = 0; i < ccMail.length; i++) {
379             ret[index] = ccMail[i];
380             index++;
381         }
382         for (int i = 0; i < bccMail.length; i++) {
383             ret[index] = bccMail[i];
384             index++;
385         }
386         return ret;
387     }
388
389     /**
390      * This method will return null if there is not any email
391      *
392      * @param email
393      * @return
394      * @throws BadInputException
395      * @throws AddressException
396      */

397     private static InternetAddress[] getInternetAddressEmails(String JavaDoc email)
398         throws BadInputException, AddressException {
399         String JavaDoc[] mails = getEmails(email);
400         if (mails.length == 0) return null;// must return null, not empty array
401

402         //log.debug("to = " + mails);
403
InternetAddress[] address = new InternetAddress[mails.length];
404         for (int i = 0; i < mails.length; i++) {
405             address[i] = new InternetAddress(mails[i]);
406             //log.debug("to each element = " + mails[i]);
407
}
408         return address;
409     }
410
411 }
412
Popular Tags