KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > info > jtrac > mail > MailSender


1 /*
2  * Copyright 2002-2005 the original author or authors.
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 info.jtrac.mail;
18
19 import info.jtrac.domain.Item;
20 import info.jtrac.domain.ItemUser;
21 import info.jtrac.domain.User;
22 import info.jtrac.util.ItemUtils;
23 import java.util.Date JavaDoc;
24 import java.util.Enumeration JavaDoc;
25 import java.util.Locale JavaDoc;
26 import java.util.Map JavaDoc;
27 import java.util.Properties JavaDoc;
28 import javax.mail.Header JavaDoc;
29 import javax.mail.internet.MimeMessage JavaDoc;
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.springframework.context.MessageSource;
33 import org.springframework.mail.javamail.JavaMailSenderImpl;
34 import org.springframework.mail.javamail.MimeMessageHelper;
35 import org.springframework.util.StringUtils;
36
37 /**
38  * Class to handle sending of E-mail and pre-formatted messages
39  */

40 public class MailSender {
41     
42     private final Log logger = LogFactory.getLog(getClass());
43     private JavaMailSenderImpl sender;
44     private String JavaDoc prefix;
45     private String JavaDoc from;
46     private String JavaDoc url;
47     private MessageSource messageSource;
48     private Locale JavaDoc defaultLocale;
49     
50     public MailSender(Map JavaDoc<String JavaDoc, String JavaDoc> config, MessageSource messageSource, String JavaDoc defaultLocale) {
51         // initialize email sender
52
this.messageSource = messageSource;
53         this.defaultLocale = StringUtils.parseLocaleString(defaultLocale);
54         String JavaDoc host = config.get("mail.server.host");
55         if (host == null) {
56             logger.warn("'mail.server.host' config is null, mail adapter not initialized");
57             return;
58         }
59         String JavaDoc port = config.get("mail.server.port");
60         String JavaDoc url = config.get("jtrac.url.base");
61         from = config.get("mail.from");
62         prefix = config.get("mail.subject.prefix");
63         String JavaDoc userName = config.get("mail.server.username");
64         String JavaDoc password = config.get("mail.server.password");
65         String JavaDoc startTls = config.get("mail.server.starttls.enable");
66         logger.debug("initializing email adapter: host = '" + host + "', port = '" +
67                 port + "', url = '" + url + "', from = '" + from + "', prefix = '" + prefix + "'");
68         this.prefix = prefix == null ? "[jtrac]" : prefix;
69         this.from = from == null ? "jtrac" : from;
70         this.url = url == null ? "http://localhost/jtrac/" : url;
71         if (!this.url.endsWith("/")) {
72             this.url = url + "/";
73         }
74         int p = 25;
75         if (port != null) {
76            try {
77                p = Integer.parseInt(port);
78            } catch (NumberFormatException JavaDoc e) {
79                logger.warn("mail.server.port not an integer : '" + port + "', defaulting to 25");
80            }
81         }
82         sender = new JavaMailSenderImpl();
83         sender.setHost(host);
84         sender.setPort(p);
85         if (userName != null) {
86             // authentication requested
87
Properties JavaDoc props = new Properties JavaDoc();
88             props.put("mail.smtp.auth", "true");
89             if (startTls != null && startTls.toLowerCase().equals("true")) {
90                 props.put("mail.smtp.starttls.enable", "true");
91             }
92             sender.setJavaMailProperties(props);
93             sender.setUsername(userName);
94             sender.setPassword(password);
95         }
96         logger.info("email sender initialized: host = '" + host + "', port = '" + p + "'");
97     }
98
99     /**
100      * we bend the rules a little and fire off a new thread for sending
101      * an email message. This has the advantage of not slowing down the item
102      * create and update screens, i.e. the system returns the next screen
103      * after "submit" without blocking. This has been used in production
104      * for quite a while now, on Tomcat without any problems. This helps a lot
105      * especially when the SMTP server is slow to respond, etc.
106      */

107     private void sendInNewThread(final MimeMessage JavaDoc message) {
108         new Thread JavaDoc(){
109             public void run() {
110                 logger.debug("send mail thread start");
111                 try {
112                     sender.send(message);
113                     logger.debug("send mail thread successfull");
114                 } catch (Exception JavaDoc e) {
115                     logger.error("send mail thread failed", e);
116                     logger.error("mail headers dump start");
117                     try {
118                         Enumeration JavaDoc headers = message.getAllHeaders();
119                         while(headers.hasMoreElements()) {
120                             Header JavaDoc h = (Header JavaDoc) headers.nextElement();
121                             logger.info(h.getName() + ": " + h.getValue());
122                         }
123                     } catch (Exception JavaDoc f) {
124                         // :(
125
}
126                     logger.error("mail headers dump end");
127                 }
128             }
129         }.start();
130     }
131     
132     private String JavaDoc fmt(String JavaDoc key, Locale JavaDoc locale) {
133         try {
134             return messageSource.getMessage("mail_sender." + key, null, locale);
135         } catch (Exception JavaDoc e) {
136             logger.debug(e);
137             return "???mail_sender." + key + "???";
138         }
139     }
140
141     private String JavaDoc addHeaderAndFooter(StringBuffer JavaDoc html) {
142         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
143         // additional cosmetic tweaking of e-mail layout
144
// style just after the body tag does not work for a minority of clients like gmail, thunderbird etc.
145
// ItemUtils adds the main inline CSS when generating the email content, so we gracefully degrade
146
sb.append("<html><body><style type='text/css'>table.jtrac th, table.jtrac td { padding-left: 0.2em; padding-right: 0.2em; }</style>");
147         sb.append(html);
148         sb.append("<hr/></html>");
149         return sb.toString();
150     }
151     
152     private String JavaDoc getItemViewAnchor(Item item, Locale JavaDoc locale) {
153         return "<p><a HREF='" + url + "flow/item_view?itemId=" + item.getId() + "'>"
154                 + fmt("clickHereToAccess", locale) + " " + item.getRefId() + "</a></p>";
155     }
156     
157     private String JavaDoc getSubject(Item item) {
158         String JavaDoc summary = null;
159         if (item.getSummary() == null) {
160             summary = "";
161         } else if (item.getSummary().length() > 80) {
162             summary = item.getSummary().substring(0, 80);
163         } else {
164             summary = item.getSummary();
165         }
166         return prefix + " #" + item.getRefId() + " " + summary;
167     }
168     
169     public void send(Item item, MessageSource messageSource) {
170         if (sender == null) {
171             logger.debug("mail sender is null, not sending notifications");
172             return;
173         }
174         // TODO make this locale sensitive per recipient
175
logger.debug("attempting to send mail for item update");
176         // prepare message content
177
StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
178         String JavaDoc anchor = getItemViewAnchor(item, defaultLocale);
179         sb.append(anchor);
180         sb.append(ItemUtils.getAsHtml(item, messageSource, defaultLocale));
181         sb.append(anchor);
182         if (logger.isDebugEnabled()) {
183             logger.debug("html content: " + sb);
184         }
185         // prepare message
186
MimeMessage JavaDoc message = sender.createMimeMessage();
187         MimeMessageHelper helper = new MimeMessageHelper(message, "UTF-8");
188         try {
189             helper.setText(addHeaderAndFooter(sb), true);
190             helper.setSubject(getSubject(item));
191             helper.setSentDate(new Date JavaDoc());
192             helper.setFrom(from);
193             // set TO
194
if (item.getAssignedTo() != null) {
195                 helper.setTo(item.getAssignedTo().getEmail());
196             } else {
197                 helper.setTo(item.getLoggedBy().getEmail());
198             }
199             // set CC
200
if (item.getItemUsers() != null) {
201                 String JavaDoc[] cc = new String JavaDoc[item.getItemUsers().size()];
202                 int i = 0;
203                 for (ItemUser itemUser : item.getItemUsers()) {
204                     cc[i++] = itemUser.getUser().getEmail();
205                 }
206                 helper.setCc(cc);
207             }
208             // send message
209
sendInNewThread(message);
210         } catch (Exception JavaDoc e) {
211             logger.error("failed to prepare e-mail", e);
212         }
213     }
214     
215     public void sendUserPassword(User user, String JavaDoc clearText) {
216         if (sender == null) {
217             logger.debug("mail sender is null, not sending new user / password change notification");
218             return;
219         }
220         logger.debug("attempting to send mail for user password");
221         String JavaDoc localeString = user.getLocale();
222         Locale JavaDoc locale = null;
223         if(localeString == null) {
224             locale = defaultLocale;
225         } else {
226             locale = StringUtils.parseLocaleString(localeString);
227         }
228         MimeMessage JavaDoc message = sender.createMimeMessage();
229         MimeMessageHelper helper = new MimeMessageHelper(message, "UTF-8");
230         try {
231             helper.setTo(user.getEmail());
232             helper.setSubject(prefix + " " + fmt("loginMailSubject", locale));
233             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
234             sb.append("<p>" + fmt("loginMailGreeting", locale) + " " + user.getName()+ ",</p>");
235             sb.append("<p>" + fmt("loginMailLine1", locale) + "</p>");
236             sb.append("<table class='jtrac'>");
237             sb.append("<tr><th style='background: #CCCCCC'>" + fmt("loginName", locale)
238                 + "</th><td style='border: 1px solid black'>" + user.getLoginName() + "</td></tr>");
239             sb.append("<tr><th style='background: #CCCCCC'>" + fmt("password", locale)
240                 + "</th><td style='border: 1px solid black'>" + clearText + "</td></tr>");
241             sb.append("</table>");
242             sb.append("<p>" + fmt("loginMailLine2", locale) + "</p>");
243             sb.append("<p><a HREF='" + url + "'>" + url + "</a></p>");
244             helper.setText(addHeaderAndFooter(sb), true);
245             helper.setSentDate(new Date JavaDoc());
246             helper.setCc(from);
247             helper.setFrom(from);
248             sendInNewThread(message);
249         } catch (Exception JavaDoc e) {
250             logger.error("failed to prepare e-mail", e);
251         }
252     }
253     
254 }
255
Popular Tags