001/*
002 *  Copyright 2023 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.web.activities.observation;
017
018import java.io.IOException;
019import java.util.List;
020import java.util.Map;
021
022import org.apache.avalon.framework.service.ServiceException;
023import org.apache.avalon.framework.service.ServiceManager;
024import org.apache.avalon.framework.service.Serviceable;
025import org.apache.commons.lang.StringUtils;
026
027import org.ametys.core.observation.Event;
028import org.ametys.core.observation.Observer;
029import org.ametys.core.util.I18nUtils;
030import org.ametys.core.util.mail.SendMailHelper;
031import org.ametys.core.util.mail.SendMailHelper.MailBuilder;
032import org.ametys.plugins.repository.AmetysObjectResolver;
033import org.ametys.plugins.repository.ObservationConstants;
034import org.ametys.plugins.repository.activities.Activity;
035import org.ametys.runtime.plugin.component.AbstractLogEnabled;
036import org.ametys.runtime.plugin.component.PluginAware;
037import org.ametys.web.activities.notify.ActivityNotifier;
038import org.ametys.web.activities.notify.ActivityNotifierExtensionPoint;
039
040import jakarta.mail.MessagingException;
041
042/**
043 * Send mail notification to user when a new activity is created
044 */
045public class NotifyActivityObserver extends AbstractLogEnabled implements Observer, Serviceable, PluginAware
046{
047    /** The ametys object resolver */
048    protected AmetysObjectResolver _resolver;
049    
050    /** The i18n utils */
051    protected I18nUtils _i18nUtils;
052    
053    /** The activity notifier extension point */
054    protected ActivityNotifierExtensionPoint _activityNotifierEP;
055    
056    /** The plugin name */
057    protected String _pluginName;
058    
059    public void service(ServiceManager manager) throws ServiceException
060    {
061        _i18nUtils = (I18nUtils) manager.lookup(I18nUtils.ROLE);
062        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
063        _activityNotifierEP = (ActivityNotifierExtensionPoint) manager.lookup(ActivityNotifierExtensionPoint.ROLE);
064    }
065    
066    public void setPluginInfo(String pluginName, String featureName, String id)
067    {
068        _pluginName = pluginName;
069    }
070    
071    public boolean supports(Event event)
072    {
073        return ObservationConstants.EVENT_ACTIVITY_CREATED.equals(event.getId());
074    }
075
076    public int getPriority()
077    {
078        return MAX_PRIORITY;
079    }
080
081    public void observe(Event event, Map<String, Object> transientVars) throws Exception
082    {
083        Map<String, Object> arguments = event.getArguments();
084        String activityId = (String) arguments.get(ObservationConstants.ARGS_ACTIVITY_ID);
085        Activity activity = _resolver.resolveById(activityId);
086        
087        for (String id : _activityNotifierEP.getExtensionsIds())
088        {
089            ActivityNotifier notifier = _activityNotifierEP.getExtension(id);
090            if (_isSupported(notifier, activity))
091            {
092                _notify(notifier, activity);
093            }
094        }
095    }
096    
097    /**
098     * <code>true</code> if the notifier and the activity are supported
099     * @param notifier the notifier
100     * @param activity the activity
101     * @return <code>true</code> if the notifier and the activity are supported
102     */
103    protected boolean _isSupported(ActivityNotifier notifier, Activity activity)
104    {
105        return !notifier.isAsync() && notifier.supports(activity.getActivityType());
106    }
107    
108    /**
109     * Notify email by mail
110     * @param notifier the activity notifier
111     * @param activity the activity
112     */
113    protected void _notify(ActivityNotifier notifier, Activity activity)
114    {
115        // Recipients
116        Map<String, List<String>> recipientsByLanguage = notifier.getUsersToNotifyByLanguage(activity);
117        
118        try
119        {
120            for (String language : recipientsByLanguage.keySet())
121            {
122                List<String> emails = recipientsByLanguage.get(language);
123                
124                // Subject
125                String subject = notifier.getMailSubject(activity, language);
126                
127                // Body
128                String mailBodyHTML = notifier.getMailHtmlBody(activity, language);
129                String mailBody = notifier.getMailTextBody(activity, language);
130                
131                MailBuilder mailBuilder = SendMailHelper.newMail()
132                        .withRecipients(emails)
133                        .withSubject(subject)
134                        .withAsync(true)
135                        .withInlineCSS(false);
136                
137                if (StringUtils.isNotBlank(mailBodyHTML))
138                {
139                    mailBuilder = mailBuilder.withHTMLBody(mailBodyHTML);
140                }
141                
142                if (StringUtils.isNotBlank(mailBody))
143                {
144                    mailBuilder = mailBuilder.withTextBody(mailBody);
145                }
146                
147                mailBuilder.sendMail();
148            }
149        }
150        catch (MessagingException | IOException e)
151        {
152            getLogger().warn("Could not send a notification e-mail to {}", recipientsByLanguage, e);
153        }
154    }
155}