From: <man...@us...> - 2009-12-08 12:50:15
|
Revision: 1332 http://j-trac.svn.sourceforge.net/j-trac/?rev=1332&view=rev Author: manfredwolff Date: 2009-12-08 12:50:07 +0000 (Tue, 08 Dec 2009) Log Message: ----------- Fixing #2859128: Duplicate Emails if assignee is also in the cc list. Modified Paths: -------------- trunk/jtrac/src/main/java/info/jtrac/mail/MailSender.java Modified: trunk/jtrac/src/main/java/info/jtrac/mail/MailSender.java =================================================================== --- trunk/jtrac/src/main/java/info/jtrac/mail/MailSender.java 2009-12-08 12:48:25 UTC (rev 1331) +++ trunk/jtrac/src/main/java/info/jtrac/mail/MailSender.java 2009-12-08 12:50:07 UTC (rev 1332) @@ -164,7 +164,10 @@ } // prepare message MimeMessage message = sender.createMimeMessage(); - MimeMessageHelper helper = new MimeMessageHelper(message, "UTF-8"); + MimeMessageHelper helper = new MimeMessageHelper(message, "UTF-8"); + + // Remember the TO person email to prevent duplicate mails + String toPersonEmail; try { helper.setText(addHeaderAndFooter(sb), true); helper.setSubject(getSubject(item)); @@ -173,20 +176,29 @@ // set TO if (item.getAssignedTo() != null) { helper.setTo(item.getAssignedTo().getEmail()); + toPersonEmail = item.getAssignedTo().getEmail(); } else { helper.setTo(item.getLoggedBy().getEmail()); + toPersonEmail = item.getLoggedBy().getEmail(); } // set CC if (item.getItemUsers() != null) { String[] cc = new String[item.getItemUsers().size()]; int i = 0; for (ItemUser itemUser : item.getItemUsers()) { - cc[i++] = itemUser.getUser().getEmail(); + // Send only, if person is not the TO assignee + if (! toPersonEmail.equals(itemUser.getUser().getEmail())) { + cc[i++] = itemUser.getUser().getEmail(); + } } helper.setCc(cc); } // send message - sendInNewThread(message); + // workaround: Some PSEUDO user has no email address. Because email address + // is mandatory, you can enter "no" in email address and the mail will not + // be sent. + if (! "no".equals(toPersonEmail)) + sendInNewThread(message); } catch (Exception e) { logger.error("failed to prepare e-mail", e); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <man...@us...> - 2010-09-02 09:42:42
|
Revision: 1355 http://j-trac.svn.sourceforge.net/j-trac/?rev=1355&view=rev Author: manfredwolff Date: 2010-09-02 09:42:35 +0000 (Thu, 02 Sep 2010) Log Message: ----------- Bugfix: There was sometimes a problem if a person was assignee and in the cc list. Modified Paths: -------------- trunk/jtrac/src/main/java/info/jtrac/mail/MailSender.java Modified: trunk/jtrac/src/main/java/info/jtrac/mail/MailSender.java =================================================================== --- trunk/jtrac/src/main/java/info/jtrac/mail/MailSender.java 2010-08-31 06:27:07 UTC (rev 1354) +++ trunk/jtrac/src/main/java/info/jtrac/mail/MailSender.java 2010-09-02 09:42:35 UTC (rev 1355) @@ -20,14 +20,20 @@ import info.jtrac.domain.ItemUser; import info.jtrac.domain.User; import info.jtrac.util.ItemUtils; + +import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.Enumeration; +import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; + import javax.mail.Header; import javax.mail.Session; import javax.mail.internet.MimeMessage; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.MessageSource; @@ -40,281 +46,307 @@ * Class to handle sending of E-mail and pre-formatted messages */ public class MailSender { - - private final Logger logger = LoggerFactory.getLogger(getClass()); - - private JavaMailSenderImpl sender; - private String prefix; - private String from; - private String url; - private MessageSource messageSource; - private Locale defaultLocale; - - public MailSender(Map<String, String> config, MessageSource messageSource, String defaultLocale) { - // initialize email sender - this.messageSource = messageSource; - this.defaultLocale = StringUtils.parseLocaleString(defaultLocale); - String mailSessionJndiName = config.get("mail.session.jndiname"); - if(StringUtils.hasText(mailSessionJndiName)) { - initMailSenderFromJndi(mailSessionJndiName); - } - if(sender == null) { - initMailSenderFromConfig(config); - } - // if sender is still null the send* methods will not - // do anything when called and will just return immediately - String tempUrl = config.get("jtrac.url.base"); - if(tempUrl == null) { - tempUrl = "http://localhost/jtrac/"; - } - if (!tempUrl.endsWith("/")) { - tempUrl = tempUrl + "/"; - } - this.url = tempUrl; - logger.info("email hyperlink base url set to '" + this.url + "'"); - } - /** - * we bend the rules a little and fire off a new thread for sending - * an email message. This has the advantage of not slowing down the item - * create and update screens, i.e. the system returns the next screen - * after "submit" without blocking. This has been used in production - * (and now I guess in many JTrac installations worldwide) - * for quite a while now, on Tomcat without any problems. This helps a lot - * especially when the SMTP server is slow to respond, etc. - */ - private void sendInNewThread(final MimeMessage message) { - new Thread(){ - @Override - public void run() { - logger.debug("send mail thread start"); - try { - try { - sender.send(message); - logger.debug("send mail thread successfull"); - } catch (Exception e) { - logger.error("send mail thread failed", e); - logger.error("mail headers dump start"); - Enumeration headers = message.getAllHeaders(); - while(headers.hasMoreElements()) { - Header h = (Header) headers.nextElement(); - logger.info(h.getName() + ": " + h.getValue()); - } - logger.error("mail headers dump end"); - } - } catch(Exception e) { - throw new RuntimeException(e); - } - } - }.start(); - } - - private String fmt(String key, Locale locale) { - try { - return messageSource.getMessage("mail_sender." + key, null, locale); - } catch (Exception e) { - logger.debug(e.getMessage()); - return "???mail_sender." + key + "???"; - } - } + private final Logger logger = LoggerFactory.getLogger(getClass()); - private String addHeaderAndFooter(StringBuffer html) { - StringBuffer sb = new StringBuffer(); - // additional cosmetic tweaking of e-mail layout - // style just after the body tag does not work for a minority of clients like gmail, thunderbird etc. - // ItemUtils adds the main inline CSS when generating the email content, so we gracefully degrade - sb.append("<html><body><style type='text/css'>table.jtrac th, table.jtrac td { padding-left: 0.2em; padding-right: 0.2em; }</style>"); - sb.append(html); - sb.append("</html>"); - return sb.toString(); - } - - private String getItemViewAnchor(Item item, Locale locale) { - String itemUrl = url + "app/item/" + item.getRefId(); - return "<p style='font-family: Arial; font-size: 75%'><a href='" + itemUrl + "'>" + itemUrl + "</a></p>"; - } - - private String getSubject(Item item) { - String summary = null; - if (item.getSummary() == null) { - summary = ""; - } else if (item.getSummary().length() > 80) { - summary = item.getSummary().substring(0, 80); - } else { - summary = item.getSummary(); - } - return prefix + " #" + item.getRefId() + " " + summary; - } - - public void send(Item item) { - if (sender == null) { - logger.debug("mail sender is null, not sending notifications"); - return; - } - // TODO make this locale sensitive per recipient - logger.debug("attempting to send mail for item update"); - // prepare message content - StringBuffer sb = new StringBuffer(); - String anchor = getItemViewAnchor(item, defaultLocale); - sb.append(anchor); - sb.append(ItemUtils.getAsHtml(item, messageSource, defaultLocale)); - sb.append(anchor); - if (logger.isDebugEnabled()) { - logger.debug("html content: " + sb); - } - // prepare message - MimeMessage message = sender.createMimeMessage(); - MimeMessageHelper helper = new MimeMessageHelper(message, "UTF-8"); - - // Remember the TO person email to prevent duplicate mails - String toPersonEmail; - try { - helper.setText(addHeaderAndFooter(sb), true); - helper.setSubject(getSubject(item)); - helper.setSentDate(new Date()); - helper.setFrom(from); - // set TO - if (item.getAssignedTo() != null) { - helper.setTo(item.getAssignedTo().getEmail()); - toPersonEmail = item.getAssignedTo().getEmail(); - } else { - helper.setTo(item.getLoggedBy().getEmail()); - toPersonEmail = item.getLoggedBy().getEmail(); - } - // set CC - if (item.getItemUsers() != null) { - String[] cc = new String[item.getItemUsers().size()]; - int i = 0; - for (ItemUser itemUser : item.getItemUsers()) { - // Send only, if person is not the TO assignee - if (! toPersonEmail.equals(itemUser.getUser().getEmail())) { - cc[i++] = itemUser.getUser().getEmail(); - } - } - helper.setCc(cc); - } - // send message - // workaround: Some PSEUDO user has no email address. Because email address - // is mandatory, you can enter "no" in email address and the mail will not - // be sent. - if (! "no".equals(toPersonEmail)) - sendInNewThread(message); - } catch (Exception e) { - logger.error("failed to prepare e-mail", e); - } - } - - public void sendUserPassword(User user, String clearText) { - if (sender == null) { - logger.debug("mail sender is null, not sending new user / password change notification"); - return; - } - logger.debug("attempting to send mail for user password"); - String localeString = user.getLocale(); - Locale locale = null; - if(localeString == null) { - locale = defaultLocale; - } else { - locale = StringUtils.parseLocaleString(localeString); - } - MimeMessage message = sender.createMimeMessage(); - MimeMessageHelper helper = new MimeMessageHelper(message, "UTF-8"); - try { - helper.setTo(user.getEmail()); - helper.setSubject(prefix + " " + fmt("loginMailSubject", locale)); - StringBuffer sb = new StringBuffer(); - sb.append("<p>" + fmt("loginMailGreeting", locale) + " " + user.getName()+ ",</p>"); - sb.append("<p>" + fmt("loginMailLine1", locale) + "</p>"); - sb.append("<table class='jtrac'>"); - sb.append("<tr><th style='background: #CCCCCC'>" + fmt("loginName", locale) - + "</th><td style='border: 1px solid black'>" + user.getLoginName() + "</td></tr>"); - sb.append("<tr><th style='background: #CCCCCC'>" + fmt("password", locale) - + "</th><td style='border: 1px solid black'>" + clearText + "</td></tr>"); - sb.append("</table>"); - sb.append("<p>" + fmt("loginMailLine2", locale) + "</p>"); - sb.append("<p><a href='" + url + "'>" + url + "</a></p>"); - helper.setText(addHeaderAndFooter(sb), true); - helper.setSentDate(new Date()); - // helper.setCc(from); - helper.setFrom(from); - sendInNewThread(message); - } catch (Exception e) { - logger.error("failed to prepare e-mail", e); - } - } - - private void initMailSenderFromJndi(String mailSessionJndiName) { - logger.info("attempting to initialize mail sender from jndi name = '" + mailSessionJndiName + "'"); - JndiObjectFactoryBean factoryBean = new JndiObjectFactoryBean(); - factoryBean.setJndiName(mailSessionJndiName); - // "java:comp/env/" will be prefixed if the JNDI name doesn't already have it - factoryBean.setResourceRef(true); - try { - // this step actually does the JNDI lookup - factoryBean.afterPropertiesSet(); - } catch(Exception e) { - logger.warn("failed to locate mail session : " + e); - return; - } - Session session = (Session) factoryBean.getObject(); - sender = new JavaMailSenderImpl(); - sender.setSession(session); - logger.info("email sender initialized from jndi name = '" + mailSessionJndiName + "'"); - } - - private void initMailSenderFromConfig(Map<String, String> config) { - String host = config.get("mail.server.host"); - if (host == null) { - logger.warn("'mail.server.host' config is null, mail sender not initialized"); - return; - } - String port = config.get("mail.server.port"); - String localhost = config.get("mail.smtp.localhost"); - from = config.get("mail.from"); - prefix = config.get("mail.subject.prefix"); - String userName = config.get("mail.server.username"); - String password = config.get("mail.server.password"); - String startTls = config.get("mail.server.starttls.enable"); - logger.info("initializing email adapter: host = '" + host + "', port = '" - + port + "', from = '" + from + "', prefix = '" + prefix + "'"); - this.prefix = prefix == null ? "[jtrac]" : prefix; - this.from = from == null ? "jtrac" : from; - int p = 25; - if (port != null) { - try { - p = Integer.parseInt(port); - } catch (NumberFormatException e) { - logger.warn("mail.server.port not an integer : '" + port + "', defaulting to 25"); - } - } - sender = new JavaMailSenderImpl(); - sender.setHost(host); - sender.setPort(p); - Properties props = null; + private JavaMailSenderImpl sender; + private String prefix; + private String from; + private String url; + private MessageSource messageSource; + private Locale defaultLocale; - if (userName != null) { - // authentication requested - props = new Properties(); - props.put("mail.smtp.auth", "true"); - if (startTls != null && startTls.toLowerCase().equals("true")) { - props.put("mail.smtp.starttls.enable", "true"); - } - sender.setUsername(userName); - sender.setPassword(password); - } - - if (localhost != null) { - if (props == null) { - props = new Properties(); - } - props.put("mail.smtp.localhost", localhost); - } - - if (props != null) { - sender.setJavaMailProperties(props); - } - - logger.info("email sender initialized from config: host = '" + host + "', port = '" + p + "'"); - } - + public MailSender(Map<String, String> config, MessageSource messageSource, + String defaultLocale) { + // initialize email sender + this.messageSource = messageSource; + this.defaultLocale = StringUtils.parseLocaleString(defaultLocale); + String mailSessionJndiName = config.get("mail.session.jndiname"); + if (StringUtils.hasText(mailSessionJndiName)) { + initMailSenderFromJndi(mailSessionJndiName); + } + if (sender == null) { + initMailSenderFromConfig(config); + } + // if sender is still null the send* methods will not + // do anything when called and will just return immediately + String tempUrl = config.get("jtrac.url.base"); + if (tempUrl == null) { + tempUrl = "http://localhost/jtrac/"; + } + if (!tempUrl.endsWith("/")) { + tempUrl = tempUrl + "/"; + } + this.url = tempUrl; + logger.info("email hyperlink base url set to '" + this.url + "'"); + } + + /** + * we bend the rules a little and fire off a new thread for sending + * an email message. This has the advantage of not slowing down the item + * create and update screens, i.e. the system returns the next screen + * after "submit" without blocking. This has been used in production + * (and now I guess in many JTrac installations worldwide) + * for quite a while now, on Tomcat without any problems. This helps a lot + * especially when the SMTP server is slow to respond, etc. + */ + private void sendInNewThread(final MimeMessage message) { + new Thread() { + @Override + public void run() { + logger.debug("send mail thread start"); + try { + try { + sender.send(message); + logger.debug("send mail thread successfull"); + } catch (Exception e) { + logger.error("send mail thread failed", e); + logger.error("mail headers dump start"); + Enumeration headers = message.getAllHeaders(); + while (headers.hasMoreElements()) { + Header h = (Header) headers.nextElement(); + logger.info(h.getName() + ": " + h.getValue()); + } + logger.error("mail headers dump end"); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + }.start(); + } + + private String fmt(String key, Locale locale) { + try { + return messageSource.getMessage("mail_sender." + key, null, locale); + } catch (Exception e) { + logger.debug(e.getMessage()); + return "???mail_sender." + key + "???"; + } + } + + private String addHeaderAndFooter(StringBuffer html) { + StringBuffer sb = new StringBuffer(); + // additional cosmetic tweaking of e-mail layout + // style just after the body tag does not work for a minority of clients + // like gmail, thunderbird etc. + // ItemUtils adds the main inline CSS when generating the email content, + // so we gracefully degrade + sb + .append("<html><body><style type='text/css'>table.jtrac th, table.jtrac td { padding-left: 0.2em; padding-right: 0.2em; }</style>"); + sb.append(html); + sb.append("</html>"); + return sb.toString(); + } + + private String getItemViewAnchor(Item item, Locale locale) { + String itemUrl = url + "app/item/" + item.getRefId(); + return "<p style='font-family: Arial; font-size: 75%'><a href='" + + itemUrl + "'>" + itemUrl + "</a></p>"; + } + + private String getSubject(Item item) { + String summary = null; + if (item.getSummary() == null) { + summary = ""; + } else if (item.getSummary().length() > 80) { + summary = item.getSummary().substring(0, 80); + } else { + summary = item.getSummary(); + } + return prefix + " #" + item.getRefId() + " " + summary; + } + + public void send(Item item) { + if (sender == null) { + logger.debug("mail sender is null, not sending notifications"); + return; + } + // TODO make this locale sensitive per recipient + logger.debug("attempting to send mail for item update"); + // prepare message content + StringBuffer sb = new StringBuffer(); + String anchor = getItemViewAnchor(item, defaultLocale); + sb.append(anchor); + sb.append(ItemUtils.getAsHtml(item, messageSource, defaultLocale)); + sb.append(anchor); + if (logger.isDebugEnabled()) { + logger.debug("html content: " + sb); + } + // prepare message + MimeMessage message = sender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(message, "UTF-8"); + + // Remember the TO person email to prevent duplicate mails + String toPersonEmail; + try { + helper.setText(addHeaderAndFooter(sb), true); + helper.setSubject(getSubject(item)); + helper.setSentDate(new Date()); + helper.setFrom(from); + // set TO + if (item.getAssignedTo() != null) { + helper.setTo(item.getAssignedTo().getEmail()); + toPersonEmail = item.getAssignedTo().getEmail(); + } else { + helper.setTo(item.getLoggedBy().getEmail()); + toPersonEmail = item.getLoggedBy().getEmail(); + } + // set CC + List<String> cclist = new ArrayList<String>(); + if (item.getItemUsers() != null) { + for (ItemUser itemUser : item.getItemUsers()) { + // Send only, if person is not the TO assignee + if (!toPersonEmail.equals(itemUser.getUser().getEmail())) { + cclist.add(itemUser.getUser().getEmail()); + } + } + + // sounds complicated but we have to ensure that no null + // item will be set in setCC(). So we collect the cc items + // in the cclist and transform it to an stringarray. + if (cclist.size() > 0) { + String[] cc = cclist.toArray(new String[0]); + helper.setCc(cc); + } + } + // send message + // workaround: Some PSEUDO user has no email address. Because email + // address + // is mandatory, you can enter "no" in email address and the mail + // will not + // be sent. + if (!"no".equals(toPersonEmail)) + sendInNewThread(message); + } catch (Exception e) { + logger.error("failed to prepare e-mail", e); + } + } + + public void sendUserPassword(User user, String clearText) { + if (sender == null) { + logger + .debug("mail sender is null, not sending new user / password change notification"); + return; + } + logger.debug("attempting to send mail for user password"); + String localeString = user.getLocale(); + Locale locale = null; + if (localeString == null) { + locale = defaultLocale; + } else { + locale = StringUtils.parseLocaleString(localeString); + } + MimeMessage message = sender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(message, "UTF-8"); + try { + helper.setTo(user.getEmail()); + helper.setSubject(prefix + " " + fmt("loginMailSubject", locale)); + StringBuffer sb = new StringBuffer(); + sb.append("<p>" + fmt("loginMailGreeting", locale) + " " + + user.getName() + ",</p>"); + sb.append("<p>" + fmt("loginMailLine1", locale) + "</p>"); + sb.append("<table class='jtrac'>"); + sb.append("<tr><th style='background: #CCCCCC'>" + + fmt("loginName", locale) + + "</th><td style='border: 1px solid black'>" + + user.getLoginName() + "</td></tr>"); + sb.append("<tr><th style='background: #CCCCCC'>" + + fmt("password", locale) + + "</th><td style='border: 1px solid black'>" + clearText + + "</td></tr>"); + sb.append("</table>"); + sb.append("<p>" + fmt("loginMailLine2", locale) + "</p>"); + sb.append("<p><a href='" + url + "'>" + url + "</a></p>"); + helper.setText(addHeaderAndFooter(sb), true); + helper.setSentDate(new Date()); + // helper.setCc(from); + helper.setFrom(from); + sendInNewThread(message); + } catch (Exception e) { + logger.error("failed to prepare e-mail", e); + } + } + + private void initMailSenderFromJndi(String mailSessionJndiName) { + logger.info("attempting to initialize mail sender from jndi name = '" + + mailSessionJndiName + "'"); + JndiObjectFactoryBean factoryBean = new JndiObjectFactoryBean(); + factoryBean.setJndiName(mailSessionJndiName); + // "java:comp/env/" will be prefixed if the JNDI name doesn't already + // have it + factoryBean.setResourceRef(true); + try { + // this step actually does the JNDI lookup + factoryBean.afterPropertiesSet(); + } catch (Exception e) { + logger.warn("failed to locate mail session : " + e); + return; + } + Session session = (Session) factoryBean.getObject(); + sender = new JavaMailSenderImpl(); + sender.setSession(session); + logger.info("email sender initialized from jndi name = '" + + mailSessionJndiName + "'"); + } + + private void initMailSenderFromConfig(Map<String, String> config) { + String host = config.get("mail.server.host"); + if (host == null) { + logger + .warn("'mail.server.host' config is null, mail sender not initialized"); + return; + } + String port = config.get("mail.server.port"); + String localhost = config.get("mail.smtp.localhost"); + from = config.get("mail.from"); + prefix = config.get("mail.subject.prefix"); + String userName = config.get("mail.server.username"); + String password = config.get("mail.server.password"); + String startTls = config.get("mail.server.starttls.enable"); + logger.info("initializing email adapter: host = '" + host + + "', port = '" + port + "', from = '" + from + "', prefix = '" + + prefix + "'"); + this.prefix = prefix == null ? "[jtrac]" : prefix; + this.from = from == null ? "jtrac" : from; + int p = 25; + if (port != null) { + try { + p = Integer.parseInt(port); + } catch (NumberFormatException e) { + logger.warn("mail.server.port not an integer : '" + port + + "', defaulting to 25"); + } + } + sender = new JavaMailSenderImpl(); + sender.setHost(host); + sender.setPort(p); + Properties props = null; + + if (userName != null) { + // authentication requested + props = new Properties(); + props.put("mail.smtp.auth", "true"); + if (startTls != null && startTls.toLowerCase().equals("true")) { + props.put("mail.smtp.starttls.enable", "true"); + } + sender.setUsername(userName); + sender.setPassword(password); + } + + if (localhost != null) { + if (props == null) { + props = new Properties(); + } + props.put("mail.smtp.localhost", localhost); + } + + if (props != null) { + sender.setJavaMailProperties(props); + } + + logger.info("email sender initialized from config: host = '" + host + + "', port = '" + p + "'"); + } + } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <udi...@us...> - 2022-06-14 12:54:17
|
Revision: 1450 http://sourceforge.net/p/j-trac/code/1450 Author: udittmer Date: 2022-06-14 12:54:14 +0000 (Tue, 14 Jun 2022) Log Message: ----------- forgot file Modified Paths: -------------- trunk/jtrac/src/main/java/info/jtrac/mail/MailSender.java Modified: trunk/jtrac/src/main/java/info/jtrac/mail/MailSender.java =================================================================== --- trunk/jtrac/src/main/java/info/jtrac/mail/MailSender.java 2022-06-14 12:53:45 UTC (rev 1449) +++ trunk/jtrac/src/main/java/info/jtrac/mail/MailSender.java 2022-06-14 12:54:14 UTC (rev 1450) @@ -223,8 +223,9 @@ List<String> cclist = new ArrayList<String>(); if (item.getItemUsers() != null) { for (ItemUser itemUser : item.getItemUsers()) { - // Send only, if person is not the TO assignee - if (!toPersonEmail.equals(itemUser.getUser().getEmail())) { + // Send only, if person is not the TO assignee AND user is not locked + if (!toPersonEmail.equals(itemUser.getUser().getEmail()) + && ! itemUser.getUser().isLocked()) { cclist.add(itemUser.getUser().getEmail()); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |