Package net.suberic.pooka.thread

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

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 javax.mail.*;
import javax.mail.internet.*;
import java.util.*;

/**
* 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 thread 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 LoadMessageThread extends Thread {
  private FolderInfo folderInfo;
  private List columnValues;
  private List loadQueue = new LinkedList();
  private List priorityLoadQueue = new LinkedList();
  private List messageLoadedListeners = new LinkedList();
  private int updateCheckMilliseconds = 60000;
  private int updateMessagesCount = 10;
  private boolean sleeping = false;

  private boolean stopped = false;

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

  /**
   * This creates a new LoadMessageThread from a FolderInfo object.
   */
   
  public LoadMessageThread(FolderInfo newFolderInfo) {
    super("Load Message Thread - " + newFolderInfo.getFolderID());
    folderInfo = newFolderInfo;
    this.setPriority(1);
  }
 
  public void run() {
    int uptime = 0;
    while (! stopped) {
      try {
  loadWaitingMessages();
      } catch (Exception e) {
  if (getFolderInfo().getLogger().isLoggable(java.util.logging.Level.WARNING)) {
    e.printStackTrace();
  }
      }

      try {
  sleeping = true;
  if (updateCheckMilliseconds < 1) {
    while (updateCheckMilliseconds < 1)
      sleep(60000);
  } else {
    sleep(updateCheckMilliseconds);
  }
  sleeping = false;
      } catch (InterruptedException ie) {
  sleeping = false;
      }
    }
  }
 
 
  /**
   * Loads the messages in the queue.
   */
  public void loadWaitingMessages() {
   
    int updateCounter = 0;
    int loadedMessageCount = 0;
    MessageProxy mp;
   
    // start this load section.
    int queueSize = getQueueSize();   
    int totalMessageCount = queueSize;
    if (! stopped && queueSize > 0) {
      folderInfo.getLogger().log(java.util.logging.Level.FINE, folderInfo.getFolderID() + " loading " + queueSize + " messages.");
     
      MessageLoadedListener display = getFolderInfo().getFolderDisplayUI();
      if (display != null)
  this.addMessageLoadedListener(display);
     
      fireMessageLoadedEvent(MessageLoadedEvent.LOADING_STARTING, 0, totalMessageCount);
     
      // get the batch sizes.
      int fetchBatchSize = 50;
      int loadBatchSize = 25;
      try {
  fetchBatchSize = Integer.parseInt(Pooka.getProperty("Pooka.fetchBatchSize", "50"));
      } catch (NumberFormatException nfe) {
      }
     
      try {
  loadBatchSize = Integer.parseInt(Pooka.getProperty("Pooka.loadBatchSize", "25"));
      } catch (NumberFormatException nfe) {
      }
     
      FetchProfile fetchProfile = getFolderInfo().getFetchProfile();

      // we'll stay in this while loop until the queue is empty
      for (List messages = retrieveNextBatch(fetchBatchSize); ! stopped && messages != null; messages=retrieveNextBatch(fetchBatchSize)) {
  totalMessageCount = messages.size() + getQueueSize() + loadedMessageCount;
  if (Pooka.getProperty("Pooka.openFoldersInBackGround", "false").equalsIgnoreCase("true")) {
    synchronized(folderInfo.getFolderThread().getRunLock()) {
      try {
        folderInfo.getFolderThread().setCurrentActionName("Loading messages.");
        // break when either we've been stopped or we're out of messages,
        for (int batchCount = 0; ! stopped && batchCount < messages.size(); batchCount++) {
    mp=(MessageProxy)messages.get(batchCount);
   
    // if the message hasn't been fetched, then fetch fetchBatchSize
    // worth of messages.
    if (! mp.getMessageInfo().hasBeenFetched()) {
      try {
        List fetchList = new ArrayList();
        for (int j = batchCount; fetchList.size() < fetchBatchSize && j < messages.size(); j++) {
          MessageInfo fetchInfo = ((MessageProxy) messages.get(j)).getMessageInfo();
          if (! fetchInfo.hasBeenFetched()) {
      fetchList.add(fetchInfo);
      //fetchInfo.setFetched(true);
          }
        }
     
        MessageInfo[] toFetch = new MessageInfo[fetchList.size()];
        toFetch = (MessageInfo[]) fetchList.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.
    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();
      }
    }
   
    loadedMessageCount++;
    if (++updateCounter >= getUpdateMessagesCount()) {
      fireMessageLoadedEvent(MessageLoadedEvent.MESSAGES_LOADED, loadedMessageCount, totalMessageCount);
      updateCounter = 0;      
    }
        }
      } finally {
        folderInfo.getFolderThread().setCurrentActionName("");
      }
    } // end synchronized
  } else {
    // break when either we've been stopped or we're out of messages,
    for (int batchCount = 0; ! stopped && batchCount < messages.size(); batchCount++) {
      mp=(MessageProxy)messages.get(batchCount);
     
      // if the message hasn't been fetched, then fetch fetchBatchSize
      // worth of messages.
      if (! mp.getMessageInfo().hasBeenFetched()) {
        try {
    List fetchList = new ArrayList();
    for (int j = batchCount; fetchList.size() < fetchBatchSize && j < messages.size(); j++) {
      MessageInfo fetchInfo = ((MessageProxy) messages.get(j)).getMessageInfo();
      if (! fetchInfo.hasBeenFetched()) {
        fetchList.add(fetchInfo);
        //fetchInfo.setFetched(true);
      }
    }
   
    MessageInfo[] toFetch = new MessageInfo[fetchList.size()];
    toFetch = (MessageInfo[]) fetchList.toArray(toFetch);
    synchronized(folderInfo.getFolderThread().getRunLock()) {
      folderInfo.getFolderThread().setCurrentActionName("Loading messages.");
      getFolderInfo().fetch(toFetch, fetchProfile);
      folderInfo.getFolderThread().setCurrentActionName("");
    }
        } catch(MessagingException me) {
    if (getFolderInfo().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.
      try {
        synchronized(folderInfo.getFolderThread().getRunLock()) {
    try {
      folderInfo.getFolderThread().setCurrentActionName("Loading messages.");
      if (! mp.isLoaded())
        mp.loadTableInfo();
      if (mp.needsRefresh())
        mp.refreshMessage();
      else if (! mp.matchedFilters()) {
        mp.matchFilters();
      }
    } finally {
      folderInfo.getFolderThread().setCurrentActionName("");
    }
        } // synchronized
      } catch (Exception e) {
        if (folderInfo.getLogger().isLoggable(java.util.logging.Level.WARNING)) {
    e.printStackTrace();
        }
      }
     
      loadedMessageCount++;
      if (++updateCounter >= getUpdateMessagesCount()) {
        fireMessageLoadedEvent(MessageLoadedEvent.MESSAGES_LOADED, loadedMessageCount, totalMessageCount);
        updateCounter = 0;      
      }
    }
  }
      }

      if (updateCounter > 0)
  fireMessageLoadedEvent(MessageLoadedEvent.MESSAGES_LOADED, loadedMessageCount, totalMessageCount);
     
      fireMessageLoadedEvent(MessageLoadedEvent.LOADING_COMPLETE, loadedMessageCount, totalMessageCount);
     
      if (display != null)
  removeMessageLoadedListener(display);
    }
  }
 
  /**
   * 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 (this.isSleeping())
      this.interrupt();
  }
 
  /**
   * 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);
      }
    }
   
    if (this.isSleeping())
      this.interrupt();
  }
 
  /**
   * 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 - 1);
    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 -1);
    returnValue.addAll(subList);
    subList.clear();
  } else {
    returnValue.addAll(loadQueue);
    loadQueue.clear();
  }
      }
     
      return returnValue;
    } else {
      return null;
    }
  }

  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();
  }

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

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





TOP

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

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.