Java tutorial
/******************************************************************************* * Crafter Studio Web-content authoring solution * Copyright (C) 2007-2016 Crafter Software Corporation. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package org.craftercms.studio.impl.v1.service.notification; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.exception.ExceptionUtils; import org.craftercms.studio.api.v1.constant.StudioConstants; import org.craftercms.studio.api.v1.constant.DmConstants; import org.craftercms.studio.api.v1.log.Logger; import org.craftercms.studio.api.v1.log.LoggerFactory; import org.craftercms.studio.api.v1.service.GeneralLockService; import org.craftercms.studio.api.v1.service.configuration.ServicesConfig; import org.craftercms.studio.api.v1.service.content.ContentService; import org.craftercms.studio.api.v1.service.notification.NotificationService; import org.craftercms.studio.api.v1.service.security.SecurityService; import org.craftercms.studio.api.v1.service.site.SiteService; import org.craftercms.studio.api.v1.to.ContentItemTO; import org.craftercms.studio.api.v1.to.EmailMessageQueueTo; import org.craftercms.studio.api.v1.to.EmailMessageTO; import org.craftercms.studio.api.v1.to.EmailMessageTemplateTO; import org.craftercms.studio.api.v1.to.MessageTO; import org.craftercms.studio.api.v1.to.NotificationConfigTO; import org.craftercms.studio.api.v1.util.StudioConfiguration; import org.craftercms.studio.impl.v1.util.ContentUtils; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.Node; import static org.craftercms.studio.api.v1.util.StudioConfiguration.CONFIGURATION_SITE_CONFIG_BASE_PATH; import static org.craftercms.studio.api.v1.util.StudioConfiguration.CONFIGURATION_SITE_NOTIFICATIONS_CONFIG_FILE_NAME; import static org.craftercms.studio.api.v1.util.StudioConfiguration.NOTIFICATION_V2_ENABLED; /** * Notification service sends workflow notifications. * Going forward the preference is to use the more general methods in this service * @deprecated This class/interface will beremovee in 2.6 * */ @Deprecated public class NotificationServiceImpl implements NotificationService { private static final Logger logger = LoggerFactory.getLogger(NotificationServiceImpl.class); /** message type key to match configuration **/ protected static final String MESSAGE_MACRO_REJECT_MESSAGE = "$reject-message"; protected static final String MESSAGE_REJECTION = "rejection"; protected static final String MESSAGE_REJECTION_NON_PREVIEWABLE = "rejectionNonPreviewable"; protected static final String MESSAGE_APPROVAL = "approval"; protected static final String MESSAGE_APPROVAL_NONPREVIEWABLE = "approvalNonPreviewable"; protected static final String MESSAGE_DELETE_APPROVAL = "deleteApproval"; protected static final String MESSAGE_CONTENT_SUBMISSION = "contentSubmission"; protected static final String MESSAGE_CONTENT_NOPREVIEWABLE_SUBMISSION = "contentNoPreviewableSubmission"; protected static final String MESSAGE_CONTENT_SUBMISSION_FOR_DELETE = "contentSubmissionForDelete"; protected static final String MESSAGE_CONTENT_NOPREVIEWABLE_SUBMISSION_FOR_DELETE = "contentNoPreviewableSubmissionForDelete"; protected static final String MESSAGE_DEPLOYMENT_FAILURE = "deploymentFailure"; protected static final String MESSAGE_CONTENT_DATE_FORMAT = "EEE, d MMM yyyy HH:mm:ss z"; protected EmailMessageQueueTo emailMessages; protected String previewBaseUrl = null; protected String liveBaseUrl = null; protected ServicesConfig servicesConfig; protected SiteService siteService; protected SecurityService securityService; protected ContentService contentService; protected StudioConfiguration studioConfiguration; protected static final String VAR_NOTIFICATION_TEMPLATE_NAME = "[NOTIFICATION_TEMPLATE]"; protected static final String VAR_REASON = "[REASON]"; protected static final String DEFAULT_CONTENT_SUBJECT = "Content workflow notification"; protected static final String DEFAULT_CONTENT_BODY = "This is a content workflow notification. \n Notification template [NOTIFICATION_TEMPLATE] has not been not configured."; public String getConfigPath() { return studioConfiguration.getProperty(CONFIGURATION_SITE_CONFIG_BASE_PATH); } public String getConfigFileName() { return studioConfiguration.getProperty(CONFIGURATION_SITE_NOTIFICATIONS_CONFIG_FILE_NAME); } public boolean isNewNotificationEnabled() { boolean toReturn = Boolean.parseBoolean(studioConfiguration.getProperty(NOTIFICATION_V2_ENABLED)); return toReturn; } public StudioConfiguration getStudioConfiguration() { return studioConfiguration; } public void setStudioConfiguration(StudioConfiguration studioConfiguration) { this.studioConfiguration = studioConfiguration; } public String getPreviewBaseUrl() { return previewBaseUrl; } public void setPreviewBaseUrl(String previewBaseUrl) { this.previewBaseUrl = previewBaseUrl; } public String getLiveBaseUrl() { return liveBaseUrl; } public void setLiveBaseUrl(String liveBaseUrl) { this.liveBaseUrl = liveBaseUrl; } public ServicesConfig getServicesConfig() { return servicesConfig; } public void setServicesConfig(ServicesConfig servicesConfig) { this.servicesConfig = servicesConfig; } public SiteService getSiteService() { return siteService; } public void setSiteService(SiteService siteService) { this.siteService = siteService; } public SecurityService getSecurityService() { return securityService; } public void setSecurityService(SecurityService securityService) { this.securityService = securityService; } public ContentService getContentService() { return contentService; } public void setContentService(ContentService contentService) { this.contentService = contentService; } @Override public boolean sendNotice(String site, String action) { NotificationConfigTO config = getNotificationConfig(site); if (config != null) { Boolean sendNotice = config.getSendNoticeMapping().get(action); if (sendNotice != null) { return sendNotice.booleanValue(); } } return true; } protected NotificationConfigTO getNotificationConfig(final String site) { return loadConfiguration(site); } @Override public String getGeneralMessage(String site, String key) { NotificationConfigTO config = getNotificationConfig(site); if (config != null) { Map<String, String> messages = config.getMessages(); if (messages != null) { return messages.get(key); } } return ""; } @Override public List<MessageTO> getCannedRejectionReasons(final String site) { NotificationConfigTO config = getNotificationConfig(site); if (config != null) { Map<String, List<MessageTO>> messages = config.getCannedMessages(); if (messages != null) { return messages.get(MESSAGE_REJECTION); } } return null; } public EmailMessageTemplateTO getRejectionEmailMessageTemplate(final String site) { NotificationConfigTO config = getNotificationConfig(site); if (config != null) { Map<String, EmailMessageTemplateTO> messages = config.getEmailMessageTemplates(); if (messages != null) { return messages.get(MESSAGE_REJECTION); } } return null; } public EmailMessageTemplateTO getRejectionNonPreviewableEmailMessageTemplate(final String site) { NotificationConfigTO config = getNotificationConfig(site); if (config != null) { Map<String, EmailMessageTemplateTO> messages = config.getEmailMessageTemplates(); if (messages != null) { return messages.get(MESSAGE_REJECTION_NON_PREVIEWABLE); } } return null; } public EmailMessageTemplateTO getApprovalEmailMessageTemplate(final String site) { NotificationConfigTO config = getNotificationConfig(site); if (config != null) { Map<String, EmailMessageTemplateTO> messages = config.getEmailMessageTemplates(); if (messages != null) { return messages.get(MESSAGE_APPROVAL); } } return null; } public EmailMessageTemplateTO getApprovalNonPreviewableEmailMessageTemplate(final String site) { NotificationConfigTO config = getNotificationConfig(site); if (config != null) { Map<String, EmailMessageTemplateTO> messages = config.getEmailMessageTemplates(); if (messages != null) { return messages.get(MESSAGE_APPROVAL_NONPREVIEWABLE); } } return null; } public EmailMessageTemplateTO getDeleteApprovalEmailMessageTemplate(final String site) { NotificationConfigTO config = getNotificationConfig(site); if (config != null) { Map<String, EmailMessageTemplateTO> messages = config.getEmailMessageTemplates(); if (messages != null) { return messages.get(MESSAGE_DELETE_APPROVAL); } } return null; } public EmailMessageTemplateTO getContentSubmissionEmailMessageTemplate(final String site) { NotificationConfigTO config = getNotificationConfig(site); if (config != null) { Map<String, EmailMessageTemplateTO> messages = config.getEmailMessageTemplates(); if (messages != null) { return messages.get(MESSAGE_CONTENT_SUBMISSION); } } return null; } public EmailMessageTemplateTO getContentSubmissionNoPreviewableEmailMessageTemplate(final String site) { NotificationConfigTO config = getNotificationConfig(site); if (config != null) { Map<String, EmailMessageTemplateTO> messages = config.getEmailMessageTemplates(); if (messages != null) { return messages.get(MESSAGE_CONTENT_NOPREVIEWABLE_SUBMISSION); } } return null; } public EmailMessageTemplateTO getContentSubmissionForDeleteEmailMessageTemplate(final String site) { NotificationConfigTO config = getNotificationConfig(site); if (config != null) { Map<String, EmailMessageTemplateTO> messages = config.getEmailMessageTemplates(); if (messages != null) { return messages.get(MESSAGE_CONTENT_SUBMISSION_FOR_DELETE); } } return null; } public EmailMessageTemplateTO getContentSubmissionForDeleteNoPreviewableEmailMessageTemplate( final String site) { NotificationConfigTO config = getNotificationConfig(site); if (config != null) { Map<String, EmailMessageTemplateTO> messages = config.getEmailMessageTemplates(); if (messages != null) { return messages.get(MESSAGE_CONTENT_NOPREVIEWABLE_SUBMISSION_FOR_DELETE); } } return null; } @Override public String getCompleteMessage(final String site, final String key) { NotificationConfigTO config = getNotificationConfig(site); if (config != null) { Map<String, String> messages = config.getCompleteMessages(); if (messages != null) { return messages.get(key); } } return ""; } @Override public String getErrorMessage(String site, String key, Map<String, String> params) { NotificationConfigTO config = getNotificationConfig(site); if (config != null) { Map<String, String> messages = config.getErrorMessages(); if (messages != null) { String s = messages.get(key); for (Map.Entry<String, String> param : params.entrySet()) { s = s.replaceAll("\\$" + param.getKey(), param.getValue()); } return s; } } return ""; } public EmailMessageTemplateTO getDeploymentFailureMessage(final String site) { NotificationConfigTO config = getNotificationConfig(site); if (config != null) { Map<String, EmailMessageTemplateTO> messages = config.getEmailMessageTemplates(); if (messages != null) { return messages.get(MESSAGE_DEPLOYMENT_FAILURE); } } return null; } @Override public void sendContentSubmissionNotification(String site, String to, String browserUrl, String from, Date scheduledDate, boolean isPreviewable, boolean isDelete) { String subject = DEFAULT_CONTENT_SUBJECT; String message = DEFAULT_CONTENT_BODY; String templateType = MESSAGE_CONTENT_SUBMISSION; try { EmailMessageTemplateTO template = null; if (isDelete) { if (isPreviewable) { template = getContentSubmissionForDeleteEmailMessageTemplate(site); templateType = MESSAGE_CONTENT_SUBMISSION_FOR_DELETE; } else { template = getContentSubmissionForDeleteNoPreviewableEmailMessageTemplate(site); templateType = MESSAGE_CONTENT_NOPREVIEWABLE_SUBMISSION_FOR_DELETE; } } else if (!isPreviewable) { template = getContentSubmissionNoPreviewableEmailMessageTemplate(site); templateType = MESSAGE_CONTENT_NOPREVIEWABLE_SUBMISSION; } else { template = getContentSubmissionEmailMessageTemplate(site); templateType = MESSAGE_CONTENT_SUBMISSION; } message = message.replace(VAR_NOTIFICATION_TEMPLATE_NAME, templateType); if (template != null) { subject = template.getSubject(); message = template.getMessage(); } notifyUser(site, to, message, subject, from, browserUrl, ""); } catch (Exception e) { logger.error("Could not queue the content submission notification:", e); } } @Override public void sendContentSubmissionNotificationToApprovers(String site, String to, String browserUrl, String from, Date scheduledDate, boolean isPreviewable, boolean isDelete) { if (isNewNotificationEnabled()) { String subject = DEFAULT_CONTENT_SUBJECT; String message = DEFAULT_CONTENT_BODY; String templateType = MESSAGE_CONTENT_SUBMISSION; try { NotificationConfigTO config = getNotificationConfig(site); if (config != null && config.getSubmitNotificationsMapping() != null) { Map<String, String> rules = config.getSubmitNotificationsMapping(); String toAddress = StringUtils.EMPTY; for (String rule : rules.keySet()) { Pattern p = Pattern.compile(rule); Matcher m = p.matcher(browserUrl); if (m.matches()) { toAddress = rules.get(rule); break; } } if (StringUtils.isNotEmpty(toAddress)) { EmailMessageTemplateTO template = null; if (isDelete) { if (isPreviewable) { template = getContentSubmissionForDeleteEmailMessageTemplate(site); templateType = MESSAGE_CONTENT_SUBMISSION_FOR_DELETE; } else { template = getContentSubmissionForDeleteNoPreviewableEmailMessageTemplate(site); templateType = MESSAGE_CONTENT_NOPREVIEWABLE_SUBMISSION_FOR_DELETE; } } else if (!isPreviewable) { template = getContentSubmissionNoPreviewableEmailMessageTemplate(site); templateType = MESSAGE_CONTENT_NOPREVIEWABLE_SUBMISSION; } else { template = getContentSubmissionEmailMessageTemplate(site); templateType = MESSAGE_CONTENT_SUBMISSION; } message = message.replace(VAR_NOTIFICATION_TEMPLATE_NAME, templateType); if (template != null) { subject = template.getSubject(); message = template.getMessage(); } logger.debug("Notifying user:" + toAddress); if (previewBaseUrl == null) { previewBaseUrl = siteService.getPreviewServerUrl(site); } if (liveBaseUrl == null) { liveBaseUrl = siteService.getLiveServerUrl(site); } Map<String, String> fromProfile = securityService.getUserProfile(from); final String userFirstName = fromProfile.get("firstName"); final String userLastName = fromProfile.get("lastName"); final String replyTo = fromProfile.get("email"); String fromPersonalName = ""; if (userFirstName != null) { fromPersonalName = userFirstName + " "; } if (userLastName != null) { fromPersonalName += userLastName; } EmailMessageTO emailMessage = new EmailMessageTO(subject, message, toAddress); emailMessage.setPreviewBaseUrl(previewBaseUrl); emailMessage.setLiveBaseUrl(liveBaseUrl); // reading item internal-name for email title String itemName = ""; boolean isDocument = false; boolean isExternalDocument = false; String documentUrl = ""; String browserUri = ""; ContentItemTO contentItem = contentService.getContentItem(site, browserUrl, 0); if (contentItem != null) { itemName = contentItem.getInternalName(); browserUri = contentItem.getBrowserUri(); if (contentItem.isPreviewable() && contentItem.isDocument()) { isDocument = true; } } String name = ContentUtils.getPageName(browserUrl); String folderPath = (name.equals(DmConstants.INDEX_FILE)) ? browserUrl.replace("/" + name, "") : browserUrl; String internalName = folderPath; int index = folderPath.lastIndexOf('/'); if (index != -1) { internalName = folderPath.substring(index + 1); } internalName = StringUtils.isEmpty(itemName) ? internalName : itemName; emailMessage.setPersonalFromName(fromPersonalName); emailMessage.setTitle(internalName); // set browser URL if (isDocument) { if (isExternalDocument) { emailMessage.setBrowserUrlForExternalDocument(documentUrl); } else { emailMessage.setBrowserUrl(documentUrl); } } else { emailMessage.setBrowserUrl(browserUri); } if (replyTo != null) emailMessage.setReplyTo(replyTo); logger.debug("Queuing notification email request for user:" + toAddress); emailMessages.addEmailMessage(emailMessage); } else { sendContentSubmissionNotification(site, to, browserUrl, from, scheduledDate, isPreviewable, isDelete); } } else { sendContentSubmissionNotification(site, to, browserUrl, from, scheduledDate, isPreviewable, isDelete); } } catch (Exception e) { logger.error("Could not queue the content submission notification:", e); } } } @Override public void sendDeleteApprovalNotification(String site, String to, String browserUrl, String from) { String subject = DEFAULT_CONTENT_SUBJECT; String message = DEFAULT_CONTENT_BODY; String templateType = MESSAGE_DELETE_APPROVAL; message = message.replace(VAR_NOTIFICATION_TEMPLATE_NAME, templateType); try { EmailMessageTemplateTO template = getDeleteApprovalEmailMessageTemplate(site); if (template != null) { subject = template.getSubject(); message = template.getMessage(); } notifyUser(site, to, message, subject, from, browserUrl, ""); } catch (Exception e) { logger.error("Could not queue the content delete approval notification:", e); } } public void setEmailMessages(EmailMessageQueueTo emailMessages) { this.emailMessages = emailMessages; } @Override public void sendGenericNotification(String site, String path, String to, String from, String key, Map<String, String> params) { try { EmailMessageTemplateTO template = null; NotificationConfigTO config = getNotificationConfig(site); if (config != null) { Map<String, EmailMessageTemplateTO> messages = config.getEmailMessageTemplates(); if (messages != null) template = messages.get(key); } if (template == null) { throw new RuntimeException("No email-message-template: " + key); } else { String subject = template.getSubject(); String message = template.getMessage(); if (params != null) { for (String name : params.keySet()) { String value = params.get(name); message = message.replaceAll("\\$" + name, value); } } notifyUser(site, to, message, subject, from, path, null); } } catch (Exception e) { logger.error("Could not queue the notification:", e); } } @Override public void sendDeploymentFailureNotification(String site, Throwable error) { try { EmailMessageTemplateTO template = getDeploymentFailureMessage(site); if (template == null) { throw new RuntimeException("No email-message-template for deployment failure"); } else { String subject = template.getSubject(); String message = template.getMessage(); StringBuilder sb = new StringBuilder(message); sb.append("\n\n").append(ExceptionUtils.getFullStackTrace(error)); message = sb.toString(); List<String> toAdrresses = getNotificationConfig(site).getDeploymentFailureNotifications(); if (CollectionUtils.isNotEmpty(toAdrresses)) { for (String toAddress : toAdrresses) { logger.debug("Sending notification to :" + toAddress); if (StringUtils.isEmpty(toAddress)) { logger.error("to User is empty or Null, not sending any email"); return; } EmailMessageTO emailMessage = new EmailMessageTO(subject, message, toAddress); logger.debug("Queuing notification email to: " + toAddress); emailMessages.addEmailMessage(emailMessage); } } } } catch (Exception e) { logger.error("Could not queue the notification:", e); } } protected NotificationConfigTO loadConfiguration(final String site) { String configFullPath = getConfigPath().replaceFirst(StudioConstants.PATTERN_SITE, site); configFullPath = configFullPath + "/" + getConfigFileName(); NotificationConfigTO config = null; try { Document document = contentService.getContentAsDocument(site, configFullPath); if (document != null) { Element root = document.getRootElement(); config = new NotificationConfigTO(); Node configNode = root.selectSingleNode("/notification-config"); if (configNode != null) { loadCannedMessages(config, configNode.selectNodes("canned-messages/messages")); loadEmailMessageTemplates(config, configNode.selectNodes("email-message-templates/email-message-template")); Map<String, String> completeMessages = loadMessages( configNode.selectNodes("complete-messages/message")); Map<String, String> errorMessages = loadMessages( configNode.selectNodes("error-messages/message")); config.setCompleteMessages(completeMessages); config.setErrorMessages(errorMessages); Map<String, String> generalMessages = loadMessages( configNode.selectNodes("general-messages/message")); config.setMessages(generalMessages); Map<String, Boolean> noticeMapping = loadSendNoticeMapping( configNode.selectSingleNode("send-notifications")); config.setSendNoticeMapping(noticeMapping); Map<String, String> submitNotificationRules = loadSubmitNotificationRules( configNode.selectSingleNode("submit-notifications")); config.setSubmitNotificationsMapping(submitNotificationRules); List<String> deploymentFailureNotifications = loadDeploymentFailureNotifications( configNode.selectSingleNode("deployment-failure")); config.setDeploymentFailureNotifications(deploymentFailureNotifications); config.setSite(site); config.setLastUpdated(new Date()); } else { logger.error("Notification config is not found for " + site); } } } catch (Exception ex) { logger.error("Notification config is not found for " + site, ex); } return config; } protected Map<String, String> loadSubmitNotificationRules(Node node) { Map<String, String> submitNotificationMapping = new HashMap<String, String>(); if (node != null) { Element element = (Element) node; List<Element> childElements = element.elements(); if (childElements != null && childElements.size() > 0) { for (Element childElement : childElements) { String regex = childElement.attributeValue("regex"); Node addressNode = childElement.selectSingleNode("email"); String value = addressNode.getText(); // default to true if (!StringUtils.isEmpty(regex) && !StringUtils.isEmpty(value)) { submitNotificationMapping.put(regex, value); } } } } return submitNotificationMapping; } protected List<String> loadDeploymentFailureNotifications(Node node) { List<String> deploymentFailureNotifications = new ArrayList<String>(); if (node != null) { Element element = (Element) node; List<Element> childElements = element.elements(); if (childElements != null && childElements.size() > 0) { for (Element childElement : childElements) { String value = childElement.getText(); if (!StringUtils.isEmpty(value) && !StringUtils.isEmpty(value)) { deploymentFailureNotifications.add(value); } } } } return deploymentFailureNotifications; } /** * load send notice mapping * * @param node * @return */ protected Map<String, Boolean> loadSendNoticeMapping(Node node) { Map<String, Boolean> noticeMapping = new HashMap<String, Boolean>(); if (node != null) { Element element = (Element) node; List<Element> childElements = element.elements(); if (childElements != null && childElements.size() > 0) { for (Element childElement : childElements) { String action = childElement.getName(); String value = childElement.getText(); // default to true Boolean sendNotice = (!StringUtils.isEmpty(value) && value.equals("false")) ? false : true; if (!StringUtils.isEmpty(action)) { noticeMapping.put(action, sendNotice); } } } } return noticeMapping; } /** * load messages from the given nodes * * notification config to store messages * @param nodes * message nodes */ protected Map<String, String> loadMessages(final List<Node> nodes) { if (nodes != null) { Map<String, String> messagesMap = new HashMap<String, String>(); for (Node node : nodes) { String name = node.valueOf("@name"); if (!StringUtils.isEmpty(name)) { String message = node.getText(); messagesMap.put(name, message); } } return messagesMap; } return null; } /** * load canned messages from the configuration file * * @param config * notification config to store messages * @param nodes * canned messages nodes * @return a list of canned messages */ @SuppressWarnings("unchecked") protected void loadCannedMessages(final NotificationConfigTO config, final List<Node> nodes) { if (nodes != null) { Map<String, List<MessageTO>> messageMap = new HashMap<String, List<MessageTO>>(); for (Node listNode : nodes) { String name = listNode.valueOf("@name"); if (!StringUtils.isEmpty(name)) { List<Node> messageNodes = listNode.selectNodes("message"); if (messageNodes != null) { List<MessageTO> messages = new ArrayList<MessageTO>(messageNodes.size()); for (Node messageNode : messageNodes) { MessageTO message = new MessageTO(); message.setTitle(messageNode.valueOf("title")); message.setBody(messageNode.valueOf("body")); message.setKey(((Element) messageNode).attributeValue("key", "")); messages.add(message); } messageMap.put(name, messages); } } } config.setCannedMessages(messageMap); } } protected void loadEmailMessageTemplates(final NotificationConfigTO config, final List<Node> nodes) { if (nodes != null) { Map<String, EmailMessageTemplateTO> messageMap = new HashMap<String, EmailMessageTemplateTO>(); for (Node listNode : nodes) { String name = listNode.valueOf("@name"); if (!StringUtils.isEmpty(name)) { EmailMessageTemplateTO message = new EmailMessageTemplateTO(); message.setSubject(listNode.valueOf("Subject")); message.setMessage(listNode.valueOf("message")); messageMap.put(name, message); } } config.setEmailMessageTemplates(messageMap); } } @Override public void sendRejectionNotification(String site, String to, String browserUrl, String reason, String from, boolean isPreviewable) { String subject = DEFAULT_CONTENT_SUBJECT; String message = DEFAULT_CONTENT_BODY; String templateType = MESSAGE_REJECTION; try { EmailMessageTemplateTO template = null; if (isPreviewable) { template = getRejectionEmailMessageTemplate(site); } else { template = this.getRejectionNonPreviewableEmailMessageTemplate(site); templateType = MESSAGE_REJECTION_NON_PREVIEWABLE; } message = message.replace(VAR_NOTIFICATION_TEMPLATE_NAME, templateType); if (template != null) { subject = template.getSubject(); message = template.getMessage(); } if (StringUtils.isNotEmpty(reason)) { message = message.replace(VAR_REASON, reason); message = message.replace(MESSAGE_MACRO_REJECT_MESSAGE, reason); } notifyUser(site, to, message, subject, from, browserUrl, reason); } catch (Exception e) { logger.error("Could not queue the rejection notification:", e); } } @Override public void sendApprovalNotification(String site, String to, String browserUrl, String from) { String subject = DEFAULT_CONTENT_SUBJECT; String message = DEFAULT_CONTENT_BODY; String templateType = MESSAGE_APPROVAL; try { logger.debug("Sending approval notification to:" + to); boolean isPreviewable = true; try { ContentItemTO contentItem = contentService.getContentItem(site, browserUrl); isPreviewable = contentItem.isPreviewable(); } catch (Exception e) { logger.error("during Notification send item name read failed", e); } EmailMessageTemplateTO template = null; if (isPreviewable) { template = getApprovalEmailMessageTemplate(site); } else { template = getApprovalNonPreviewableEmailMessageTemplate(site); templateType = MESSAGE_APPROVAL_NONPREVIEWABLE; } message = message.replace(VAR_NOTIFICATION_TEMPLATE_NAME, templateType); if (template != null) { subject = template.getSubject(); message = template.getMessage(); } notifyUser(site, to, message, subject, from, browserUrl, ""); } catch (Exception e) { logger.error("Could not queue the approval notification:", e); } } protected void notifyUser(final String site, final String toUser, final String content, final String subject, final String fromUser, String relativeUrl, String rejectReason) { if (isNewNotificationEnabled()) { return; } logger.debug("Notifying user:" + toUser); if (StringUtils.isEmpty(toUser)) { logger.error("to User is empty or Null, not sending any email"); return; } if (previewBaseUrl == null) { previewBaseUrl = siteService.getPreviewServerUrl(site); } if (liveBaseUrl == null) { liveBaseUrl = siteService.getLiveServerUrl(site); } String authoringBaseUrl = siteService.getAuthoringServerUrl(site); String adminEmailAddress = siteService.getAdminEmailAddress(site); String userEmailAddress = ""; if (StringUtils.isEmpty(userEmailAddress)) { Map<String, String> profile = securityService.getUserProfile(toUser); if (profile != null) { userEmailAddress = profile.get("email"); } } if (StringUtils.isEmpty(userEmailAddress)) { logger.error("Not able to find valid email address for user " + toUser + ", not sending any email"); return; } Map<String, String> fromProfile = securityService.getUserProfile(fromUser); final String userFirstName = fromProfile.get("firstName"); final String userLastName = fromProfile.get("lastName"); final String replyTo = fromProfile.get("email"); String fromPersonalName = ""; if (userFirstName != null) { fromPersonalName = userFirstName + " "; } if (userLastName != null) { fromPersonalName += userLastName; } EmailMessageTO emailMessage = new EmailMessageTO(subject, content, userEmailAddress); emailMessage.setPreviewBaseUrl(previewBaseUrl); emailMessage.setLiveBaseUrl(liveBaseUrl); emailMessage.setAuthoringBaseUrl(authoringBaseUrl); if (StringUtils.isNotEmpty(rejectReason)) { emailMessage.setRejectReason(rejectReason); } // reading item internal-name for email title String itemName = ""; boolean isDocument = false; boolean isExternalDocument = false; String documentUrl = ""; String browserUri = ""; ContentItemTO contentItem = contentService.getContentItem(site, relativeUrl, 0); if (contentItem != null) { itemName = contentItem.getInternalName(); browserUri = contentItem.getBrowserUri(); if (contentItem.isPreviewable() && contentItem.isDocument()) { isDocument = true; String documentUrlProperty = ""; } } String name = ContentUtils.getPageName(relativeUrl); String folderPath = (name.equals(DmConstants.INDEX_FILE)) ? relativeUrl.replace("/" + name, "") : relativeUrl; String internalName = folderPath; int index = folderPath.lastIndexOf('/'); if (index != -1) { internalName = folderPath.substring(index + 1); } internalName = StringUtils.isEmpty(itemName) ? internalName : itemName; emailMessage.setPersonalFromName(fromPersonalName); emailMessage.setTitle(internalName); emailMessage.setAdminEmail(adminEmailAddress); // set browser URL if (isDocument) { if (isExternalDocument) { emailMessage.setBrowserUrlForExternalDocument(documentUrl); } else { emailMessage.setBrowserUrl(documentUrl); } } else { emailMessage.setBrowserUrl(browserUri); } if (replyTo != null) emailMessage.setReplyTo(replyTo); logger.debug("Queuing notification email request for user:" + userEmailAddress); emailMessages.addEmailMessage(emailMessage); } protected String getDateInSpecificTimezone(Date dt, String site) { String ret = ""; try { SimpleDateFormat fmt = new SimpleDateFormat(MESSAGE_CONTENT_DATE_FORMAT); fmt.setTimeZone(TimeZone.getTimeZone(servicesConfig.getDefaultTimezone(site))); ret = (fmt.format(dt)).toString(); } catch (Exception e) { logger.error("Date cannot be converted", e); } return ret; } @Override public void reloadConfiguration(String site) { NotificationConfigTO config = loadConfiguration(site); } public GeneralLockService getGeneralLockService() { return generalLockService; } public void setGeneralLockService(GeneralLockService generalLockService) { this.generalLockService = generalLockService; } protected GeneralLockService generalLockService; }