1
2
3
4
5
6
7
8
9
10
11 package psiprobe.tools;
12
13 import jakarta.activation.DataHandler;
14 import jakarta.activation.DataSource;
15 import jakarta.mail.Message;
16 import jakarta.mail.MessagingException;
17 import jakarta.mail.Part;
18 import jakarta.mail.Session;
19 import jakarta.mail.Transport;
20 import jakarta.mail.internet.AddressException;
21 import jakarta.mail.internet.InternetAddress;
22 import jakarta.mail.internet.MimeBodyPart;
23 import jakarta.mail.internet.MimeMessage;
24 import jakarta.mail.internet.MimeMultipart;
25
26 import java.io.PrintStream;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.List;
30 import java.util.Properties;
31
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34 import org.springframework.beans.factory.annotation.Value;
35
36
37
38
39 public class Mailer {
40
41
42 public static final String PROPERTY_KEY_SMTP = "mail.smtp.host";
43
44
45 private static final Logger logger = LoggerFactory.getLogger(Mailer.class);
46
47
48 private String from;
49
50
51 private String smtp;
52
53
54 private String defaultTo;
55
56
57 private String subjectPrefix;
58
59
60
61
62 public Mailer() {
63 this(null);
64 }
65
66
67
68
69
70
71 public Mailer(String from) {
72 this(from, null);
73 }
74
75
76
77
78
79
80
81 public Mailer(String from, String smtp) {
82 this.smtp = smtp;
83 this.from = from;
84 }
85
86
87
88
89
90
91 public String getFrom() {
92 return from;
93 }
94
95
96
97
98
99
100 public String getSmtp() {
101 if (smtp == null) {
102 return System.getProperty(PROPERTY_KEY_SMTP);
103 }
104 return smtp;
105 }
106
107
108
109
110
111
112 public void setFrom(String from) {
113 this.from = from;
114 }
115
116
117
118
119
120
121 public void setSmtp(String smtp) {
122 this.smtp = smtp;
123 }
124
125
126
127
128
129
130 public String getDefaultTo() {
131 return defaultTo;
132 }
133
134
135
136
137
138
139 @Value("${psiprobe.tools.mail.to}")
140 public void setDefaultTo(String defaultTo) {
141 this.defaultTo = defaultTo;
142 }
143
144
145
146
147
148
149 public String getSubjectPrefix() {
150 return subjectPrefix;
151 }
152
153
154
155
156
157
158 @Value("${psiprobe.tools.mail.subjectPrefix}")
159 public void setSubjectPrefix(String subjectPrefix) {
160 this.subjectPrefix = subjectPrefix;
161 }
162
163
164
165
166
167
168
169
170 public void send(MailMessage mailMessage) throws MessagingException {
171 Properties props = (Properties) System.getProperties().clone();
172 if (smtp != null) {
173 props.put(PROPERTY_KEY_SMTP, smtp);
174 }
175
176 try (PrintStream debugOut =
177 LogOutputStream.createPrintStream(logger, LogOutputStream.LEVEL_DEBUG)) {
178 Session session = Session.getDefaultInstance(props);
179 session.setDebug(true);
180 session.setDebugOut(debugOut);
181
182 MimeMessage message = createMimeMessage(session, mailMessage);
183 logger.debug("Sending message");
184 Transport.send(message);
185 }
186 }
187
188
189
190
191
192
193
194
195
196
197
198 private MimeMessage createMimeMessage(Session session, MailMessage mailMessage)
199 throws MessagingException {
200
201 String subject = mailMessage.getSubject();
202 if (subjectPrefix != null && !subjectPrefix.isEmpty()) {
203 subject = subjectPrefix + " " + subject;
204 }
205
206 MimeMultipart content = new MimeMultipart("related");
207
208
209 DataSource[] attachments = mailMessage.getAttachmentsArray();
210 for (DataSource attachment : attachments) {
211 MimeBodyPart attachmentPart = createAttachmentPart(attachment);
212 content.addBodyPart(attachmentPart);
213 }
214
215
216 MimeBodyPart bodyPart = createMessageBodyPart(mailMessage.getBody(), mailMessage.isBodyHtml());
217 content.addBodyPart(bodyPart);
218
219 MimeMessage message = new MimeMessage(session);
220 if (from == null) {
221
222 message.setFrom();
223 } else {
224 message.setFrom(new InternetAddress(from));
225 }
226
227 InternetAddress[] to = createAddresses(mailMessage.getToArray());
228 if (to.length == 0) {
229 to = InternetAddress.parse(defaultTo);
230 }
231 message.setRecipients(Message.RecipientType.TO, to);
232
233 InternetAddress[] cc = createAddresses(mailMessage.getCcArray());
234 message.setRecipients(Message.RecipientType.CC, cc);
235
236 InternetAddress[] bcc = createAddresses(mailMessage.getBccArray());
237 message.setRecipients(Message.RecipientType.BCC, bcc);
238
239 message.setSubject(subject);
240 message.setContent(content);
241 return message;
242 }
243
244
245
246
247
248
249
250
251
252
253 private static InternetAddress[] createAddresses(String[] addresses) throws AddressException {
254 List<InternetAddress> result = new ArrayList<>(addresses.length);
255 for (String address : addresses) {
256 InternetAddress[] parsedAddresses = InternetAddress.parse(address);
257 result.addAll(Arrays.asList(parsedAddresses));
258 }
259 return result.toArray(new InternetAddress[result.size()]);
260 }
261
262
263
264
265
266
267
268
269
270
271 private static MimeBodyPart createAttachmentPart(DataSource attachment)
272 throws MessagingException {
273
274 MimeBodyPart attachmentPart = new MimeBodyPart();
275 attachmentPart.setDataHandler(new DataHandler(attachment));
276 attachmentPart.setDisposition(Part.ATTACHMENT);
277 attachmentPart.setFileName(attachment.getName());
278 return attachmentPart;
279 }
280
281
282
283
284
285
286
287
288
289
290
291 private static MimeBodyPart createMessageBodyPart(String body, boolean html)
292 throws MessagingException {
293 MimeBodyPart bodyPart = new MimeBodyPart();
294 bodyPart.setText(body);
295 bodyPart.setHeader("content-type", html ? "text/html" : "text/plain");
296 return bodyPart;
297 }
298
299 }