1. Project Clover database Mon Dec 22 2025 14:59:38 CST
  2. Package org.europa.together.application

File JakartaMailClient.java

 

Coverage histogram

../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

30
121
15
1
292
260
32
0.26
8.07
15
2.13

Classes

Class Line # Actions
JakartaMailClient 40 121 0% 32 1
0.993975999.4%
 

Contributing tests

This file is covered by 18 tests. .

Source view

1    package org.europa.together.application;
2   
3    import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
4    import jakarta.activation.DataHandler;
5    import jakarta.activation.DataSource;
6    import jakarta.mail.MessagingException;
7    import jakarta.mail.Multipart;
8    import jakarta.mail.NoSuchProviderException;
9    import jakarta.mail.PasswordAuthentication;
10    import jakarta.mail.Session;
11    import jakarta.mail.internet.InternetAddress;
12    import jakarta.mail.internet.MimeBodyPart;
13    import jakarta.mail.internet.MimeMessage;
14    import jakarta.mail.internet.MimeMultipart;
15    import java.io.IOException;
16    import java.util.Date;
17    import java.util.HashMap;
18    import java.util.List;
19    import java.util.Map;
20    import java.util.Properties;
21    import jakarta.activation.FileDataSource;
22    import org.europa.together.business.ConfigurationDAO;
23    import org.europa.together.business.CryptoTools;
24    import org.europa.together.business.Logger;
25    import org.europa.together.business.MailClient;
26    import org.europa.together.business.PropertyReader;
27    import org.europa.together.domain.ConfigurationDO;
28    import org.europa.together.domain.HashAlgorithm;
29    import org.europa.together.domain.LogLevel;
30    import org.europa.together.domain.Mail;
31    import org.europa.together.utils.Constraints;
32    import org.europa.together.utils.StringUtils;
33    import org.springframework.beans.factory.annotation.Autowired;
34    import org.springframework.stereotype.Repository;
35   
36    /**
37    * Implementation of a simple SMTP Mailer.
38    */
39    @Repository
 
40    public class JakartaMailClient implements MailClient {
41   
42    private static final long serialVersionUID = 6L;
43    private static final Logger LOGGER = new LogbackLogger(JakartaMailClient.class);
44   
45    @Autowired
46    private ConfigurationDAO configurationDAO;
47    @Autowired
48    private CryptoTools cryptoTools;
49    @Autowired
50    private PropertyReader propertyReader;
51   
52    private Map<String, String> configuration;
53    private MimeMessage message;
54    private Mail email;
55    private int configMaximumMailBulk;
56    private long configCountWaitTime;
57   
58    /**
59    * Constructor.
60    */
 
61  3 toggle public JakartaMailClient() {
62  3 initConfig();
63  3 configMaximumMailBulk = -1;
64  3 configCountWaitTime = -1;
65  3 LOGGER.log("instance class", LogLevel.INFO);
66    }
67   
 
68  19 toggle @Override
69    public Map<String, String> getDebugActiveConfiguration() {
70  19 return Map.copyOf(configuration);
71    }
72   
 
73  3 toggle @Override
74    public void clearConfiguration() {
75  3 configuration.clear();
76    }
77   
 
78  8 toggle @Override
79    public boolean loadConfigurationFromProperties(final String resource)
80    throws IOException {
81  8 boolean success = true;
82  8 initConfig();
83  8 Map<String, String> properties = new HashMap<>();
84  8 try {
85  8 propertyReader.appendPropertiesFromClasspath(resource);
86  6 properties = propertyReader.getPropertyList();
87    } catch (Exception ex) {
88  2 success = false;
89  2 LOGGER.catchException(ex);
90    }
91   
92  8 try {
93  8 propertyReader.appendPropertiesFromFile(resource);
94  1 properties = propertyReader.getPropertyList();
95    } catch (Exception ex) {
96  7 success = false;
97  7 LOGGER.catchException(ex);
98    }
99   
100  8 if (!properties.isEmpty()) {
101  7 configuration.putAll(properties);
102    } else {
103  1 success = false;
104  1 throw new IOException("Could not load " + resource + " from file system or classpath.");
105    }
106  7 return success;
107    }
108   
 
109  7 toggle @Override
110    public boolean loadConfigurationFromDatabase() {
111  7 boolean success = false;
112  7 initConfig();
113  7 LOGGER.log("Load all configuration sets of: " + CONFIG_SET
114    + " - Version: " + CONFIG_VERSION
115    + " - Module: " + Constraints.MODULE_NAME, LogLevel.DEBUG);
116  7 List<ConfigurationDO> configurationEntries
117    = configurationDAO.getAllConfigurationSetEntries(Constraints.MODULE_NAME,
118    CONFIG_VERSION, CONFIG_SET);
119  7 LOGGER.log("Size of config SET: " + configurationEntries.size(), LogLevel.DEBUG);
120  7 if (configurationEntries.size() > 0) {
121  6 processConfiguration(configurationEntries);
122  6 success = true;
123    }
124  7 LOGGER.log("DB CONFIG: " + configuration, LogLevel.DEBUG);
125  7 return success;
126    }
127   
 
128  2 toggle @Override
129    public int getBulkMailLimiter() {
130  2 return this.configMaximumMailBulk;
131    }
132   
 
133  2 toggle @Override
134    public long getWaitTime() {
135  2 return this.configCountWaitTime;
136    }
137   
 
138  6 toggle @Override
139    public void composeMail(final Mail email)
140    throws MessagingException {
141  6 MimeMessage mimeMessage = null;
142  6 LOGGER.log("Compose E-Mail", LogLevel.DEBUG);
143  6 mimeMessage = new MimeMessage(getSession());
144    //HEADER - EVENLOPE
145  6 mimeMessage.setHeader("From: ", configuration.get("mailer.sender"));
146  6 mimeMessage.setHeader("Return-Path: ", configuration.get("mailer.sender"));
147  6 mimeMessage.setSentDate(new Date());
148  6 mimeMessage.setSubject(email.getSubject());
149  6 mimeMessage.setFrom(new InternetAddress(configuration.get("mailer.sender")));
150  6 mimeMessage.setSender(new InternetAddress(configuration.get("mailer.sender")));
151  6 LOGGER.log("E-Mail {evenlope} done", LogLevel.DEBUG);
152    // CONTENT
153  6 MimeBodyPart bodypart = new MimeBodyPart();
154  6 if (email.getMimeType().equals("html")) {
155  1 bodypart.setContent(email.getMessage(), "text/html; charset=utf-8");
156    } else {
157  5 bodypart.setText(email.getMessage(), "utf-8");
158    }
159  6 LOGGER.log("E-Mail {content} done", LogLevel.DEBUG);
160    // ATTACHMENTS : http://www.jguru.com/faq/view.jsp?EID=30251
161  6 Multipart multipart = new MimeMultipart();
162  6 multipart.addBodyPart(bodypart);
163  6 if (!email.getAttachmentList().isEmpty()) {
164  2 for (FileDataSource file : email.getAttachmentList()) {
165  2 DataSource source = file;
166  2 bodypart.setDataHandler(new DataHandler(source));
167  2 bodypart.setFileName(file.getName());
168  2 multipart.addBodyPart(bodypart);
169    }
170    }
171  6 LOGGER.log("E-Mail {atachments} done", LogLevel.DEBUG);
172  6 mimeMessage.setContent(multipart);
173  6 this.message = mimeMessage;
174  6 this.email = new Mail(email);
175    }
176   
 
177  10 toggle @Override
178    public Session getSession()
179    throws NoSuchProviderException {
180  10 Session connection = Session.getInstance(wireConfigurationEntries(),
181    new jakarta.mail.Authenticator() {
 
182  2 toggle @Override
183    protected PasswordAuthentication getPasswordAuthentication() {
184  2 return new PasswordAuthentication(
185    configuration.get("mailer.user"),
186    configuration.get("mailer.password")
187    );
188    }
189    });
190  9 connection.setDebug(Boolean.valueOf(configuration.get("mailer.debug")));
191  9 return connection;
192    }
193   
 
194  1 toggle @Override
195    public Mail getMailObject() {
196  1 return new Mail(email);
197    }
198   
 
199  3 toggle @Override
200    public MimeMessage getMimeMessage() {
201  3 final MimeMessage msg = this.message;
202  3 return msg;
203    }
204   
 
205  18 toggle @SuppressFBWarnings
206    //SpotBugs: hard coded Password
207    private void initConfig() {
208  18 this.configuration = new HashMap<>();
209  18 configuration.put("mailer.host", "mailer.host");
210  18 configuration.put("mailer.port", "mailer.port");
211  18 configuration.put("mailer.sender", "mailer.sender");
212  18 configuration.put("mailer.user", "mailer.user");
213  18 configuration.put("mailer.password", "mailer.password");
214  18 configuration.put("mailer.ssl", "mailer.ssl");
215  18 configuration.put("mailer.tls", "mailer.tls");
216  18 configuration.put("mailer.debug", "false");
217  18 configuration.put("mailer.count", "-1");
218  18 configuration.put("mailer.wait", "-1");
219    }
220   
 
221  10 toggle private Properties wireConfigurationEntries() {
222  10 configCountWaitTime = Long.parseLong(configuration.get("mailer.wait"));
223  9 configMaximumMailBulk = Integer.parseInt(configuration.get("mailer.count"));
224  9 Properties props = new Properties();
225  9 props.put("mail.smtp.host", configuration.get("mailer.host"));
226  9 props.put("mail.smtp.port", configuration.get("mailer.port"));
227  9 props.put("mail.smtp.auth", "true");
228  9 props.put("mail.smtp.starttls.enable", configuration.get("mailer.tls"));
229  9 props.put("mail.smtp.ssl.enable", configuration.get("mailer.ssl"));
230  9 props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
231  9 props.put("mail.smtp.socketFactory.port", configuration.get("mailer.port"));
232  9 props.put("mail.smtp.socketFactory.fallback", "false");
233   
234  9 props.put("mail.smtp.connectiontimeout", "8000"); // 8 seconds
235  9 props.put("mail.smtp.timeout", "10000"); // 10 seconds
236  9 return props;
237    }
238   
 
239  6 toggle private void processConfiguration(final List<ConfigurationDO> configurationEntries) {
240  6 LOGGER.log("Process E-Mail Configuration (" + configurationEntries.size() + ")",
241    LogLevel.DEBUG);
242  6 for (ConfigurationDO entry : configurationEntries) {
243  60 String value;
244  60 if (StringUtils.isEmpty(entry.getValue())) {
245  53 value = entry.getDefaultValue();
246    } else {
247  7 value = entry.getValue();
248    }
249  60 if (entry.getKey()
250    .equals(cryptoTools.calculateHash("mailer.host",
251    HashAlgorithm.SHA256))) {
252  6 configuration.replace("mailer.host", value);
253  54 } else if (entry.getKey()
254    .equals(cryptoTools.calculateHash("mailer.port",
255    HashAlgorithm.SHA256))) {
256  6 configuration.replace("mailer.port", value);
257  48 } else if (entry.getKey()
258    .equals(cryptoTools.calculateHash("mailer.sender",
259    HashAlgorithm.SHA256))) {
260  6 configuration.replace("mailer.sender", value);
261  42 } else if (entry.getKey()
262    .equals(cryptoTools.calculateHash("mailer.user",
263    HashAlgorithm.SHA256))) {
264  6 configuration.replace("mailer.user", value);
265  36 } else if (entry.getKey()
266    .equals(cryptoTools.calculateHash("mailer.password",
267    HashAlgorithm.SHA256))) {
268  6 configuration.replace("mailer.password", value);
269  30 } else if (entry.getKey()
270    .equals(cryptoTools.calculateHash("mailer.ssl",
271    HashAlgorithm.SHA256))) {
272  6 configuration.replace("mailer.ssl", value);
273  24 } else if (entry.getKey()
274    .equals(cryptoTools.calculateHash("mailer.tls",
275    HashAlgorithm.SHA256))) {
276  6 configuration.replace("mailer.tls", value);
277  18 } else if (entry.getKey()
278    .equals(cryptoTools.calculateHash("mailer.debug",
279    HashAlgorithm.SHA256))) {
280  6 configuration.replace("mailer.debug", value);
281  12 } else if (entry.getKey()
282    .equals(cryptoTools.calculateHash("mailer.count",
283    HashAlgorithm.SHA256))) {
284  6 configuration.replace("mailer.count", value);
285  6 } else if (entry.getKey()
286    .equals(cryptoTools.calculateHash("mailer.wait",
287    HashAlgorithm.SHA256))) {
288  6 configuration.replace("mailer.wait", value);
289    }
290    }
291    }
292    }