From 1e58368f3e0cad101387d05ae481f162d8d263b1 Mon Sep 17 00:00:00 2001 From: lmann99 Date: Sun, 1 Jan 2017 08:42:21 -0500 Subject: [PATCH] Add project url to email template keywords, allow url keyword in timesheet template --- .../notifications/ComposeMessage.java | 406 +++++++++++------- .../src/main/resources/i18n/keys.pot | 4 + .../src/main/webapp/email/email_templates.zul | 5 + pom.xml | 6 + 4 files changed, 255 insertions(+), 166 deletions(-) diff --git a/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/ComposeMessage.java b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/ComposeMessage.java index 55045847a..047b243e7 100644 --- a/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/ComposeMessage.java +++ b/libreplan-webapp/src/main/java/org/libreplan/importers/notifications/ComposeMessage.java @@ -19,6 +19,8 @@ package org.libreplan.importers.notifications; +//import javax.annotation.Resource; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.libreplan.business.common.entities.ConnectorProperty; @@ -33,9 +35,20 @@ import org.libreplan.web.email.IEmailTemplateModel; import org.libreplan.web.planner.tabs.MultipleTabsPlannerController; import org.libreplan.web.resources.worker.IWorkerModel; import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.beans.factory.annotation; import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Configuration; + +import org.springframework.context.ApplicationContext; +import org.springframework.core.env.Environment; +import org.springframework.core.env.AbstractEnvironment; + +import org.springframework.web.context.WebApplicationContext; + import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; +import javax.servlet.ServletContext; + import org.zkoss.zul.Messagebox; import javax.mail.Message; @@ -45,243 +58,304 @@ import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; +import javax.management.AttributeNotFoundException; +import javax.management.InstanceNotFoundException; +import javax.management.MBeanException; +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; +import javax.management.Query; +import javax.management.ReflectionException; +import javax.naming.InitialContext; +import javax.naming.Context; + import java.util.List; import java.util.Locale; import java.util.Properties; +import java.util.Set; +import java.util.Iterator; +import java.util.Map; +import java.util.ArrayList; +import java.util.HashMap; +import java.lang.String; +import java.lang.management.ManagementFactory; +import java.io.File; +import java.net.InetAddress; +import java.net.URLDecoder; +import java.net.UnknownHostException; +import java.io.UnsupportedEncodingException; + +import org.springframework.core.env.MapPropertySource; import static org.libreplan.web.I18nHelper._; /** - * Sends E-mail to users with data that storing in notification_queue table - * and that are treat to incoming {@link EmailNotification}. + * Sends E-mail to users with data that storing in notification_queue table and + * that are treat to incoming {@link EmailNotification}. * * @author Vova Perebykivskyi */ +@Configuration @Component @Scope(BeanDefinition.SCOPE_PROTOTYPE) public class ComposeMessage { - @Autowired - private IWorkerModel workerModel; + @Autowired + private IWorkerModel workerModel; - @Autowired - private IEmailTemplateModel emailTemplateModel; + @Autowired + private IEmailTemplateModel emailTemplateModel; - @Autowired - private EmailConnectionValidator emailConnectionValidator; + @Autowired + private EmailConnectionValidator emailConnectionValidator; - private String protocol; + // @Autowired + // private Environment environment; - private String host; + @Autowired + private WebApplicationContext webApplicationContext; - private String port; + // @Autowired + // private ServletContext servletContext; - private String sender; + private String protocol; - private String usrnme; + private String host; - private String psswrd; + private String port; - private Properties properties; + private String sender; - private static final Log LOG = LogFactory.getLog(ComposeMessage.class); + private String usrnme; + private String psswrd; - public boolean composeMessageForUser(EmailNotification notification) { - // Gather data about EmailTemplate needs to be used - Resource resource = notification.getResource(); - EmailTemplateEnum type = notification.getType(); - Locale locale; - Worker currentWorker = getCurrentWorker(resource.getId()); + private Properties properties; - UserRole currentUserRole = getCurrentUserRole(notification.getType()); + private static final Log LOG = LogFactory.getLog(ComposeMessage.class); - if (currentWorker != null && currentWorker.getUser().isInRole(currentUserRole)) { - if (currentWorker.getUser().getApplicationLanguage().equals(Language.BROWSER_LANGUAGE)) { - locale = new Locale(System.getProperty("user.language")); - } else { - locale = new Locale(currentWorker.getUser().getApplicationLanguage().getLocale().getLanguage()); - } + public boolean composeMessageForUser(EmailNotification notification) { + // Gather data about EmailTemplate needs to be used + Resource resource = notification.getResource(); + EmailTemplateEnum type = notification.getType(); + Locale locale; + Worker currentWorker = getCurrentWorker(resource.getId()); - EmailTemplate currentEmailTemplate = findCurrentEmailTemplate(type, locale); + UserRole currentUserRole = getCurrentUserRole(notification.getType()); - if (currentEmailTemplate == null) { - LOG.error("Email template is null"); - return false; - } + if (currentWorker != null && currentWorker.getUser().isInRole(currentUserRole)) { + if (currentWorker.getUser().getApplicationLanguage().equals(Language.BROWSER_LANGUAGE)) { + locale = new Locale(System.getProperty("user.language")); + } else { + locale = new Locale(currentWorker.getUser().getApplicationLanguage().getLocale().getLanguage()); + } - // Modify text that will be composed - String text = currentEmailTemplate.getContent(); - text = replaceKeywords(text, currentWorker, notification); + EmailTemplate currentEmailTemplate = findCurrentEmailTemplate(type, locale); - String receiver = currentWorker.getUser().getEmail(); + if (currentEmailTemplate == null) { + LOG.error("Email template is null"); + return false; + } - setupConnectionProperties(); + // Modify text that will be composed + String text = currentEmailTemplate.getContent(); + text = replaceKeywords(text, currentWorker, notification); - final String username = usrnme; - final String password = psswrd; + String receiver = currentWorker.getUser().getEmail(); - // It is very important to use Session.getInstance() instead of Session.getDefaultInstance() - Session mailSession = Session.getInstance(properties, new javax.mail.Authenticator() { - @Override - protected PasswordAuthentication getPasswordAuthentication() { - return new PasswordAuthentication(username, password); - } - }); + setupConnectionProperties(); - // Send message - try { - MimeMessage message = new MimeMessage(mailSession); + final String username = usrnme; + final String password = psswrd; - message.setFrom(new InternetAddress(sender)); - message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(receiver)); + // It is very important to use Session.getInstance() instead of + // Session.getDefaultInstance() + Session mailSession = Session.getInstance(properties, new javax.mail.Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); + } + }); - String subject = currentEmailTemplate.getSubject(); - message.setSubject(subject); + // Send message + try { + MimeMessage message = new MimeMessage(mailSession); - message.setText(text); + message.setFrom(new InternetAddress(sender)); + message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(receiver)); - Transport.send(message); + String subject = currentEmailTemplate.getSubject(); + message.setSubject(subject); - return true; + message.setText(text); - } catch (MessagingException e) { - throw new RuntimeException(e); - } catch (NullPointerException e) { - if (receiver == null) { - Messagebox.show( - _(currentWorker.getUser().getLoginName() + " - this user have not filled E-mail"), - _("Error"), Messagebox.OK, Messagebox.ERROR); - } - } - } - return false; - } + Transport.send(message); - private Worker getCurrentWorker(Long resourceID){ - List workerList = workerModel.getWorkers(); + return true; - for (Worker aWorkerList : workerList) { - if (aWorkerList.getId().equals(resourceID)) { - return aWorkerList; - } - } + } catch (MessagingException e) { + throw new RuntimeException(e); + } catch (NullPointerException e) { + if (receiver == null) { + Messagebox.show(_(currentWorker.getUser().getLoginName() + " - this user have not filled E-mail"), + _("Error"), Messagebox.OK, Messagebox.ERROR); + } + } + } + return false; + } - return null; - } + private Worker getCurrentWorker(Long resourceID) { + List workerList = workerModel.getWorkers(); - private EmailTemplate findCurrentEmailTemplate(EmailTemplateEnum templateEnum, Locale locale) { - List emailTemplates; - emailTemplates = emailTemplateModel.getAll(); + for (Worker aWorkerList : workerList) { + if (aWorkerList.getId().equals(resourceID)) { + return aWorkerList; + } + } - for (EmailTemplate item : emailTemplates) { - if ( item.getType().equals(templateEnum) && item.getLanguage().getLocale().equals(locale) ) { - return item; - } + return null; + } - } + private EmailTemplate findCurrentEmailTemplate(EmailTemplateEnum templateEnum, Locale locale) { + List emailTemplates; + emailTemplates = emailTemplateModel.getAll(); - return null; - } + for (EmailTemplate item : emailTemplates) { + if (item.getType().equals(templateEnum) && item.getLanguage().getLocale().equals(locale)) { + return item; + } - private String replaceKeywords(String text, Worker currentWorker, EmailNotification notification) { - String newText = text; + } - if ( notification.getType().equals(EmailTemplateEnum.TEMPLATE_ENTER_DATA_IN_TIMESHEET) ) { - // It is because there is no other data for - // EmailNotification of TEMPLATE_ENTER_DATA_IN_TIMESHEET notification type - newText = newText.replaceAll("\\{resource\\}", notification.getResource().getName()); - } - else { - newText = newText.replaceAll("\\{username\\}", currentWorker.getUser().getLoginName()); - newText = newText.replaceAll("\\{firstname\\}", currentWorker.getUser().getFirstName()); - newText = newText.replaceAll("\\{lastname\\}", currentWorker.getUser().getLastName()); - newText = newText.replaceAll("\\{project\\}", notification.getProject().getName()); - newText = newText.replaceAll("\\{resource\\}", notification.getResource().getName()); - newText = newText.replaceAll("\\{task\\}", notification.getTask().getName()); - newText = newText.replaceAll("\\{url\\}", MultipleTabsPlannerController.WELCOME_URL); - } - return newText; - } + return null; + } - private void setupConnectionProperties() { - List emailConnectorProperties = emailConnectionValidator.getEmailConnectorProperties(); + private String replaceKeywords(String text, Worker currentWorker, EmailNotification notification) { + String newText = text; - for (int i = 0; i < emailConnectorProperties.size(); i++) { - switch (i) { + // replace {url} in all messages even timesheet reminder emails + // as a link may be helpful + newText = newText.replaceAll("\\{url\\}", MultipleTabsPlannerController.WELCOME_URL); + if (notification.getType().equals(EmailTemplateEnum.TEMPLATE_ENTER_DATA_IN_TIMESHEET)) { + // It is because there is no other data for + // EmailNotification of TEMPLATE_ENTER_DATA_IN_TIMESHEET + // notification type + newText = newText.replaceAll("\\{resource\\}", notification.getResource().getName()); + } else { + newText = newText.replaceAll("\\{username\\}", currentWorker.getUser().getLoginName()); + newText = newText.replaceAll("\\{firstname\\}", currentWorker.getUser().getFirstName()); + newText = newText.replaceAll("\\{lastname\\}", currentWorker.getUser().getLastName()); + newText = newText.replaceAll("\\{project\\}", notification.getProject().getName()); + newText = newText.replaceAll("\\{resource\\}", notification.getResource().getName()); + newText = newText.replaceAll("\\{task\\}", notification.getTask().getName()); + newText = newText.replaceAll("\\{projecturl\\}", MultipleTabsPlannerController.WELCOME_URL+ ";order=" + notification.getProject().getProjectCode()); + } + return newText; + } - case 1: - protocol = emailConnectorProperties.get(1).getValue(); - break; + List getEndPoints() throws MalformedObjectNameException, NullPointerException, UnknownHostException, + AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException { + + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + + Set objs = mbs.queryNames(new ObjectName("*:type=Connector,*"), + Query.match(Query.attr("protocol"), Query.value("HTTP/1.1"))); + + String hostname = InetAddress.getLocalHost().getHostName(); + + InetAddress[] addresses = InetAddress.getAllByName(hostname); + + ArrayList endPoints = new ArrayList(); + for (Iterator i = objs.iterator(); i.hasNext();) { + ObjectName obj = i.next(); + String scheme = mbs.getAttribute(obj, "scheme").toString(); + String port = obj.getKeyProperty("port"); + for (InetAddress addr : addresses) { + String host = addr.getHostAddress(); + String ep = scheme + "://" + host + ":" + port; + endPoints.add(ep); + } + } + return endPoints; + } - case 2: - host = emailConnectorProperties.get(2).getValue(); - break; + private void setupConnectionProperties() { + List emailConnectorProperties = emailConnectionValidator.getEmailConnectorProperties(); - case 3: - port = emailConnectorProperties.get(3).getValue(); - break; + for (int i = 0; i < emailConnectorProperties.size(); i++) { + switch (i) { - case 4: - sender = emailConnectorProperties.get(4).getValue(); - break; + case 1: + protocol = emailConnectorProperties.get(1).getValue(); + break; - case 5: - usrnme = emailConnectorProperties.get(5).getValue(); - break; + case 2: + host = emailConnectorProperties.get(2).getValue(); + break; - case 6: - psswrd = emailConnectorProperties.get(6).getValue(); - break; + case 3: + port = emailConnectorProperties.get(3).getValue(); + break; - default: - break; + case 4: + sender = emailConnectorProperties.get(4).getValue(); + break; - } - } + case 5: + usrnme = emailConnectorProperties.get(5).getValue(); + break; - properties = new Properties(); + case 6: + psswrd = emailConnectorProperties.get(6).getValue(); + break; - if ( "STARTTLS".equals(protocol) ) { - properties.put("mail.smtp.starttls.enable", "true"); - properties.put("mail.smtp.host", host); - properties.put("mail.smtp.socketFactory.port", port); - properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); - properties.put("mail.smtp.auth", "true"); - properties.put("mail.smtp.port", port); - } - else if ( "SMTP".equals(protocol) ) { - properties.put("mail.smtp.host", host); - properties.put("mail.smtp.port", port); - } - } + default: + break; - private UserRole getCurrentUserRole(EmailTemplateEnum type) { - switch (type) { + } + } - case TEMPLATE_TASK_ASSIGNED_TO_RESOURCE: - return UserRole.ROLE_EMAIL_TASK_ASSIGNED_TO_RESOURCE; + properties = new Properties(); - case TEMPLATE_RESOURCE_REMOVED_FROM_TASK: - return UserRole.ROLE_EMAIL_RESOURCE_REMOVED_FROM_TASK; + if ("STARTTLS".equals(protocol)) { + properties.put("mail.smtp.starttls.enable", "true"); + properties.put("mail.smtp.host", host); + properties.put("mail.smtp.socketFactory.port", port); + properties.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); + properties.put("mail.smtp.auth", "true"); + properties.put("mail.smtp.port", port); + } else if ("SMTP".equals(protocol)) { + properties.put("mail.smtp.host", host); + properties.put("mail.smtp.port", port); + } + } - case TEMPLATE_MILESTONE_REACHED: - return UserRole.ROLE_EMAIL_MILESTONE_REACHED; + private UserRole getCurrentUserRole(EmailTemplateEnum type) { + switch (type) { - case TEMPLATE_TODAY_TASK_SHOULD_START: - return UserRole.ROLE_EMAIL_TASK_SHOULD_START; + case TEMPLATE_TASK_ASSIGNED_TO_RESOURCE: + return UserRole.ROLE_EMAIL_TASK_ASSIGNED_TO_RESOURCE; - case TEMPLATE_TODAY_TASK_SHOULD_FINISH: - return UserRole.ROLE_EMAIL_TASK_SHOULD_FINISH; + case TEMPLATE_RESOURCE_REMOVED_FROM_TASK: + return UserRole.ROLE_EMAIL_RESOURCE_REMOVED_FROM_TASK; - case TEMPLATE_ENTER_DATA_IN_TIMESHEET: - return UserRole.ROLE_EMAIL_TIMESHEET_DATA_MISSING; + case TEMPLATE_MILESTONE_REACHED: + return UserRole.ROLE_EMAIL_MILESTONE_REACHED; - default: - /* There is no other template */ - return null; - } - } + case TEMPLATE_TODAY_TASK_SHOULD_START: + return UserRole.ROLE_EMAIL_TASK_SHOULD_START; + case TEMPLATE_TODAY_TASK_SHOULD_FINISH: + return UserRole.ROLE_EMAIL_TASK_SHOULD_FINISH; + + case TEMPLATE_ENTER_DATA_IN_TIMESHEET: + return UserRole.ROLE_EMAIL_TIMESHEET_DATA_MISSING; + + default: + /* There is no other template */ + return null; + } + } } diff --git a/libreplan-webapp/src/main/resources/i18n/keys.pot b/libreplan-webapp/src/main/resources/i18n/keys.pot index 6cc02d7d7..8e1257a62 100644 --- a/libreplan-webapp/src/main/resources/i18n/keys.pot +++ b/libreplan-webapp/src/main/resources/i18n/keys.pot @@ -9291,6 +9291,10 @@ msgstr "" msgid "Welcome page" msgstr "" +#: libreplan-webapp/src/main/webapp/email/email_templates.zul:124 +msgid "Project details page" +msgstr "" + #: libreplan-business/src/main/java/org/libreplan/business/orders/entities/OrderStatusEnum.java:43 msgid "ARCHIVED" msgstr "" diff --git a/libreplan-webapp/src/main/webapp/email/email_templates.zul b/libreplan-webapp/src/main/webapp/email/email_templates.zul index 75fabff0f..716b1549f 100644 --- a/libreplan-webapp/src/main/webapp/email/email_templates.zul +++ b/libreplan-webapp/src/main/webapp/email/email_templates.zul @@ -118,6 +118,11 @@