001/* 002 * Copyright 2017 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.bpm.workflowsdef; 017 018import java.io.IOException; 019import java.util.ArrayList; 020import java.util.List; 021import java.util.Map; 022 023import org.apache.avalon.framework.component.Component; 024import org.apache.avalon.framework.context.Context; 025import org.apache.avalon.framework.context.ContextException; 026import org.apache.avalon.framework.context.Contextualizable; 027import org.apache.avalon.framework.service.ServiceException; 028import org.apache.avalon.framework.service.ServiceManager; 029import org.apache.avalon.framework.service.Serviceable; 030import org.apache.cocoon.components.ContextHelper; 031import org.apache.cocoon.environment.Request; 032import org.apache.commons.lang.StringUtils; 033 034import org.ametys.core.user.CurrentUserProvider; 035import org.ametys.core.user.User; 036import org.ametys.core.user.UserIdentity; 037import org.ametys.core.user.UserManager; 038import org.ametys.core.util.I18nUtils; 039import org.ametys.core.util.JSONUtils; 040import org.ametys.core.util.mail.SendMailHelper; 041import org.ametys.plugins.bpm.BPMWorkflowManager; 042import org.ametys.plugins.bpm.jcr.JCRWorkflowProcess; 043import org.ametys.runtime.i18n.I18nizableText; 044import org.ametys.runtime.plugin.component.AbstractLogEnabled; 045 046import com.opensymphony.module.propertyset.PropertySet; 047import com.opensymphony.workflow.FunctionProvider; 048import com.opensymphony.workflow.WorkflowException; 049 050import jakarta.mail.MessagingException; 051/** 052 * Send mail to the users listed in the "users" argument. If the "sendToCreator" argument is present, the mail will also be send to the process creator 053 */ 054public class SendProcessMailFunction extends AbstractLogEnabled implements Component, FunctionProvider, Serviceable, Contextualizable 055{ 056 /** Actually send the email ? */ 057 public static final String SEND_MAIL = "send-request-information-mail"; 058 059 /** The mail subject key. */ 060 protected static final String SUBJECT_KEY = "subjectKey"; 061 /** The mail body key. */ 062 protected static final String BODY_KEY = "bodyKey"; 063 064 private JSONUtils _jsonUtils; 065 private UserManager _userManager; 066 private I18nUtils _i18nUtils; 067 private Context _context; 068 private BPMWorkflowManager _bpmWorkflowManager; 069 private CurrentUserProvider _currentUserProvider; 070 071 @Override 072 public void contextualize(Context context) throws ContextException 073 { 074 _context = context; 075 } 076 077 public void service(ServiceManager manager) throws ServiceException 078 { 079 _bpmWorkflowManager = (BPMWorkflowManager) manager.lookup(BPMWorkflowManager.ROLE); 080 _jsonUtils = (JSONUtils) manager.lookup(JSONUtils.ROLE); 081 _userManager = (UserManager) manager.lookup(UserManager.ROLE); 082 _i18nUtils = (I18nUtils) manager.lookup(I18nUtils.ROLE); 083 _currentUserProvider = (CurrentUserProvider) manager.lookup(CurrentUserProvider.ROLE); 084 } 085 086 @Override 087 public void execute(Map transientVars, Map args, PropertySet ps) throws WorkflowException 088 { 089 JCRWorkflowProcess process = (JCRWorkflowProcess) transientVars.getOrDefault("process", null); 090 if (process == null) 091 { 092 return; 093 } 094 095 UserIdentity creator = process.getCreator(); 096 User creatorUser = _userManager.getUser(creator); 097 098 String subjectKey = (String) args.get(SUBJECT_KEY); 099 String bodyKey = (String) args.get(BODY_KEY); 100 String mailSubject = _getSubject(StringUtils.defaultString(subjectKey), process); 101 String mailBody = _getBody(StringUtils.defaultString(bodyKey), process, creatorUser); 102 103 if (mailSubject == null || mailBody == null) 104 { 105 return; 106 } 107 108 List<User> usersList = _getRecipients((String) args.getOrDefault("users", null), (String) args.getOrDefault("sendToCreator", null), creatorUser); 109 110 List<String> sentTo = new ArrayList<>(); 111 for (User user : usersList) 112 { 113 String recipient = user.getEmail(); 114 if (StringUtils.isNotEmpty(recipient) && !sentTo.contains(recipient)) 115 { 116 try 117 { 118 SendMailHelper.newMail() 119 .withSubject(mailSubject) 120 .withTextBody(mailBody) 121 .withRecipient(recipient) 122 .sendMail(); 123 124 sentTo.add(recipient); 125 } 126 catch (MessagingException | IOException e) 127 { 128 getLogger().warn("Could not send a workflow notification mail to {}", recipient, e); 129 } 130 } 131 } 132 133 } 134 135 private String _getSubject(String subjectI18nKey, JCRWorkflowProcess process) 136 { 137 List<String> subjectParams = new ArrayList<>(); 138 subjectParams.add(process.getTitle()); 139 try 140 { 141 String mailSubject = _i18nUtils.translate(new I18nizableText(null, subjectI18nKey, subjectParams), null); // {0} 142 if (mailSubject == null) 143 { 144 getLogger().error("Could not send email for the process workflow, unknown i18n key specified for subject {}", subjectI18nKey); 145 } 146 return mailSubject; 147 } 148 catch (Exception e) 149 { 150 getLogger().error("Could not send email for the process workflow, failed to translate i18n key specified for subject {}", subjectI18nKey, e); 151 return null; 152 } 153 } 154 155 private String _getBody(String bodyI18nKey, JCRWorkflowProcess process, User creatorUser) 156 { 157 List<String> bodyParams = new ArrayList<>(); 158 159 UserIdentity user = _currentUserProvider.getUser(); 160 User currentUser = user != null ? _userManager.getUser(user) : null; 161 bodyParams.add(currentUser != null ? currentUser.getFullName() : ""); // {0} 162 bodyParams.add(creatorUser != null ? creatorUser.getFullName() : ""); // {1} 163 bodyParams.add(process.getTitle()); // {2} 164 165 Request request = ContextHelper.getRequest(_context); 166 String siteName = request.getParameter("site"); 167 if (siteName == null) 168 { 169 siteName = (String) request.getAttribute("site"); 170 } 171 String lang = request.getParameter("lang"); 172 if (lang == null) 173 { 174 lang = (String) request.getAttribute("sitemapLanguage"); 175 } 176 177 bodyParams.add(_bpmWorkflowManager.getProcessPageUrl(process, siteName, lang, true)); // {3} 178 179 try 180 { 181 String mailBody = _i18nUtils.translate(new I18nizableText(null, bodyI18nKey, bodyParams), null); 182 if (mailBody == null) 183 { 184 getLogger().error("Could not send email for the process workflow, unknown i18n key specified for body {}", bodyI18nKey); 185 } 186 return mailBody; 187 } 188 catch (Exception e) 189 { 190 getLogger().error("Could not send email for the process workflow, fail to translate i18n key specified for body {}", bodyI18nKey, e); 191 return null; 192 } 193 } 194 195 private List<User> _getRecipients(String users, String sendToCreator, User creatorUser) 196 { 197 List<User> usersList = new ArrayList<>(); 198 199 if (users != null) 200 { 201 for (Object obj : _jsonUtils.convertJsonToList(users)) 202 { 203 @SuppressWarnings("unchecked") 204 Map<String, Object> grantedUser = (Map<String, Object>) obj; 205 String login = (String) grantedUser.get("login"); 206 String populationId = (String) grantedUser.get("populationId"); 207 208 if (login != null && populationId != null) 209 { 210 User user = _userManager.getUser(populationId, login); 211 usersList.add(user); 212 } 213 } 214 } 215 else if ("true".equals(sendToCreator) && creatorUser != null) 216 { 217 usersList.add(creatorUser); 218 } 219 return usersList; 220 } 221}