Package net.suberic.pooka.thread

Source Code of net.suberic.pooka.thread.MessageLoader

package net.suberic.pooka.thread;

import net.suberic.pooka.*;
import net.suberic.pooka.event.*;
import net.suberic.pooka.gui.LoadMessageTracker;
import net.suberic.pooka.gui.MessageProxy;
import net.suberic.pooka.gui.FolderInternalFrame;
import net.suberic.pooka.cache.*;
import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;
import java.awt.event.ActionEvent;
import javax.swing.Action;
import javax.swing.AbstractAction;

/**
* This class does the actual loading of the header information from
* the messages in the folder.  It also is set up to communicate with
* a JProgessBar to show how far the loading has gotten.
*
* More specifically, this class takes an array of Messages and a
* Vector of Strings which are the column values which are to be put
* into the table.  It then loads the values into a Vector of Vectors,
* each of which contains the information for the Table for a group
* of Messages.  It then throws a ChangeEvent to the listening
* FolderTableModel.  The FolderTableModel can then get the information
* using the getNewMessages() function.
*/

public class MessageLoader extends Thread {
  private FolderInfo folderInfo;
  private List columnValues;
  private List loadQueue = new LinkedList();
  private List priorityLoadQueue = new LinkedList();
  private List cacheQueue = new LinkedList();
  private List messageLoadedListeners = new LinkedList();
  private int updateMessagesCount = 10;
  private boolean mEnqueued = false;

  private boolean stopped = false;

  public static int NORMAL = 5;
  public static int HIGH = 10;

  /**
   * The Action that will get added to the ActionQueue when there
   * are messages to be loaded.
   */
  public Action mAction = null;

  /**
   * This creates a new MessageLoader from a FolderInfo object.
   */
  public MessageLoader(FolderInfo newFolderInfo) {
    folderInfo = newFolderInfo;
    mAction = new AbstractAction("Load Messages - " + newFolderInfo.getFolderID()) {
  public void actionPerformed(ActionEvent ae) {
    loadNextBatch();
  }
      };
  }
 
  /**
   * Loads the messages in the queue.
   */
  public void loadNextBatch() {
    MessageProxy mp;
   
    // start this load section.
    int queueSize = getQueueSize();   
    if (! stopped) {
      if (queueSize > 0) {
  folderInfo.getLogger().log(java.util.logging.Level.FINE, folderInfo.getFolderID() + " loading " + queueSize + " messages.");
 
  // get the batch sizes.
  int fetchBatchSize = 50;
  try {
    fetchBatchSize = Integer.parseInt(Pooka.getProperty("Pooka.fetchBatchSize", "50"));
  } catch (NumberFormatException nfe) {
  }
 
  FetchProfile fetchProfile = getFolderInfo().getFetchProfile();
 
  // get the next batch.
  List messageProxies = retrieveNextBatch(fetchBatchSize);
  List toFetchInfos = new LinkedList();
 
  // go through and find all of the messages that need to be fetched
  // or refetched, and add them to the toFetchInfos list.
  for (int i = 0 ; i < messageProxies.size(); i++) {
    MessageInfo fetchCheckInfo = ((MessageProxy) messageProxies.get(i)).getMessageInfo();
    if (! fetchCheckInfo.hasBeenFetched()) {
      toFetchInfos.add(fetchCheckInfo);
    }
  }
 
  if (toFetchInfos.size() > 0) {
    try {
      MessageInfo[] toFetch = new MessageInfo[toFetchInfos.size()];
      toFetch = (MessageInfo[]) toFetchInfos.toArray(toFetch);
      getFolderInfo().fetch(toFetch, fetchProfile);
    } catch(MessagingException me) {
      if (folderInfo.getLogger().isLoggable(java.util.logging.Level.WARNING)) {
        System.out.println("caught error while fetching for folder " + getFolderInfo().getFolderID() + ":  " + me);
        me.printStackTrace();
      }
    }
  }
 
  // now load each individual messageproxy.
  // and refresh each message.
  for (int i = 0 ; i < messageProxies.size(); i++) {
    mp = (MessageProxy) messageProxies.get(i);
    try {
      if (! mp.isLoaded())
        mp.loadTableInfo();
      if (mp.needsRefresh()) {
        mp.refreshMessage();
      }
      else if (! mp.matchedFilters()) {
        mp.matchFilters();
      }
    } catch (Exception e) {
      if (folderInfo.getLogger().isLoggable(java.util.logging.Level.WARNING)) {
        e.printStackTrace();
      }
    }
  }

      } else if (getCacheQueueSize() > 0) {
  try {
    MessageProxy nextCache = (MessageProxy) cacheQueue.remove(0);
    if (folderInfo instanceof CachingFolderInfo) {
      MessageInfo mi = nextCache.getMessageInfo();
      MimeMessage mimeMessage = (MimeMessage) mi.getMessage();
      CachingFolderInfo cfi = (CachingFolderInfo) folderInfo;
      if (cfi.getFolderDisplayUI() != null) {
        cfi.showStatusMessage(cfi.getFolderDisplayUI(), "caching messages, " + getCacheQueueSize() + " remaining...");
      }
      cfi.getCache().cacheMessage(mimeMessage, cfi.getUID(mimeMessage), cfi.getUIDValidity(), SimpleFileCache.MESSAGE, false);
      if (cfi.getFolderDisplayUI() != null && getCacheQueueSize() == 0) {
        cfi.clearStatusMessage(cfi.getFolderDisplayUI());
      }
    }
  } catch (Exception e) {
    if (folderInfo.getLogger().isLoggable(java.util.logging.Level.WARNING)) {
      e.printStackTrace();
    }
 
  }
      }
    }
    if (! stopped && (getQueueSize() > 0 || getCacheQueueSize() > 0)) {
      enqueue();
    }
  }
 
  /**
   * Fires a new MessageLoadedEvent to each registered MessageLoadedListener.
   */ 
  public void fireMessageLoadedEvent(int type, int numMessages, int max) {
    /*
    for (int i = 0; i < messageLoadedListeners.size(); i ++) {
      ((MessageLoadedListener)messageLoadedListeners.get(i)).handleMessageLoaded(new MessageLoadedEvent(this, type, numMessages, max));
    }
    */
  }
 
  /**
   * Adds a MessageLoadedListener to the messageLoadedListener list.
   */
  public void addMessageLoadedListener(MessageLoadedListener newListener) {
    if (messageLoadedListeners.indexOf(newListener) == -1)
      messageLoadedListeners.add(newListener);
  }
 
  /**
   * Removes a MessageLoadedListener from the messageLoadedListener list,
   * if it's in the list.
   */
  public void removeMessageLoadedListener(MessageLoadedListener remListener) {
    if (messageLoadedListeners.indexOf(remListener) > -1)
      messageLoadedListeners.remove(remListener);
  }
 
  /**
   * Adds the MessageProxy(s) to the loadQueue.
   */
  public synchronized void loadMessages(MessageProxy mp) {
    loadMessages(mp, NORMAL);
  }

  /**
   * Adds the MessageProxy(s) to the loadQueue.
   */
  public synchronized void loadMessages(MessageProxy mp, int pPriority) {
    if (pPriority > NORMAL) {
      if (! priorityLoadQueue.contains(mp))
  priorityLoadQueue.add(mp);
      loadQueue.remove(mp);
    } else {
      if (! priorityLoadQueue.contains(mp) && ! loadQueue.contains(mp))
  loadQueue.add(mp);
    }

    if (! isEnqueued())
      enqueue();
  }
 
  /**
   * Adds the MessageProxy(s) to the loadQueue.
   */
  public synchronized void loadMessages(MessageProxy[] mp) {
    loadMessages(mp, NORMAL);
  }

  /**
   * Adds the MessageProxy(s) to the loadQueue.
   */
  public synchronized void loadMessages(MessageProxy[] mp, int pPriority) {
    loadMessages(Arrays.asList(mp), pPriority);
  }
 
  /**
   * Adds the MessageProxy(s) to the loadQueue.
   */
  public synchronized void loadMessages(List mp) {
    loadMessages(mp, NORMAL);
  }

  /**
   * Adds the MessageProxy(s) to the loadQueue.
   */
  public synchronized void loadMessages(List mp, int pPriority) {
    if (mp != null && mp.size() > 0) {
      if (pPriority > NORMAL) {
  loadQueue.removeAll(mp);
  addUniqueReversed(priorityLoadQueue, mp);
      } else {
  List copy = new ArrayList(mp);
  copy.removeAll(priorityLoadQueue);
  addUniqueReversed(loadQueue, copy);
      }
    }
   
    enqueue();
  }
 
  /**
   * Adds the MessageProxy(s) to the cacheQueue.
   */
  public synchronized void cacheMessages(List mp) {
    if (mp != null && mp.size() > 0) {
  addUniqueReversed(cacheQueue, mp);
    }
   
    enqueue();
  }
 
  /**
   * Adds the MessageProxy(s) to the cacheQueue.
   */
  public synchronized void cacheMessages(MessageProxy[] mp) {
    if (mp != null && mp.length > 0) {
  addUniqueReversed(cacheQueue, Arrays.asList(mp));
    }
   
    enqueue();
  }
 
  /**
   * retrieves all the messages from the loadQueue, and resets that
   * List to 0 (an empty List).
   *
   * generally, use retrieveNextBatch() instead.
   */
  public synchronized List retrieveLoadQueue() {
    List returnValue = new LinkedList();
    returnValue.addAll(priorityLoadQueue);
    returnValue.addAll(loadQueue);
    loadQueue = new LinkedList();
    priorityLoadQueue = new LinkedList();
    return returnValue;
  }
 
  /**
   * Adds all of the entries in toAdd to targetList, in reversed order.
   */
  private void addUniqueReversed(List targetList, List toAdd) {
    for (int i = toAdd.size() - 1; i >= 0; i--) {
      Object current = toAdd.get(i);
      if (current != null && ! targetList.contains(current))
  targetList.add(current);
    }
  }

  /**
   * Retrieves the next pCount messages from the queue, or returns null
   * if there are no entries in the queue.
   */
  public synchronized List retrieveNextBatch(int pCount) {
    int plqLength = priorityLoadQueue.size();
    int lqLength = loadQueue.size();

    // check to see if we actually have anything in the queue.
    if (plqLength + lqLength > 0) {
      List returnValue = new LinkedList();

      // adding the priority queue first
      if (plqLength > 0) {
  // if the priority queue is larger than (or the same size as) the
  // requested count, then just return it.
  if (plqLength >= pCount) {
    List subList = priorityLoadQueue.subList(0, pCount);
    returnValue.addAll(subList);
    subList.clear();
    return returnValue;
  } else {
    // just add of the priority queue, and go on.
    returnValue.addAll(priorityLoadQueue);
    priorityLoadQueue.clear();
  }
      }

      // add in the normal queue now.
      if (lqLength > 0) {
  int newCount = pCount - plqLength;
  if (lqLength >= newCount) {
    List subList = loadQueue.subList(0, newCount);
    returnValue.addAll(subList);
    subList.clear();
  } else {
    returnValue.addAll(loadQueue);
    loadQueue.clear();
  }
      }
     
      return returnValue;
    } else {
      return null;
    }
  }

  /**
   * Adds the action for this MessageLoader to the FolderThread of the
   * Folder.
   */
  public synchronized void enqueue() {
    //FIXME
    if (getFolderInfo() != null && getFolderInfo().getFolderThread() != null && ! getFolderInfo().getFolderThread().getQueue().contains(mAction)) {
      getFolderInfo().getFolderThread().addToQueue(mAction, null, net.suberic.util.thread.ActionThread.PRIORITY_LOW);
    }
  }
  public int getUpdateMessagesCount() {
    return updateMessagesCount;
  }
 
  public void setUpdateMessagesCount(int newValue) {
    updateMessagesCount = newValue;
  }

  /**
   * Returns the total amount left in the queue.
   */
  public synchronized int getQueueSize() {
    return loadQueue.size() + priorityLoadQueue.size();
  }

  /**
   * Returns the total amount left in the cache queue.
   */
  public synchronized int getCacheQueueSize() {
    return cacheQueue.size();
  }

  public List getColumnValues() {
    return columnValues;
  }
 
  public void setColumnValues(List newValue) {
    columnValues=newValue;
  }
 
  public FolderInfo getFolderInfo() {
    return folderInfo;
  }
 
  public boolean isEnqueued() {
    return mEnqueued;
  }

  /**
   * Stops the thread.
   */
  public void stopLoading() {
    stopped = true;
  }
}





TOP

Related Classes of net.suberic.pooka.thread.MessageLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.