/* * FrontlineSMS <http://www.frontlinesms.com> * Copyright 2007, 2008 kiwanja * * This file is part of FrontlineSMS. * * FrontlineSMS is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at * your option) any later version. * * FrontlineSMS 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 Lesser * General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with FrontlineSMS. If not, see <http://www.gnu.org/licenses/>. */ package net.frontlinesms; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import net.frontlinesms.data.domain.*; import net.frontlinesms.listener.EmailListener; import org.apache.log4j.Logger; /** * EmailServerHandler should be run as a separate thread. * * It handles the email accounts available to send emails from. * * @author Carlos Eduardo Genz * <li> kadu(at)masabi(dot)com */ public class EmailServerHandler extends Thread implements EmailListener { /** List of emails queued to be sent. */ private final ConcurrentLinkedQueue<Email> outbox = new ConcurrentLinkedQueue<Email>(); /** List of servers handlers that this manager is currently looking after. */ private final Map<EmailAccount, EmailSender> serverHandlers = new ConcurrentHashMap<EmailAccount, EmailSender>(); /** Listener to be passed Email Listener events from this */ private EmailListener emailListener; /** Flag indicating that the thread should continue running. */ private boolean running; private static Logger LOG = FrontlineUtils.getLogger(EmailServerHandler.class); public EmailServerHandler() { super("EmailServerHandler"); } public void setEmailListener(EmailListener emailListener) { this.emailListener = emailListener; } public void run() { LOG.trace("ENTER"); running = true; while (running) { Email email; while ((email = outbox.poll()) != null) { LOG.debug("Got e-mail [" + email + "] from outbox"); try { LOG.debug("Looking for a thread for this e-mail server [" + email.getEmailFrom().getAccountServer() + "]"); if (serverHandlers.containsKey(email.getEmailFrom())) { LOG.debug("A Thread for the server already exists!"); if (serverHandlers.get(email.getEmailFrom()).isAlive()) { LOG.debug("And it is alive! Adding this e-mail to the thread outbox."); serverHandlers.get(email.getEmailFrom()).sendEmail(email); } else { LOG.debug("And it is dead! Creating a new thread for server [" + email.getEmailFrom().getAccountServer() + "]..."); EmailSender sender = new EmailSender(email.getEmailFrom(), this); sender.sendEmail(email); sender.start(); serverHandlers.put(email.getEmailFrom(), sender); } } else { LOG.debug("No thread found! Creating a new thread for server [" + email.getEmailFrom().getAccountServer() + "]..."); EmailSender sender = new EmailSender(email.getEmailFrom(), this); sender.sendEmail(email); sender.start(); serverHandlers.put(email.getEmailFrom(), sender); } } catch (Exception e) { //This exception may happens because the account was deleted. LOG.debug("Error retrieving account details", e); } } FrontlineUtils.sleep_ignoreInterrupts(5000); } LOG.trace("EXIT"); } public void serverRemoved(EmailAccount account) { LOG.trace("ENTER"); if (serverHandlers.containsKey(account)) { LOG.debug("Stopping the account thread [" + account.getAccountName() + "]"); serverHandlers.get(account).stopRunning(); serverHandlers.remove(account); } LOG.trace("EXIT"); } /** * Remove the supplied email from outbox. * * @param deleted */ public void removeFromOutbox(Email deleted) { LOG.trace("ENTER"); outbox.remove(deleted); LOG.debug("Email [" + deleted + "] removed from outbox. Size is [" + outbox.size() + "]"); LOG.trace("EXIT"); } /** * Send the email. */ public void sendEmail(Email outgoing) { LOG.trace("ENTER"); outgoing.setStatus(Email.Status.OUTBOX); outbox.add(outgoing); if (emailListener != null) { emailListener.outgoingEmailEvent(null, outgoing); } LOG.debug("E-mail added to outbox. Size is [" + outbox.size() + "]"); LOG.trace("EXIT"); } /** * Flags the internal thread to stop running. */ public void stopRunning() { this.running = false; for (EmailAccount acc : serverHandlers.keySet()) { serverHandlers.get(acc).stopRunning(); } } public void outgoingEmailEvent(EmailSender sender, Email email) { if (emailListener != null) { emailListener.outgoingEmailEvent(sender, email); } } }