1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.itracker.services.util;
20
21 import java.io.UnsupportedEncodingException;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Date;
25 import java.util.HashSet;
26 import java.util.Iterator;
27 import java.util.Properties;
28 import java.util.Set;
29
30 import javax.mail.Authenticator;
31 import javax.mail.MessagingException;
32 import javax.mail.PasswordAuthentication;
33 import javax.mail.Session;
34 import javax.mail.Transport;
35 import javax.mail.internet.AddressException;
36 import javax.mail.internet.InternetAddress;
37 import javax.mail.internet.MimeMessage;
38 import javax.naming.InitialContext;
39 import javax.naming.NamingException;
40
41 import org.apache.log4j.Logger;
42 import org.itracker.services.ConfigurationService;
43
44 public class EmailService {
45
46 private ConfigurationService configurationService;
47
48 @Deprecated
49 public static final String DEFAULT_FROM_ADDRESS = "itracker@localhost";
50 @Deprecated
51 public static final String DEFAULT_FROM_TEXT = "ITracker Notification System";
52 @Deprecated
53 public static final String DEFAULT_REPLYTO_ADDRESS = "itracker@localhost";
54 @Deprecated
55 public static final String DEFAULT_SMTP_HOST = "localhost";
56
57 public static final String DEFAULT_SMTP_CHARSET = "ISO-8859-1";
58
59
60
61 private Session session;
62
63 private final Logger logger = Logger.getLogger(EmailService.class);
64 private InternetAddress replyTo;
65 private InternetAddress from;
66
67 public void setConfigurationService(
68 ConfigurationService configurationService) {
69 if (null == configurationService) {
70 throw new IllegalArgumentException("configuration service must not be null.");
71 }
72 if (null != this.configurationService) {
73 throw new IllegalStateException("configuration service was already set.");
74 }
75 this.configurationService = configurationService;
76 }
77
78
79
80 private void initMailsession(String smtpHost, String smtpUserid, String smtpPassword) {
81 Authenticator smtpAuth = null;
82 Properties props = new Properties();
83 props.put("mail.smtp.host", smtpHost);
84
85
86 if (smtpUserid != null && smtpPassword != null) {
87 smtpAuth = (Authenticator) new EmailAuthenticator(
88 new PasswordAuthentication(smtpUserid,
89 smtpPassword));
90 }
91 this.session = Session.getInstance(props, smtpAuth);
92 }
93
94 private final void initCharset(String smtpCharset) {
95 if (null != smtpCharset) {
96 try {
97 new String(new byte[0], smtpCharset);
98 this.session.getProperties().put("mail.mime.charset",
99 smtpCharset);
100 logger.info("initCharset: cherset was initialized to "
101 + session.getProperty("mail.mime.charset"));
102 } catch (UnsupportedEncodingException use) {
103 logger
104 .warn(
105 "initCharset: unsupported smtp charset configured, ignoring",
106 use);
107 }
108 }
109 }
110
111 private final void initFrom(String fromAddress, String fromText) {
112 if (null != fromAddress) {
113 try {
114 this.from = new InternetAddress(fromAddress, fromText, readSmtpCharset(this.session));
115 logger.info("initFrom: initialized from-address: " + this.from);
116 } catch (UnsupportedEncodingException e) {
117 logger.warn("initReplyTo: could not initialize reply-to (configured: " +
118 fromText + " <" + fromAddress + ">" , e);
119 }
120 }
121 }
122
123 private final void initReplyTo(String replyToAddress, String replyToText) {
124 try {
125 this.replyTo = new InternetAddress(replyToAddress, replyToText, readSmtpCharset(this.session));
126 logger.info("initFrom: initialized reply-to: " + this.replyTo);
127 } catch (UnsupportedEncodingException e) {
128 logger.warn("initReplyTo: could not initialize reply-to (configured: " + replyToText + " <" + replyToAddress + ">" , e);
129 }
130 }
131
132
133
134 public void init() {
135
136 if (this.configurationService == null) {
137 throw new IllegalStateException("configuration service was not set.");
138 }
139
140 String fromAddress = configurationService.getProperty(
141 "notification_from_address", DEFAULT_FROM_ADDRESS);
142 String fromText = configurationService.getProperty("notification_from_text",
143 DEFAULT_FROM_TEXT);
144 String replyToAddress = configurationService.getProperty(
145 "notification_replyto_address", DEFAULT_REPLYTO_ADDRESS);
146
147 String smtpCharset = configurationService.getProperty(
148 "notification_smtp_charset", DEFAULT_SMTP_CHARSET);
149
150 String mailSessionLookupName = configurationService.getProperty(
151 "mail_session_jndi_lookup", "none");
152
153 logger
154 .info("init: looking for Session in JNDI, lookup name from configuration: "
155 + mailSessionLookupName);
156
157 try {
158 InitialContext ctx = new InitialContext();
159 logger.debug("init: got Mailsession from Naming Context:" + NamingUtilites.lookup(ctx, mailSessionLookupName));
160
161
162 this.session = (Session) NamingUtilites.lookup(ctx, mailSessionLookupName);
163 } catch (NamingException e) {
164 logger.warn("init: failed to get Mailsession from initial context.", e);
165 }
166 if (null == this.session) {
167 logger
168 .warn("init: failed to lookup Session from JNDI lookup " + mailSessionLookupName + ", using manual session");
169 String smtpHost = configurationService.getProperty(
170 "notification_smtp_host", DEFAULT_SMTP_HOST);
171 String smtpUserid = configurationService.getProperty(
172 "notification_smtp_userid", null);
173 String smtpPassword = configurationService.getProperty(
174 "notification_smtp_password", null);
175
176 logger
177 .warn("init: setting up SMTP manually, no session-lookup found in configuration!");
178 if ("".equals(smtpUserid) || "".equals(smtpPassword)) {
179 smtpUserid = null;
180 smtpPassword = null;
181 }
182 initMailsession(smtpHost, smtpUserid, smtpPassword);
183 initCharset(smtpCharset);
184 initFrom(fromAddress, fromText);
185
186 if (logger.isDebugEnabled()) {
187 logger.debug("init: From Address set to: " + fromAddress);
188 logger.debug("init: From Text set to: " + fromText);
189 logger.debug("init: ReplyTo Address set to: " + replyToAddress);
190 logger.debug("init: SMTP server set to: " + smtpHost);
191 logger.debug("init: SMTP userid set to: " + smtpUserid);
192 logger.debug("init: SMTP password set to: " + smtpPassword);
193 }
194 } else {
195 initCharset(smtpCharset);
196
197 initFrom(fromAddress, fromText);
198 }
199 initReplyTo(replyToAddress, fromText);
200
201
202 }
203
204
205
206
207
208
209
210 public void sendEmail(String address, String subject, String msgText) {
211 try {
212 InternetAddress[] recipients = new InternetAddress[1];
213 recipients[0] = new InternetAddress(address);
214
215 sendEmail(recipients, subject, msgText);
216 } catch (AddressException ex) {
217 logger.warn(
218 "AddressException while sending email. caught. address was "
219 + address, ex);
220 }
221 }
222
223 public void sendEmail(Set<InternetAddress> recipients, String subject,
224 String message) {
225
226 InternetAddress[] recipientsArray = new ArrayList<InternetAddress>(recipients).toArray(new InternetAddress[]{});
227
228 if (recipientsArray.length > 0) {
229 this.sendEmail(recipientsArray, subject, message);
230 }
231
232 }
233
234
235
236
237
238
239
240 public void sendEmail(HashSet<String> addresses, String subject,
241 String msgText) {
242
243 if (null == addresses || 0 == addresses.size()) {
244 throw new IllegalArgumentException(
245 "No addresses in recipients set.");
246 }
247
248 try {
249
250 ArrayList<InternetAddress> recipients = new ArrayList<InternetAddress>(
251 addresses.size());
252
253 Iterator<String> iterator = addresses.iterator();
254 while (iterator.hasNext()) {
255 recipients.add(new InternetAddress((String) iterator.next()));
256 }
257
258 sendEmail(recipients.toArray(new InternetAddress[0]), subject,
259 msgText);
260 } catch (AddressException ex) {
261 logger.warn("AddressException while sending email.", ex);
262 }
263 }
264
265
266
267
268
269
270
271 public void sendEmail(InternetAddress address, String subject,
272 String msgText) {
273 this.sendEmail(new InternetAddress[] { address }, subject, msgText);
274 }
275
276
277
278
279
280
281
282 public void sendEmail(InternetAddress[] recipients, String subject,
283 String msgText) {
284 try {
285 if (logger.isDebugEnabled()) {
286 logger.debug("sendEmail: called with recipients: " + Arrays.asList(recipients) + ", subject: " + subject + ", msgText: " + subject);
287 }
288 if (null == this.session) {
289 throw new IllegalStateException("session was not initialized.");
290 }
291 if (null == recipients || recipients.length < 1) {
292 throw new IllegalArgumentException(
293 "at least one recipient must be specified.");
294 }
295 if (null == subject || subject.length() < 1) {
296 throw new IllegalArgumentException("subject must be specified.");
297 }
298 if (null == msgText) {
299 msgText = "Empty message";
300 }
301
302 MimeMessage msg = new MimeMessage(this.session);
303
304 if(null != this.from ){
305 msg.setFrom(this.from);
306 }
307 if (null != this.replyTo) {
308 msg.setReplyTo(new InternetAddress[] { this.replyTo });
309 }
310 for (InternetAddress internetAddress: recipients) {
311 try {
312 internetAddress.setPersonal(internetAddress.getPersonal(), readSmtpCharset(session));
313 } catch (UnsupportedEncodingException e) {
314 logger.info("sendEmail: could not encode " + internetAddress + " using " + readSmtpCharset(session));
315 }
316 }
317 msg.setRecipients(javax.mail.Message.RecipientType.TO, recipients);
318 msg.setSubject(subject, readSmtpCharset(session));
319
320 msg.setSentDate(new Date());
321
322
323
324 msg.setContent(msgText.toString(), "text/plain; charset=\""
325 + readSmtpCharset(session) + "\"");
326
327 Transport.send(msg);
328
329 } catch (MessagingException me) {
330 logger.warn("MessagingException while sending email, caught.", me);
331 }
332 }
333
334 private String readSmtpCharset(Session session) {
335 String charset = null==session?null:session.getProperty("mail.mime.charset");
336 if (null == charset) {
337 charset = configurationService.getProperty(
338 "notification_smtp_charset", DEFAULT_SMTP_CHARSET);
339 }
340 return charset;
341 }
342 }