James Moger
2012-10-13 c658df9e87d65b08d5482cf04489cb0532ff83dd
src/com/gitblit/MailExecutor.java
@@ -15,8 +15,8 @@
 */
package com.gitblit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
@@ -24,10 +24,10 @@
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.regex.Pattern;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
@@ -50,8 +50,6 @@
   private final Logger logger = LoggerFactory.getLogger(MailExecutor.class);
   private final Queue<Message> queue = new ConcurrentLinkedQueue<Message>();
   private final Set<Message> failures = Collections.synchronizedSet(new HashSet<Message>());
   private final Session session;
@@ -152,11 +150,28 @@
         InternetAddress from = new InternetAddress(fromAddress, "Gitblit");
         message.setFrom(from);
         InternetAddress[] tos = new InternetAddress[toAddresses.size()];
         for (int i = 0; i < toAddresses.size(); i++) {
            tos[i] = new InternetAddress(toAddresses.get(i));
         // determine unique set of addresses
         Set<String> uniques = new HashSet<String>();
         for (String address : toAddresses) {
            uniques.add(address.toLowerCase());
         }
         message.setRecipients(Message.RecipientType.TO, tos);
         Pattern validEmail = Pattern
               .compile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$");
         List<InternetAddress> tos = new ArrayList<InternetAddress>();
         for (String address : uniques) {
            if (StringUtils.isEmpty(address)) {
               continue;
            }
            if (validEmail.matcher(address).find()) {
               try {
                  tos.add(new InternetAddress(address));
               } catch (Throwable t) {
               }
            }
         }
         message.setRecipients(Message.RecipientType.BCC,
               tos.toArray(new InternetAddress[tos.size()]));
         message.setSentDate(new Date());
      } catch (Exception e) {
         logger.error("Failed to properly create message", e);
@@ -197,49 +212,22 @@
      if (!queue.isEmpty()) {
         if (session != null) {
            // send message via mail server
            List<Message> failures = new ArrayList<Message>();
            Message message = null;
            while ((message = queue.peek()) != null) {
            while ((message = queue.poll()) != null) {
               try {
                  if (settings.getBoolean(Keys.mail.debug, false)) {
                     logger.info("send: "
                           + StringUtils.trimString(
                                 message.getSubject()
                                       + " => "
                                       + message.getRecipients(RecipientType.TO)[0]
                                             .toString(), 60));
                     logger.info("send: " + StringUtils.trimString(message.getSubject(), 60));
                  }
                  Transport.send(message);
                  queue.remove();
                  failures.remove(message);
               } catch (Throwable e) {
                  if (!failures.contains(message)) {
                     logger.error("Failed to send message", e);
                     failures.add(message);
                  }
                  logger.error("Failed to send message", e);
                  failures.add(message);
               }
            }
         }
      } else {
         // log message to console and drop
         if (!queue.isEmpty()) {
            Message message = null;
            while ((message = queue.peek()) != null) {
               try {
                  logger.info("drop: "
                        + StringUtils.trimString(
                              (message.getSubject())
                                    + " => "
                                    + message.getRecipients(RecipientType.TO)[0]
                                          .toString(), 60));
                  queue.remove();
                  failures.remove(message);
               } catch (Throwable e) {
                  if (!failures.contains(message)) {
                     logger.error("Failed to remove message from queue");
                     failures.add(message);
                  }
               }
            }
            // push the failures back onto the queue for the next cycle
            queue.addAll(failures);
         }
      }
   }