001/*
002 * Copyright 2016 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.forms.content.workflow;
017
018import java.util.ArrayList;
019import java.util.HashMap;
020import java.util.List;
021import java.util.Map;
022import java.util.Optional;
023import java.util.regex.Pattern;
024
025import org.apache.avalon.framework.component.Component;
026import org.apache.avalon.framework.service.ServiceException;
027import org.apache.avalon.framework.service.ServiceManager;
028import org.apache.avalon.framework.service.Serviceable;
029
030import org.ametys.core.ui.Callable;
031import org.ametys.core.user.CurrentUserProvider;
032import org.ametys.core.user.User;
033import org.ametys.core.user.UserIdentity;
034import org.ametys.core.user.UserManager;
035import org.ametys.core.util.mail.SendMailHelper;
036import org.ametys.plugins.forms.FormsException;
037import org.ametys.plugins.forms.content.Field;
038import org.ametys.plugins.forms.content.Form;
039import org.ametys.plugins.forms.content.Field.FieldType;
040import org.ametys.plugins.forms.content.data.FieldValue;
041import org.ametys.plugins.forms.content.data.UserEntry;
042import org.ametys.plugins.forms.content.jcr.FormPropertiesManager;
043import org.ametys.plugins.forms.content.table.FormTableManager;
044import org.ametys.runtime.plugin.component.AbstractLogEnabled;
045
046/**
047 * Helper component allowing to retrieve information in order to send emails
048 */
049public class MailInformationHelper extends AbstractLogEnabled implements Component, Serviceable
050{
051    /** The Avalon role */
052    public static final String ROLE = MailInformationHelper.class.getName();
053
054    /** The email validation pattern. */
055    protected static final Pattern _EMAIL_PATTERN = SendMailHelper.EMAIL_VALIDATION;
056
057    /** The current user provider */
058    protected CurrentUserProvider _currentUserProvider;
059    
060    /** The user manager */
061    protected UserManager _userManager;
062    
063    /** The manager for the JCR representation of forms */
064    protected FormPropertiesManager _formPropertiesManager;
065    
066    /** The manager for the form entries */
067    protected FormTableManager _formTableManager;
068    
069    @Override
070    public void service(ServiceManager serviceManager) throws ServiceException
071    {
072        _currentUserProvider = (CurrentUserProvider) serviceManager.lookup(CurrentUserProvider.ROLE);
073        _userManager = (UserManager) serviceManager.lookup(UserManager.ROLE);
074        _formPropertiesManager = (FormPropertiesManager) serviceManager.lookup(FormPropertiesManager.ROLE);
075        _formTableManager = (FormTableManager) serviceManager.lookup(FormTableManager.ROLE);
076    }
077    
078    /**
079     * Get information on the given entry of the given form
080     * @param formId the id of the form
081     * @param entryId the id of the entry
082     * @return a map of information on the current user and on the email fields filled in the entry
083     */
084    @Callable
085    public Map<String, Object> getMailInfo(String formId, Integer entryId)
086    {
087        Map<String, Object> sendMail = new HashMap<> ();
088        
089        sendMail.put("current-user", _getSender());
090        
091        UserEntry formEntry = _getFormEntry(formId, entryId);
092        sendMail.put("emails", _getAvailableRecipients(formEntry));
093
094        Map<String, Object> result = new HashMap<> ();
095        result.put("send-mail", sendMail);
096        return result;
097    }
098    
099    /**
100     * Get the sender filled into the dialog to send informations to claimant by email about his form entry status.
101     * @return the sender
102     */
103    protected Map<String, Object> _getSender()
104    {
105        // Retrieve the current user name and email
106        UserIdentity userIdentity = _currentUserProvider.getUser();
107        User user = _userManager.getUser(userIdentity);
108        
109        Map<String, Object> currentUser = new HashMap<> ();
110        currentUser.put("email", user.getEmail());
111        currentUser.put("fullname", user.getFullName());
112        
113        return currentUser;
114    }
115    
116    /**
117     * Get the available recipients from the form entries to propose recipients.
118     * @param formEntry The form entry
119     * @return the list of available recipients
120     */
121    protected List<Map<String, String>> _getAvailableRecipients(UserEntry formEntry)
122    {
123        // Retrieve the valid email fields
124        List<Map<String, String>> emails = new ArrayList<>();
125        for (FieldValue fieldValue : formEntry.getValues())
126        {
127            Field field = fieldValue.getField();
128            if (FieldType.TEXT.equals(field.getType()))
129            {
130                Map<String, String> properties = field.getProperties();
131                String value = (String) fieldValue.getValue();
132                if (value != null && "email".equals(properties.get("regexptype")) && _EMAIL_PATTERN.matcher(value).matches())
133                {
134                    Map<String, String> email = new HashMap<> ();
135                    email.put("displayValue", field.getLabel() + ": " + value);
136                    email.put("value", value);
137                    emails.add(email);
138                }
139            }
140        }
141        
142        return emails;
143    }
144    
145    /**
146     * Get the form entry from form identifier and entry identifier.
147     * @param formId The form id
148     * @param entryId The entry id
149     * @return the form entry or throw a {@link IllegalArgumentException} if it doesn't exist.
150     */
151    protected UserEntry _getFormEntry(String formId, Integer entryId)
152    {
153        try
154        {
155            Form form = _formPropertiesManager.getForm(formId);
156            Map<String, FieldValue> columns = _formTableManager.getColumns(form);
157            
158            return Optional.ofNullable(_formTableManager.getSubmission(form, columns, entryId))
159                    .orElseThrow(() -> new IllegalArgumentException("Unable to retrieve the workflow id for the entry '" + entryId + "' of the form '" + formId + "'."));
160        }
161        catch (FormsException e)
162        {
163            throw new IllegalArgumentException("An error occured while trying to recover the user entry '" + entryId + "' of the form of id '" + formId + "'.");
164        }
165    }
166}