View Javadoc

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     // Static -------------------------------------------------------------------
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     // Attributes ---------------------------------------------------------------
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     // Constructors -------------------------------------------------------------
98  
99     /** Creates a new instance of MailNotifier. */
100    public MailNotifier(){
101    }
102 
103 
104    // Public -------------------------------------------------------------------
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    // Implementation of SubscribersNotifier ------------------------------------
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       // Just delegate to notify() method after having extracted recipients.
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       // Create and initialize a mail sender.
183       JavaMailSenderImpl sender = new JavaMailSenderImpl();
184       sender.setHost(host);
185       sender.setUsername(username);
186       sender.setPassword(password);
187 
188       // Copy title and content as final variables for later access.
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             // Log and wrap as a notification exception.
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             // Log but don't propagate. Maybe a recipient does not exists ?
213             log.error("Exception while sending mail to " + msgRecipient + ". Check recipient existence");
214          }
215          catch (MailException me){
216             // Loag and wrap as a notification exception.
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    // Implementation of Configurable -------------------------------------------
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 }