1 package org.argeo.connect.mail;
2
3 import java.util.Map;
4 import java.util.Properties;
5
6 import javax.mail.Authenticator;
7 import javax.mail.Message;
8 import javax.mail.MessagingException;
9 import javax.mail.Multipart;
10 import javax.mail.PasswordAuthentication;
11 import javax.mail.Session;
12 import javax.mail.Transport;
13 import javax.mail.internet.InternetAddress;
14 import javax.mail.internet.MimeBodyPart;
15 import javax.mail.internet.MimeMessage;
16 import javax.mail.internet.MimeMultipart;
17
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20 import org.argeo.connect.ConnectException;
21 import org.argeo.eclipse.ui.EclipseUiUtils;
22
23
24 public class SendMail implements Runnable {
25 private final static Log log = LogFactory.getLog(SendMail.class);
26
27
28
29
30
31
32
33 public final static String ARGEO_SEND_MAILS = "org.argeo.connect.mail.dosend";
34 private final static String ARGEO_SMTP_TLS_DEBUG = "org.argeo.connect.smtp.tls.debug";
35 private final static String DEFAULT_ENCODING = "UTF-8";
36
37 private final static boolean sendingActive = Boolean.parseBoolean(System.getProperty(ARGEO_SEND_MAILS, "true"));
38
39 private String host;
40 private String port;
41 private String from;
42 private String to;
43 private String subject;
44 private String plainText;
45 private String htmlText;
46 private String username;
47 private String password;
48
49 public void run() {
50
51
52 if (!sendingActive)
53 traceUnsentMail();
54 else {
55 if ("smtp.gmail.com".equals(host))
56 sendWithGMail();
57 else
58 sendWithJavaSmtp();
59 }
60 }
61
62 protected void sendWithJavaSmtp() {
63
64
65
66 String doDebugStr = System.getProperty(ARGEO_SMTP_TLS_DEBUG);
67 boolean debug = "true".equals(doDebugStr);
68
69 boolean auth = true;
70 Properties props = new Properties();
71 props.put("mail.smtp.host", host);
72 props.put("mail.smtp.port", port);
73
74 props.put("mail.smtp.starttls.enable", false);
75
76
77
78
79
80
81
82
83
84
85
86
87 Authenticator authenticator = null;
88 if (auth) {
89 props.put("mail.smtp.auth", true);
90 authenticator = new Authenticator() {
91 private PasswordAuthentication pa = new PasswordAuthentication(username, password);
92
93 @Override
94 public PasswordAuthentication getPasswordAuthentication() {
95 return pa;
96 }
97 };
98 }
99 Session session = Session.getInstance(props, authenticator);
100 session.setDebug(debug);
101 MimeMessage message = new MimeMessage(session);
102 try {
103 buildJavaMailMessage(message);
104 Transport.send(message);
105 } catch (MessagingException ex) {
106 throw new ConnectException("Unable to send java tls mail to " + to + " with username: " + username, ex);
107 }
108 }
109
110 protected void sendWithGMail() {
111 try {
112 Properties props = new Properties();
113 props.put("mail.smtps.auth", "true");
114 props.put("mail.smtps.host", host);
115 props.put("mail.smtp.starttls.enable", true);
116 Session session = Session.getDefaultInstance(props, null);
117 MimeMessage message = new MimeMessage(session);
118 buildJavaMailMessage(message);
119 Transport t = session.getTransport("smtps");
120 try {
121 t.connect(host, username, password);
122 t.sendMessage(message, message.getAllRecipients());
123 } finally {
124 t.close();
125 }
126 if (log.isDebugEnabled())
127 log.debug("Sent mail to " + to + " with Google Mail");
128 } catch (Exception e) {
129 throw new ConnectException("Cannot send message.", e);
130 }
131 }
132
133 protected void buildJavaMailMessage(MimeMessage message) throws MessagingException {
134 message.setFrom(new InternetAddress(from));
135 InternetAddress toAddr = new InternetAddress(to);
136 message.setRecipient(Message.RecipientType.TO, toAddr);
137 message.setSubject(subject, DEFAULT_ENCODING);
138 if (EclipseUiUtils.notEmpty((htmlText))) {
139 Multipart multipart = new MimeMultipart("alternative");
140
141 MimeBodyPart textPart = new MimeBodyPart();
142 textPart.setText(htmlText, DEFAULT_ENCODING);
143
144 MimeBodyPart htmlPart = new MimeBodyPart();
145 htmlPart.setText(htmlText, DEFAULT_ENCODING, "html");
146
147 multipart.addBodyPart(textPart);
148 multipart.addBodyPart(htmlPart);
149 message.setContent(multipart);
150 } else
151 message.setText(plainText, DEFAULT_ENCODING);
152 }
153
154
155
156
157
158
159 public void setMailConfig(Map<String, String> mailConfig) {
160 host = mailConfig.get(MailProperty.host.name());
161 port = mailConfig.get(MailProperty.port.name());
162 from = mailConfig.get(MailProperty.from.name());
163 to = mailConfig.get(MailProperty.to.name());
164 subject = mailConfig.get(MailProperty.subject.name());
165 plainText = mailConfig.get(MailProperty.plainText.name());
166 htmlText = mailConfig.get(MailProperty.htmlText.name());
167 username = mailConfig.get(MailProperty.username.name());
168 password = mailConfig.get(MailProperty.password.name());
169 }
170
171 public void setHost(String host) {
172 this.host = host;
173 }
174
175 public void setFrom(String from) {
176 this.from = from;
177 }
178
179 public void setTo(String to) {
180 this.to = to;
181 }
182
183 public void setSubject(String subject) {
184 this.subject = subject;
185 }
186
187 public void setPlainText(String plainText) {
188 this.plainText = plainText;
189 }
190
191 public void setHtmlText(String htmlText) {
192 this.htmlText = htmlText;
193 }
194
195 public void setUsername(String username) {
196 this.username = username;
197 }
198
199 public void setPassword(String password) {
200 this.password = password;
201 }
202
203 private void traceUnsentMail() {
204 StringBuilder builder = new StringBuilder();
205 builder.append("*** MAIL NOT SENT *** ");
206 builder.append("This message should have been sent but mail sending is disabled.\n");
207 builder.append(logMail(false));
208 log.info(builder.toString());
209 }
210
211 public String logMail(boolean html) {
212 StringBuilder builder = new StringBuilder();
213 if (!html) {
214 builder.append("From: ").append(from);
215 builder.append(" - To: ").append(to);
216 builder.append("- Subject: ").append(subject).append("\n");
217 builder.append("Body: \n");
218 }
219 builder.append(html ? htmlText : plainText);
220 return builder.toString();
221 }
222
223 public static boolean isSendingActive() {
224 return sendingActive;
225 }
226
227 }