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