www.pudn.com > MUMail.rar > MailQueue.java


/*
 * Copyright (C) 1998-2001 Mark Tuempfel and Uli Luckas
 *
 * 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 2
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 *
 * To reach the Authors you can send E-Mail to:
 *	Mark Tuempfel 
 *      Uli Luckas    
 *
 */

package mumail.net;

import java.util.*;
import java.lang.reflect.Array;
import java.io.IOException;
import java.beans.*;
import mumail.mime.*;

public final class MailQueue implements PropertyChangeListener {


  private PropertyChangeSupport propertyChangeSupport;
  private boolean               Connected;
  private int                   noOfMails;
  protected MailClient          mailClient;
  protected Hashtable           Header;
  protected Hashtable           Message;
  protected String[]            UID;
  private String                newHost;
  private int                   newPort;
  private String                newUser;
  private String                newPassword;
  private MailFetcher           mailFetcher;
  public static final String    pn_Connected = "Connected";
  protected final static int    downloadIdle = -1;

  private class MailFetcher extends Thread {
    private MailListener mailListener;
    Object interruptLock;
    private int currentDownload;
    private boolean exit;
    private boolean downloadInterrupting;

    public MailFetcher() {
      super("Mail Fetcher");
      setDaemon(true);
      interruptLock = new Object();
      currentDownload = downloadIdle;
      exit = false;
      downloadInterrupting = false;
    }

    public void fetchMessage(int index, MailListener newMailListener) {
      abortCurrentDownload();
      synchronized (this) {
        mailListener = newMailListener;
        currentDownload = index;
        this.notifyAll();
      }
    }

    public void abortCurrentDownload() {
      synchronized (interruptLock) {
        if (currentDownload != downloadIdle && !downloadInterrupting) {

          // With a java 1.1 VM, calling Thread.interrupt() can cause an
          // IOException in the interrupted thread. "downloadInterrupting"
          // signals the cause of this exception.
          downloadInterrupting = true;
          interrupt();
          // The Netscape 4.6 VM somehow looses Thread.interrupt() calls.
          // Therefore we need to close the connection to cancel a download.
          // The reason for the resulting Exception is signaled by
          // "downloadInterrupting"
          Close();
          while (downloadInterrupting) {
            try {
              interruptLock.wait();
            } catch (InterruptedException e) {
            }
          }
        }
      }
    }

    private void downloadMessage(int index) throws IOException, InterruptedException {
      synchronized (interruptLock) {
        if (!(mailClient.isConnected() || downloadInterrupting)) {
          Open();
        }
      }
      mimeMail newMessage = new mimeMail(mailClient.getMail(index + 1, mailListener));
      Message.put(UID[index], newMessage);
      Header.put(UID[index], newMessage.getHeader());
    }

    public synchronized void run() {
      while (!exit) {
        try {
          synchronized (interruptLock) {
            currentDownload = downloadIdle;
            this.notifyAll();
            downloadInterrupting = false;
            interruptLock.notifyAll();
          }
          while (currentDownload == downloadIdle && !exit) {
            this.wait();
          }
          if (!exit) {
            downloadMessage(currentDownload);
            mailListener.mailDownloaded(currentDownload);
          }
        } catch (Exception e) {
          // Something went wrong. (My be on purpose)

          // Work around Bug in Java 1.1 where Thread.interrupt() can cause
          // different Exceptions, not only a InterruptedException.
          if (downloadInterrupting) {
            e = new InterruptedException();
          }
          //
          //

          mailListener.downloadFailed(currentDownload, new InterruptedException());
          Close();
        }
      }
    }

  }

  public void addPropertyChangeListener(PropertyChangeListener listener) {
    propertyChangeSupport.addPropertyChangeListener(listener);
  }

  public void removePropertyChangeListener(PropertyChangeListener listener) {
    propertyChangeSupport.removePropertyChangeListener(listener);
  }

  private void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
    propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
  }

  private void setConnected(boolean isConnected) {
    boolean wasConnected = Connected;
    Connected = isConnected;
    firePropertyChange(pn_Connected, toBoolean(isConnected), toBoolean(wasConnected));
  }

  public boolean isConnected() {
    return Connected;
  }

  public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
    if (propertyChangeEvent.getSource() == mailClient) {
      if (propertyChangeEvent.getPropertyName().equals(pn_Connected)) {
        try {
          if (mailClient.isConnected()) {
            noOfMails = mailClient.getCount();
            UID = new String[noOfMails];
            for(int i = 0; i