001/*
002 *  Copyright 2020 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.cms.schedule;
017
018import java.util.Optional;
019
020import javax.mail.MessagingException;
021
022import org.apache.avalon.framework.activity.Initializable;
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025import org.apache.commons.lang.exception.ExceptionUtils;
026import org.apache.commons.lang3.StringUtils;
027import org.quartz.JobExecutionContext;
028
029import org.ametys.core.user.User;
030import org.ametys.core.util.I18nUtils;
031import org.ametys.core.util.mail.SendMailHelper;
032import org.ametys.plugins.core.impl.schedule.AbstractStaticSchedulable;
033import org.ametys.runtime.config.Config;
034import org.ametys.runtime.i18n.I18nizableText;
035
036/**
037 * Abstract schedulable that send an email at the end of the execution
038 * The email is send to the user that launched the schedulable
039 * If this user has no email address and there is an error during the execution, an email is send to the system administrator
040 */
041public abstract class AbstractSendingMailSchedulable extends AbstractStaticSchedulable implements Initializable
042{
043    /** The utils for i18n */
044    protected I18nUtils _i18nUtils;
045    /** Mail sender */
046    protected String _mailSender;
047    /** Sys admin mail */
048    protected String _sysadminMail;
049    
050    @Override
051    public void service(ServiceManager manager) throws ServiceException
052    {
053        super.service(manager);
054        _i18nUtils = (I18nUtils) manager.lookup(I18nUtils.ROLE);
055    }
056
057    public void initialize() throws Exception
058    {
059        _mailSender = Config.getInstance().getValue("smtp.mail.from");
060        _sysadminMail = Config.getInstance().getValue("smtp.mail.sysadminto");
061    }
062
063    @Override
064    public void execute(JobExecutionContext context) throws Exception
065    {
066        Optional<String> recipient = Optional.of(context)
067                .map(this::_getLaunchUser)
068                .map(User::getEmail)
069                .filter(StringUtils::isNotEmpty);
070        
071        I18nizableText mailSubject = null;
072        I18nizableText mailBody = null;
073        Optional<String> additionalMessage = Optional.empty();
074        try
075        {
076            _doExecute(context);
077            
078            mailSubject = _getSuccessMailSubject(context);
079            mailBody = _getSuccessMailBody(context);
080        }
081        catch (Exception e)
082        {
083            if (recipient.isEmpty())
084            {
085                recipient = Optional.ofNullable(_sysadminMail)
086                        .filter(StringUtils::isNotEmpty);
087            }
088            
089            mailSubject = _getErrorMailSubject(context);
090            mailBody = _getErrorMailBody(context);
091            additionalMessage = Optional.of(ExceptionUtils.getStackTrace(e));
092
093            throw e;
094        }
095        finally
096        {
097            if (recipient.isPresent())
098            {
099                _sendMail(mailSubject, mailBody, additionalMessage, recipient.get());
100            }
101        }
102    }
103    
104    /**
105     * Executes the schedulable.
106     * @param context the context
107     * @throws Exception if an error occurred
108     */
109    protected abstract void _doExecute(JobExecutionContext context) throws Exception;
110    
111    /**
112     * Retrieves the subject of the success mail
113     * @param context the context
114     * @return the subject of the success mail
115     */
116    protected abstract I18nizableText _getSuccessMailSubject(JobExecutionContext context);
117    
118    /**
119     * Retrieves the body of the success mail
120     * @param context the context
121     * @return the body of the success mail
122     */
123    protected abstract I18nizableText _getSuccessMailBody(JobExecutionContext context);
124    
125    /**
126     * Retrieves the subject of the error mail
127     * @param context the context
128     * @return the subject of the error mail
129     */
130    protected abstract I18nizableText _getErrorMailSubject(JobExecutionContext context);
131    
132    /**
133     * Retrieves the body of the error mail
134     * @param context the context
135     * @return the body of the error mail
136     */
137    protected abstract I18nizableText _getErrorMailBody(JobExecutionContext context);
138    
139    /**
140     * Send an email
141     * @param subject the email's subject
142     * @param body the email's body
143     * @param additionalMessage an optional message to add to the email's body
144     * @param recipient the recipient address
145     */
146    protected void _sendMail (I18nizableText subject, I18nizableText body, Optional<String> additionalMessage, String recipient)
147    {
148        String translatedSubject = _i18nUtils.translate(subject);
149
150        String translatedBody = _i18nUtils.translate(body);
151        String completeBody = translatedBody;
152        if (additionalMessage.isPresent())
153        {
154            completeBody += "\n\n" + additionalMessage.get();
155        }
156        
157        try
158        {
159            SendMailHelper.sendMail(translatedSubject, null, completeBody, recipient, _mailSender);
160        }
161        catch (MessagingException e)
162        {
163            if (getLogger().isWarnEnabled())
164            {
165                getLogger().warn("Unable to send the e-mail '" + subject  + "' to '" + recipient + "'", e);
166            }
167        }
168    }
169}