1 /**
2 * Copyright 2005-2006 the original author or authors.
3 *
4 * Licensed under the Gnu General Pubic License, Version 2.0 (the
5 * "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/gpl-license.php
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the Gnu General Public License for more details.
14 */
15 package org.figure8.join.services.notification.mail;
16
17 import org.figure8.join.core.ParameterDefinition;
18 import org.figure8.join.core.InvalidParameterException;
19 import org.figure8.join.services.notification.SubscribersNotifier;
20 import org.figure8.join.services.notification.NotificationException;
21 import org.figure8.join.services.remoting.beans.RemoteSubscriber;
22 import org.figure8.join.util.LogUtil;
23
24 import org.apache.commons.logging.Log;
25 import org.springframework.mail.MailException;
26 import org.springframework.mail.MailSendException;
27 import org.springframework.mail.MailAuthenticationException;
28 import org.springframework.mail.javamail.MimeMessageHelper;
29 import org.springframework.mail.javamail.JavaMailSenderImpl;
30 import org.springframework.mail.javamail.MimeMessagePreparator;
31
32 import javax.mail.MessagingException;
33 import javax.mail.internet.MimeMessage;
34
35 import java.util.List;
36 import java.util.Iterator;
37 import java.util.ArrayList;
38 import java.util.Properties;
39 /**
40 * This is an implementation of {@link SubscribersNotifier} using the mail as
41 * notification media.
42 * @author <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
43 * @version $Revision: 1.1 $
44 */
45 public class MailNotifier implements SubscribersNotifier{
46
47
48
49 /** Get a commons logger. */
50 private static final Log log = LogUtil.getLog(MailNotifier.class);
51
52 /** Name of configurable parameter denoting the SMTP host to use. */
53 public static final String HOST_PARAM = "smtpHost";
54 /** Name of configurable parameter denoting the username for connecting to SMTP host. */
55 public static final String USER_PARAM = "smtpUsername";
56 /** Name of configurable parameter denoting the password for connecting to SMTP host. */
57 public static final String PASSWORD_PARAM = "smtpPassword";
58 /** Name of configurable parameter denoting the From address to use in sent messages. */
59 public static final String FROM_PARAM = "fromAddress";
60
61 /** List of {@link ParameterDefinition}s supported by this adapter */
62 protected static List parameters = new ArrayList();
63
64 /** ParameterDefinition representation of parameter denoting the SMTP host to use. */
65 protected static final ParameterDefinition hostParam = new ParameterDefinition(HOST_PARAM,
66 "The SMTP host to use for sending mail messages", "smpt.mycompany.com", true);
67 /** ParameterDefintion representation of paramter denoting the username of SMTP host. */
68 protected static final ParameterDefinition userParam = new ParameterDefinition(USER_PARAM,
69 "The username for connecting to SMTP host", "username", false);
70 /** ParameterDefinition representation of parameter denoting the password of SMTP host. */
71 protected static final ParameterDefinition pwdParam = new ParameterDefinition(PASSWORD_PARAM,
72 "The password for connecting to SMTP host", "password", false);
73 /** ParameterDefinition representation of parameter denoting the From address to use. */
74 protected static final ParameterDefinition fromParam = new ParameterDefinition(FROM_PARAM,
75 "The 'From' address that appears in sent messages", "integrationservice@mycompany.com", true);
76
77 static{
78 parameters.add(hostParam);
79 parameters.add(userParam);
80 parameters.add(pwdParam);
81 parameters.add(fromParam);
82 }
83
84
85
86
87 /** The SMTP host to use for sending messages. */
88 private String host = null;
89 /** The username for connecting to SMTP host. */
90 private String username = null;
91 /** The password for connecting to SMTP host. */
92 private String password = null;
93 /** The From address that appears on sent messages. */
94 private String from = null;
95
96
97
98
99 /** Creates a new instance of MailNotifier. */
100 public MailNotifier(){
101 }
102
103
104
105
106 /** @return The SMTP host to use for sending messages. */
107 public String getHost(){
108 return host;
109 }
110 /** @param host The SMTP host to use for sending messages. */
111 public void setHost(String host){
112 this.host = host;
113 }
114 /** @return The username for connecting to SMTP host. */
115 public String getUsername(){
116 return username;
117 }
118 /** @param username The username for connecting to SMTP host. */
119 public void setUsername(String username){
120 this.username = username;
121 }
122 /** @return The password for connecting to SMTP host. */
123 public String getPassword(){
124 return password;
125 }
126 /** @param password The password for connecting to SMTP host. */
127 public void setPassword(String password){
128 this.password = password;
129 }
130 /** @return The From address that appears on sent messages. */
131 public String getFrom(){
132 return from;
133 }
134 /** @param from The From address that appears on sent messages. */
135 public void setFrom(String from){
136 this.from = from;
137 }
138
139
140
141
142 /**
143 * Extract mail addresses for subscribers to provide recipients.
144 * @param subscribers The subscribers to get recipients for
145 * @return The list of corresponding recipients.
146 */
147 public String[] extractRecipients(RemoteSubscriber[] subscribers){
148 String[] recipients = new String[subscribers.length];
149 for (int i=0; i<subscribers.length; i++){
150 recipients[i] = subscribers[i].getMailAddress();
151 }
152 return recipients;
153 }
154
155 /**
156 * Notify subscribers of mailing list defined into Join application
157 * @param subscribers The subscriber of mailing list to notify
158 * @param title The title of notification message to send
159 * @param content The content of notification message to send
160 * @throws NotificationException if an exception occurs during the notification operation
161 * (usually they are network related exceptions)
162 */
163 public void notify(RemoteSubscriber[] subscribers, String title, String content) throws NotificationException{
164
165 notify(extractRecipients(subscribers), title, content);
166 }
167
168 /**
169 * Notifier are able to notify recipients and use a title and a content within
170 * their notification messages. The definition of a recipients is voluntary abstract
171 * letting implementations or sub-interfaces defining what they consider as valid
172 * recipients (ex: mail addresses, IM identifies, etc...)
173 * @param recipients An array of recipients to noitify. Recipient is described with a String
174 * @param title The title of notification message to send
175 * @param content The content of notification message to send
176 * @throws NotificationException if an exception occurs during the notification operation
177 * (usually they are network related exceptions)
178 */
179 public void notify(String[] recipients, String title, String content) throws NotificationException{
180 if (log.isDebugEnabled())
181 log.debug("Notifying recipients using " + host + " with " + username + "/" + password + " credentials");
182
183 JavaMailSenderImpl sender = new JavaMailSenderImpl();
184 sender.setHost(host);
185 sender.setUsername(username);
186 sender.setPassword(password);
187
188
189 final String msgTitle = title;
190 final String msgContent = content;
191
192 for (int i=0; i<recipients.length; i++){
193 final String msgRecipient = recipients[i];
194 log.debug("Sending mail message to " + msgRecipient);
195 try{
196 sender.send(new MimeMessagePreparator(){
197 public void prepare(MimeMessage mimeMessage) throws MessagingException {
198 MimeMessageHelper message = new MimeMessageHelper(mimeMessage, true, "UTF-8");
199 message.setFrom(from);
200 message.setTo(msgRecipient);
201 message.setSubject(msgTitle);
202 message.setText(msgContent, msgContent);
203 }
204 });
205 }
206 catch (MailAuthenticationException mae){
207
208 log.error("Authentication exception while sending mails with " + host + ": " + mae.getMessage());
209 throw new NotificationException("Authentication exception while sending mails", mae);
210 }
211 catch (MailSendException mse){
212
213 log.error("Exception while sending mail to " + msgRecipient + ". Check recipient existence");
214 }
215 catch (MailException me){
216
217 log.error("MailException while sending mails with " + host + ": " + me.getMessage());
218 throw new NotificationException("MailException while sending mails", me);
219 }
220 }
221 }
222
223
224
225
226 /**
227 * Get this object parameters definitions as a list
228 * @return A list of {@code ParameterDefinition} objects
229 */
230 public List getParameterDefinitionsAsList(){
231 return parameters;
232 }
233
234 /**
235 * Get this object parameters definitions as an array
236 * @return An array of {@code ParameterDefinition} objects
237 */
238 public ParameterDefinition[] getParameterDefinitions(){
239 List result = getParameterDefinitionsAsList();
240 return (ParameterDefinition[])result.toArray(new ParameterDefinition[result.size()]);
241 }
242
243 /**
244 * Set the value of a parameter using its nama
245 * @param parameterName The name of parameter so set value for
246 * @param parameterValue The value of the paramater
247 * @throws org.figure8.join.core.InvalidParameterException if this parameter is not supported by this object
248 */
249 public void setParameter(String parameterName, String parameterValue) throws InvalidParameterException{
250 if (HOST_PARAM.equals(parameterName))
251 setHost(parameterValue);
252 else if (USER_PARAM.equals(parameterName))
253 setUsername(parameterValue);
254 else if (PASSWORD_PARAM.equals(parameterName))
255 setPassword(parameterValue);
256 else if (FROM_PARAM.equals(parameterName))
257 setFrom(parameterValue);
258 else{
259 log.error("The parameter '" + parameterName + "' is not supported by MailNotifier");
260 throw new InvalidParameterException("The parameter '" + parameterName + "' is not supported by MailNotifier");
261 }
262 }
263
264 /**
265 * Set the value of a parameter using its definitions
266 * @param parameter The definitino of the paramater to set
267 * @param parameterValue The value of the parameter
268 * @throws InvalidParameterException if this parameter is not supported by this object
269 */
270 public void setParameter(ParameterDefinition parameter, String parameterValue) throws InvalidParameterException{
271 setParameter(parameter.getName(), parameterValue);
272 }
273
274 /**
275 * Convenient methods for setting all attributes values using a single method.
276 * @param parameters Properties where keys are parameter names
277 * @throws InvalidParameterException if one of these parameters is not supported by this object
278 */
279 public void setParameters(Properties parameters) throws InvalidParameterException{
280 Iterator keys = parameters.keySet().iterator();
281 while (keys != null && keys.hasNext()){
282 String parameterName = (String)keys.next();
283 String parameterValue = parameters.getProperty(parameterName);
284 setParameter(parameterName, parameterValue);
285 }
286 }
287 }