001/*
002 *  Copyright 2010 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package org.ametys.plugins.newsletter.workflow;
017
018import java.io.IOException;
019import java.util.Date;
020import java.util.Map;
021import java.util.Random;
022
023import org.slf4j.Logger;
024import org.slf4j.LoggerFactory;
025
026import org.ametys.core.util.URIUtils;
027import org.ametys.core.util.mail.SendMailHelper;
028import org.ametys.plugins.newsletter.ga.GAUriBuilder;
029
030import jakarta.mail.MessagingException;
031
032/**
033 * Sends mails in a thread
034 */
035public class SendMailEngine implements Runnable
036{
037    private static Logger _logger = LoggerFactory.getLogger(SendMailEngine.class);
038
039    private static final Random _RNG = new Random((long) Math.random() * System.nanoTime());
040    
041    private String _subject;
042    private String _htmlBody;
043    private String _textBody;
044    private Map<String, String> _recipients;
045    private String _sender;
046    
047    private boolean _parametrized;
048    
049    /**
050     * Parameterize engine
051     * @param subject The mail subject
052     * @param htmlBody The mail body in HTML format
053     * @param textBody The mail body in text format
054     * @param recipients The recipient addresses
055     * @param sender The sender address
056     */
057    public void parameterize (String subject, String htmlBody, String textBody, Map<String, String> recipients, String sender)
058    {
059        _subject = subject;
060        _htmlBody = SendMailHelper.inlineCSS(htmlBody);
061        _textBody = textBody;
062        _recipients = recipients;
063        _sender = sender;
064        
065        _parametrized = true;
066    }
067    
068    private void _checkParametrization()
069    {
070        if (!_parametrized)
071        {
072            String message = "The mail engine component has to be parameterized before it can be run.";
073            _logger.error(message);
074            throw new IllegalStateException(message);
075        }
076    }
077    
078    public void run()
079    {
080        _checkParametrization ();
081        
082        if (_logger.isInfoEnabled())
083        {
084            _logger.info("Try to send " + _recipients.size() + " mails at " + new Date());
085        }
086
087        for (String recipient : _recipients.keySet())
088        {
089            try
090            {
091                String htmlBody = _htmlBody.replaceAll("#token#", _recipients.get(recipient));
092                String textBody = _textBody.replaceAll("#token#", _recipients.get(recipient));
093                
094                htmlBody = htmlBody.replaceAll(URIUtils.encodeParameter(GAUriBuilder.GA_VISITORID_TOKEN), Integer.toString(_RNG.nextInt(Integer.MAX_VALUE)));
095                htmlBody = htmlBody.replaceAll(GAUriBuilder.GA_UTMN_TOKEN, Integer.toString(_RNG.nextInt(Integer.MAX_VALUE)));
096                htmlBody = htmlBody.replaceAll(GAUriBuilder.GA_UTMHID_TOKEN, Integer.toString(_RNG.nextInt(Integer.MAX_VALUE)));
097
098                SendMailHelper.newMail()
099                              .withSubject(_subject)
100                              .withHTMLBody(htmlBody)
101                              .withInlineCSS(false) // We inline the CSS manually once and for all to avoid doing it multiple times
102                              .withTextBody(textBody)
103                              .withSender(_sender)
104                              .withRecipient(recipient)
105                              .sendMail();
106                
107                Thread.sleep(1000);
108            }
109            catch (MessagingException | IOException e)
110            {
111                _logger.error("Mail failed !", e);
112            }
113            catch (InterruptedException e)
114            {
115                _logger.error("Error while waiting for sending mails", e);
116            }
117        }
118        
119        if (_logger.isInfoEnabled())
120        {
121            _logger.info("All mails are sent at " + new Date());
122        }
123    }
124}