Package net.suberic.pooka.cache

Source Code of net.suberic.pooka.cache.CachingFolderInfo

package net.suberic.pooka.cache;
import javax.mail.*;
import javax.mail.event.MessageCountEvent;
import javax.mail.internet.MimeMessage;
import javax.mail.event.MessageChangedEvent;
import javax.mail.event.ConnectionEvent;
import java.util.Vector;
import java.util.List;
import java.util.logging.*;
import java.util.StringTokenizer;
import java.util.HashMap;
import java.io.File;
import net.suberic.pooka.*;
import net.suberic.pooka.gui.MessageProxy;
import net.suberic.pooka.gui.FolderTableModel;
import net.suberic.util.thread.ActionThread;

/**
* A FolderInfo which caches its messages in a MessageCache.
* @author Allen Petersen
* @version $Revision: 1718 $
*/

public class CachingFolderInfo extends net.suberic.pooka.UIDFolderInfo {
  private MessageCache cache = null;

  // the resource for the folder disconnected message
  protected static String disconnectedMessage = "error.CachingFolder.disconnected";

  boolean autoCache = false;

  public CachingFolderInfo(StoreInfo parent, String fname) {
    super(parent, fname);

    if (! getCacheHeadersOnly()) {
      autoCache =  Pooka.getProperty(getFolderProperty() + ".autoCache", Pooka.getProperty(getParentStore().getStoreProperty() + ".autoCache", Pooka.getProperty("Pooka.autoCache", "false"))).equalsIgnoreCase("true");
    }

    Pooka.getResources().addValueChangeListener(this, getFolderProperty() + ".autoCache");
  }

  public CachingFolderInfo(FolderInfo parent, String fname) {
    super(parent, fname);

    if (! getCacheHeadersOnly()) {
      autoCache =  Pooka.getProperty(getFolderProperty() + ".autoCache", Pooka.getProperty(getParentStore().getStoreProperty() + ".autoCache", Pooka.getProperty("Pooka.autoCache", "false"))).equalsIgnoreCase("true");
    }

    Pooka.getResources().addValueChangeListener(this, getFolderProperty() + ".autoCache");
    Pooka.getResources().addValueChangeListener(this, getFolderProperty() + ".cacheHeadersOnly");
    Pooka.getResources().addValueChangeListener(this, getParentStore().getStoreProperty() + ".autoCache");
    Pooka.getResources().addValueChangeListener(this, getParentStore().getStoreProperty() + ".cacheHeadersOnly");
  }

  /**
   * Loads the column names and sizes.
   */
  protected FetchProfile createColumnInformation() {
    FetchProfile fp = super.createColumnInformation();
    // we need to get the full headers for the CachingFolderInfo.
    fp = new FetchProfile();
    fp.add(FetchProfile.Item.FLAGS);
    fp.add(com.sun.mail.imap.IMAPFolder.FetchProfileItem.HEADERS);
    return fp;
  }

  /**
   * This actually loads up the Folder object itself.  This is used so
   * that we can have a FolderInfo even if we're not connected to the
   * parent Store.
   *
   * Before we load the folder, the FolderInfo has the state of NOT_LOADED.
   * Once the parent store is connected, we can try to load the folder.
   * If the load is successful, we go to a CLOSED state.  If it isn't,
   * then we can either return to NOT_LOADED, or INVALID.
   */
  public void loadFolder(boolean pConnectStore) throws OperationCancelledException {
    if (cache == null) {
      try {
        this.cache = new SimpleFileCache(this, getCacheDirectory());
        type =  type | Folder.HOLDS_MESSAGES;
        setStatus(DISCONNECTED);
      } catch (java.io.IOException ioe) {
        System.out.println("Error creating cache!");
        ioe.printStackTrace();
        return;
      }
    }

    if (isLoaded() || (loading && children == null))
      return;

    Folder[] tmpFolder = null;
    Folder tmpParentFolder;

    try {
      loading = true;
      if (getParentStore().isConnected()) {
        if (getParentFolder() == null) {
          try {
            if (getLogger().isLoggable(Level.FINE))
              getLogger().log(Level.FINE, Thread.currentThread() + "loading folder " + getFolderID() + ":  checking parent store connection.");

            Store store = getParentStore().getStore();
            // first see if we're a namespace
            try {
              if (getLogger().isLoggable(Level.FINE)) {
                getLogger().log(Level.FINE, "checking to see if " + getFolderID() + " is a shared folder.");
              }

              Folder[] sharedFolders = store.getSharedNamespaces();

              if (sharedFolders != null && sharedFolders.length > 0) {
                for (int i = 0; ( tmpFolder == null || tmpFolder.length == 0 ) && i < sharedFolders.length; i++) {
                  if (sharedFolders[i].getName().equalsIgnoreCase(getFolderName())) {

                    if (!mNamespace) {
                      Pooka.setProperty(getFolderID() + "._namespace", "true");
                      mNamespace = true;
                    }

                    tmpFolder = new Folder[1];
                    tmpFolder[0] =  sharedFolders[i] ;
                  }
                }
              }
            } catch (Exception e) {
              // if we get a not supported exception or some such here,
              // just ignore it.
            }

            if (tmpFolder == null || tmpFolder.length == 0) {
              // not a shared namespace
              tmpParentFolder = store.getDefaultFolder();
              if (getLogger().isLoggable(Level.FINE)) {
                getLogger().log(Level.FINE, "got " + tmpParentFolder + " as Default Folder for store.");
                getLogger().log(Level.FINE, "doing a list on default folder " + tmpParentFolder + " for folder " + getFolderName());
              }

              tmpFolder = tmpParentFolder.list(getFolderName());
            }

            if (getLogger().isLoggable(Level.FINE))
              getLogger().log(Level.FINE, "got " + tmpFolder + " as Folder for folder " + getFolderID() + ".");

          } catch (MessagingException me) {
            me.printStackTrace();

            if (getLogger().isLoggable(Level.FINE)) {
              getLogger().log(Level.FINE, Thread.currentThread() + "loading folder " + getFolderID() + ":  caught messaging exception from parentStore getting folder: " + me);
              me.printStackTrace();
            }
            tmpFolder =null;
          }
        } else {
          if (!getParentFolder().isLoaded())
            getParentFolder().loadFolder();
          if (!getParentFolder().isLoaded()) {
            tmpFolder = null;
          } else {
            tmpParentFolder = getParentFolder().getFolder();
            if (tmpParentFolder != null) {
              tmpFolder = tmpParentFolder.list(getFolderName());
            } else {
              tmpFolder = null;
            }
          }
        }
        if (tmpFolder != null && tmpFolder.length > 0) {
          setFolder(tmpFolder[0]);
          if (! getFolder().isSubscribed())
            getFolder().setSubscribed(true);
          setStatus(CLOSED);
          getFolder().addMessageChangedListener(this);
        } else {
          if (cache != null)
            setStatus(CACHE_ONLY);
          else
            setStatus(INVALID);
          setFolder(new FolderProxy(getFolderName()));
        }
      } else {
        setFolder(new FolderProxy(getFolderName()));
      }

    } catch (MessagingException me) {
      if (getLogger().isLoggable(Level.FINE)) {
        getLogger().log(Level.FINE, Thread.currentThread() + "loading folder " + getFolderID() + ":  caught messaging exception; setting loaded to false:  " + me.getMessage() );
        me.printStackTrace();
      }
      setStatus(NOT_LOADED);
      setFolder(new FolderProxy(getFolderName()));
    } finally {
      initializeFolderInfo();
      loading = false;
    }
  }

  /**
   * called when the folder is opened.
   */
  public void opened (ConnectionEvent e) {
    super.opened(e);
    rematchFilters();
  }

  /**
   * This method opens the Folder, and sets the FolderInfo to know that
   * the Folder should be open.  You should use this method instead of
   * calling getFolder().open(), because if you use this method, then
   * the FolderInfo will try to keep the Folder open, and will try to
   * reopen the Folder if it gets closed before closeFolder is called.
   *
   * This method can also be used to reset the mode of an already
   * opened folder.
   */
  public void openFolder(int mode, boolean pConnectStore) throws MessagingException, OperationCancelledException {
    try {
      getLogger().log(Level.FINE, this + ":  checking parent store.");

      if (!getParentStore().isConnected() && pConnectStore && getParentStore().getPreferredStatus() == FolderInfo.CONNECTED) {
        getLogger().log(Level.FINE, this + ":  parent store isn't connected.  trying connection.");
        try {
          getParentStore().connectStore();
        } catch (OperationCancelledException oce) {
          getLogger().log(Level.INFO, "Login cancelled.");
        }
      }

      getLogger().log(Level.FINE, this + ":  loading folder.");

      if (! isLoaded() && status != CACHE_ONLY)
        loadFolder();

      getLogger().log(Level.FINE, this + ":  folder loaded.  status is " + status + "; checked on parent store.  trying isLoaded() and isAvailable().");

      if (status == CLOSED || status == LOST_CONNECTION || status == DISCONNECTED) {
        getLogger().log(Level.FINE, this + ":  isLoaded() and isAvailable().");
        if (getFolder().isOpen()) {
          if (getFolder().getMode() == mode)
            return;
          else {
            getFolder().close(false);
            openFolder(mode);
          }
        } else {
          Folder f = getFolder();
          getFolder().open(mode);
          updateFolderOpenStatus(true);
          resetMessageCounts();
        }
      } else if (status == INVALID) {
        throw new MessagingException(Pooka.getProperty("error.folderInvalid", "Error:  folder is invalid.  ") + getFolderID());
      }
    } catch (MessagingException me) {
      setStatus(DISCONNECTED);
      throw me;
    } finally {
      resetMessageCounts();
    }
  }


  /**
   * Called when the store in disconnected.
   */
  public void disconnected(ConnectionEvent e) {
    super.disconnected(e);
    rematchFilters();
  }

  /**
   * Called when the folder is closed.
   */
  public void closed(ConnectionEvent e) {
    super.closed(e);
    rematchFilters();
  }

  /**
   * gets all of the message proxies associated with this folder info
   * and notifies them that they need to rematch their filters.
   */
  protected void rematchFilters() {
    if (folderTableModel != null) {
      List allProxies = folderTableModel.getAllProxies();
      for (int i = 0; i < allProxies.size(); i++) {
        ((MessageProxy) allProxies.get(i)).clearMatchedFilters();
      }
      //loaderThread.loadMessages(allProxies);
      mMessageLoader.loadMessages(allProxies);
    }
  }

  /**
   * During loadAllMessages, updates the display to say that we're loading
   * messages.
   */
  protected void updateDisplay(boolean start) {
    if (getFolderDisplayUI() != null) {
      if (start) {
        getFolderDisplayUI().setBusy(true);
        showStatusMessage(getFolderDisplayUI(), Pooka.getProperty("messages.CachingFolder.loading.starting", "Loading messages."));
      } else {
        getFolderDisplayUI().setBusy(false);
        showStatusMessage(getFolderDisplayUI(), Pooka.getProperty("messages.CachingFolder.loading.finished", "Done loading messages."));
      }
    }
  }

  /**
   * While loading messages, attempts to update the folder status.
   */
  protected void updateFolderStatusForLoading() throws MessagingException, OperationCancelledException {
    if (preferredStatus < DISCONNECTED && !(isConnected() && getParentStore().getConnection().getStatus() == NetworkConnection.CONNECTED )) {
      try {
        openFolder(Folder.READ_WRITE);
      } catch (MessagingException me) {
        uidValidity = cache.getUIDValidity();
        preferredStatus = DISCONNECTED;
      }
    }
  }

  /**
   * Loads the MessageInfos and MesageProxies.  Returns a List of
   * newly created MessageProxies.
   */
  protected List createInfosAndProxies() throws MessagingException {

    List messageProxies = new Vector();

    if (getStatus() > CONNECTED) {
      uidValidity = cache.getUIDValidity();
    }

    if (isConnected()) {
      try {
        // load the list of uid's.

        showStatusMessage(getFolderDisplayUI(), Pooka.getProperty("message.CachingFolder.synchronizing.writingChanges", "Writing local changes to server..."));

        // first write all the changes that we made back to the server.
        getCache().writeChangesToServer(getFolder());

        showStatusMessage(getFolderDisplayUI(), Pooka.getProperty("message.UIDFolder.synchronizing.loading", "Loading messages from folder..."));

        FetchProfile uidFetchProfile = new FetchProfile();
        uidFetchProfile.add(UIDFolder.FetchProfileItem.UID);
        getLogger().log(Level.FINE, "getting messages.");

        Message[] messages = getFolder().getMessages();
        getLogger().log(Level.FINE, "fetching messages.");
        getFolder().fetch(messages, uidFetchProfile);
        getLogger().log(Level.FINE, "done fetching messages.  getting uid's");

        long[] uids = new long[messages.length];

        for (int i = 0; i < messages.length; i++) {
          uids[i] = getUID(messages[i]);
        }

        MessageInfo mi;

        for (int i = 0; i < uids.length; i++) {
          Message m = new CachingMimeMessage(this, uids[i]);
          mi = new MessageInfo(m, this);

          messageProxies.add(new MessageProxy(getColumnValues() , mi));
          messageToInfoTable.put(m, mi);
          uidToInfoTable.put(new Long(uids[i]), mi);
        }

        return messageProxies;
      } catch (Exception e) {
        final Exception fe = e;
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
              if (getFolderDisplayUI() != null) {
                getFolderDisplayUI().showError(Pooka.getProperty("error.CachingFolder.synchronzing", "Error synchronizing with folder"), Pooka.getProperty("error.CachingFolder.synchronzing.title", "Error synchronizing with folder"), fe);
              } else {
                Pooka.getUIFactory().showError(Pooka.getProperty("error.CachingFolder.synchronzing", "Error synchronizing with folder"), Pooka.getProperty("error.CachingFolder.synchronzing.title", "Error synchronizing with folder"), fe);

              }
            }
          });
      }
    }

    long[] uids = cache.getMessageUids();
    MessageInfo mi;

    for (int i = 0; i < uids.length; i++) {
      Message m = new CachingMimeMessage(this, uids[i]);
      mi = new MessageInfo(m, this);
      MessageProxy mp = new MessageProxy(getColumnValues() , mi);
      mp.setRefresh(true);
      messageProxies.add(mp);
      messageToInfoTable.put(m, mi);
      uidToInfoTable.put(new Long(uids[i]), mi);
    }

    return messageProxies;
  }

  /**
   * Updates any caching information, if necessary.
   */
  protected void updateCache() throws MessagingException {
    if (isConnected()) {
      synchronizeCache();
    }
  }

  /**
   * Fetches the information for the given messages using the given
   * FetchProfile.
   */
  /* original version
     public void fetch(MessageInfo[] messages, FetchProfile profile) throws MessagingException {
     // if we're connected, go ahead and fetch these.

     if (getLogger().isLoggable(Level.FINE)) {
     if (messages == null)
     getLogger().log(Level.FINE, "cachingFolderInfo:  fetching with null messages.");
     else
     getLogger().log(Level.FINE, "cachingFolderInfo:  fetching " + messages.length + " messages.");
     }

     int cacheStatus = -1;
     boolean doFlags = profile.contains(FetchProfile.Item.FLAGS);
     boolean doHeaders = (profile.contains(FetchProfile.Item.ENVELOPE) || profile.contains(FetchProfile.Item.CONTENT_INFO));

     if (doFlags && doHeaders) {
     cacheStatus = SimpleFileCache.FLAGS_AND_HEADERS;
     } else if (doFlags) {
     cacheStatus = SimpleFileCache.FLAGS;
     } else if (doHeaders) {
     cacheStatus = SimpleFileCache.HEADERS;
     }

     if (isConnected()) {

     if (getLogger().isLoggable(Level.FINE)) {
     getLogger().log(Level.FINE, "CachingFolderInfo:  running fetch against folder.");
     }
     super.fetch(messages, profile);

     if (cacheStatus != -1) {
     for (int i = 0; i < messages.length; i++) {
     Message m = messages[i].getRealMessage();
     if (m != null) {
     long uid = getUID(m);
     getCache().cacheMessage((MimeMessage)m, uid, cache.getUIDValidity(), cacheStatus);
     }
     }
     }
     } else {
     // if we're not connected, then go ahead and preload the cache for
     // these.
     for (int i = 0; i < messages.length; i++) {
     Message current = messages[i].getMessage();
     if (current != null && current instanceof UIDMimeMessage) {
     long uid = ((UIDMimeMessage) current).getUID();
     if (cacheStatus == SimpleFileCache.FLAGS_AND_HEADERS || cacheStatus == SimpleFileCache.FLAGS) {
     getCache().getFlags(uid, cache.getUIDValidity());
     }

     if (cacheStatus == SimpleFileCache.FLAGS_AND_HEADERS || cacheStatus == SimpleFileCache.HEADERS) {
     getCache().getHeaders(uid, cache.getUIDValidity());
     }
     }

     messages[i].setFetched(true);
     }
     }

     }
  */
  // new version
  public void fetch(MessageInfo[] messages, FetchProfile profile) throws MessagingException {
    // if we're connected, go ahead and fetch these.

    if (getLogger().isLoggable(Level.FINE)) {
      if (messages == null)
        getLogger().log(Level.FINE, "cachingFolderInfo:  fetching with null messages.");
      else
        getLogger().log(Level.FINE, "cachingFolderInfo:  fetching " + messages.length + " messages.");
    }

    int cacheStatus = -1;
    boolean doFlags = profile.contains(FetchProfile.Item.FLAGS);
    String[] headers = profile.getHeaderNames();
    boolean doHeaders = (profile.contains(FetchProfile.Item.ENVELOPE) || profile.contains(FetchProfile.Item.CONTENT_INFO) || profile.contains(com.sun.mail.imap.IMAPFolder.FetchProfileItem.HEADERS) || (headers != null && headers.length > 0));

    if (doFlags && doHeaders) {
      cacheStatus = SimpleFileCache.FLAGS_AND_HEADERS;
    } else if (doFlags) {
      cacheStatus = SimpleFileCache.FLAGS;
    } else if (doHeaders) {
      cacheStatus = SimpleFileCache.HEADERS;
    }

    if (isConnected()) {

      if (getLogger().isLoggable(Level.FINE)) {
        getLogger().log(Level.FINE, "CachingFolderInfo:  connected.  checking for already-cached messages.");
      }

      if (doHeaders) {
        // assume that headers don't change.
        FetchProfile fp = new FetchProfile();
        if (doFlags) {
          fp.add(FetchProfile.Item.FLAGS);
        }

        java.util.LinkedList flagsOnly = new java.util.LinkedList();
        java.util.LinkedList headersAndFlags = new java.util.LinkedList();

        for (int i = 0 ; i < messages.length; i++) {
          Message current = messages[i].getMessage();
          if (current != null && current instanceof UIDMimeMessage) {
            long uid = ((UIDMimeMessage) current).getUID();
            if (getCache().getCacheStatus(((UIDMimeMessage) current).getUID()) >= MessageCache.HEADERS) {
              flagsOnly.add(messages[i]);
            } else {
              headersAndFlags.add(messages[i]);
            }
          }
        }

        if (getLogger().isLoggable(Level.FINE)) {
          getLogger().log(Level.FINE, "CachingFolderInfo:  running fetch against " + headersAndFlags.size() + " full messages, plus " + flagsOnly.size() + " flags-only messages");
        }

        MessageInfo[] headersAndFlagsArray = (MessageInfo[]) headersAndFlags.toArray(new MessageInfo[0]);
        MessageInfo[] flagsOnlyArray = (MessageInfo[]) flagsOnly.toArray(new MessageInfo[0]);
        super.fetch(headersAndFlagsArray, profile);
        super.fetch(flagsOnlyArray, fp);

        if (cacheStatus != -1) {
          for (int i = 0; i < headersAndFlagsArray.length; i++) {
            Message m = headersAndFlagsArray[i].getRealMessage();
            if (m != null) {
              long uid = getUID(m);
              getCache().cacheMessage((MimeMessage)m, uid, cache.getUIDValidity(), cacheStatus);
            }
          }

          for (int i = 0; i < flagsOnlyArray.length; i++) {
            Message m = flagsOnlyArray[i].getRealMessage();
            if (m != null) {
              long uid = getUID(m);
              getCache().cacheMessage((MimeMessage)m, uid, cache.getUIDValidity(), MessageCache.FLAGS);
            }
          }
        }
      } else {
        if (getLogger().isLoggable(Level.FINE)) {
          getLogger().log(Level.FINE, "CachingFolderInfo:  running fetch against folder.");
        }
        super.fetch(messages, profile);

        if (cacheStatus != -1) {
          for (int i = 0; i < messages.length; i++) {
            Message m = messages[i].getRealMessage();
            if (m != null) {
              long uid = getUID(m);
              getCache().cacheMessage((MimeMessage)m, uid, cache.getUIDValidity(), cacheStatus);
            }
          }
        }

      }
    } else {
      // if we're not connected, then go ahead and preload the cache for
      // these.
      for (int i = 0; i < messages.length; i++) {
        Message current = messages[i].getMessage();
        if (current != null && current instanceof UIDMimeMessage) {
          long uid = ((UIDMimeMessage) current).getUID();
          if (cacheStatus == SimpleFileCache.FLAGS_AND_HEADERS || cacheStatus == SimpleFileCache.FLAGS) {
            getCache().getFlags(uid, cache.getUIDValidity());
          }

          if (cacheStatus == SimpleFileCache.FLAGS_AND_HEADERS || cacheStatus == SimpleFileCache.HEADERS) {
            getCache().getHeaders(uid, cache.getUIDValidity());
          }
        }

        messages[i].setFetched(true);
      }
    }

  }
  // end new version
  /**
   * Refreshes the headers for the given MessageInfo.
   */
  public void refreshHeaders(MessageInfo mi) throws MessagingException {
    cacheMessage(mi, SimpleFileCache.HEADERS);
  }

  /**
   * Refreshes the flags for the given MessageInfo.
   */
  public void refreshFlags(MessageInfo mi) throws MessagingException {
    if (isConnected())
      cacheMessage(mi, SimpleFileCache.FLAGS);
  }


  /**
   * Gets the row number of the first unread message.  Returns -1 if
   * there are no unread messages, or if the FolderTableModel is not
   * set or empty.
   */

  public int getFirstUnreadMessage() {
    // one part brute, one part force, one part ignorance.

    if (getLogger().isLoggable(Level.FINE))
      getLogger().log(Level.FINE, "getting first unread message");

    if (! tracksUnreadMessages())
      return -1;

    if (getFolderTableModel() == null)
      return -1;

    if (isConnected()) {
      return super.getFirstUnreadMessage();
    } else {
      try {
        int countUnread = 0;
        int i;

        int unreadCount = cache.getUnreadMessageCount();

        if (unreadCount > 0) {
          long[] uids = getCache().getMessageUids();

          for (i = uids.length - 1; ( i >= 0 && countUnread < unreadCount) ; i--) {
            MessageInfo mi = getMessageInfoByUid(uids[i]);

            if (! mi.getFlags().contains(Flags.Flag.SEEN))
              countUnread++;
          }
          if (getLogger().isLoggable(Level.FINE))
            getLogger().log(Level.FINE, "Returning " + i);

          return i + 1;
        } else {
          if (getLogger().isLoggable(Level.FINE))
            getLogger().log(Level.FINE, "Returning -1");
          return -1;
        }
      } catch (MessagingException me) {
        if (getLogger().isLoggable(Level.FINE))
          getLogger().log(Level.FINE, "Messaging Exception.  Returning -1");
        return -1;
      }
    }

  }

  public boolean hasUnread() {
    if (! tracksUnreadMessages())
      return false;
    else
      return (getUnreadCount() > 0);
  }

  /*
    public int getUnreadCount() {
    if (! tracksUnreadMessages())
    return -1;
    else {
    try {
    if (getCache() != null)
    unreadCount = getCache().getUnreadMessageCount();
    } catch (MessagingException me) {

    }
    return unreadCount;
    }
    }

    public int getMessageCount() {
    try {
    if (getCache() != null)
    messageCount = getCache().getMessageCount();
    } catch (MessagingException me) {
    }
    return messageCount;
    }
  */

  /**
   * This forces an update of both the total and unread message counts.
   */
  public void resetMessageCounts() {
    try {
      if (getLogger().isLoggable(Level.FINE)) {
        if (getFolder() != null)
          getLogger().log(Level.FINE, "running resetMessageCounts.  unread message count is " + getFolder().getUnreadMessageCount());
        else
          getLogger().log(Level.FINE, "running resetMessageCounts.  getFolder() is null.");
      }

      if (isConnected()) {
        if (tracksUnreadMessages())
          unreadCount = getFolder().getUnreadMessageCount();
        messageCount = getFolder().getMessageCount();
      } else if (getCache() != null) {
        messageCount = getCache().getMessageCount();
        if (tracksUnreadMessages())
          unreadCount = getCache().getUnreadMessageCount();
      } else {
        // if there's no cache and no connection, don't do anything.
      }
    } catch (MessagingException me) {
      // if we lose the connection to the folder, we'll leave the old
      // messageCount and set the unreadCount to zero.
      unreadCount = 0;
    }
    updateNode();
  }

  /**
   * This synchronizes the cache with the new information from the
   * Folder.
   */
  public void synchronizeCache() throws MessagingException {

    if (getLogger().isLoggable(Level.FINE))
      getLogger().log(Level.FINE, "synchronizing cache.");

    try {
      showStatusMessage(getFolderDisplayUI(), Pooka.getProperty("message.UIDFolder.synchronizing", "Re-synchronizing with folder..."));
      if (getFolderDisplayUI() != null) {
        getFolderDisplayUI().setBusy(true);
      }

      long cacheUidValidity = getCache().getUIDValidity();

      if (uidValidity != cacheUidValidity) {
        showStatusMessage(getFolderDisplayUI(), Pooka.getProperty("error.UIDFolder.validityMismatch", "Error:  validity not correct.  reloading..."));

        getCache().invalidateCache();
        getCache().setUIDValidity(uidValidity);
        cacheUidValidity = uidValidity;
      }


      showStatusMessage(getFolderDisplayUI(), Pooka.getProperty("message.CachingFolder.synchronizing.writingChanges", "Writing local changes to server..."));

      // first write all the changes that we made back to the server.
      showStatusMessage(getFolderDisplayUI(), Pooka.getProperty("message.UIDFolder.synchronzing.writingChanges", "Writing local changes to server"));

      getCache().writeChangesToServer(getFolder());

      showStatusMessage(getFolderDisplayUI(), Pooka.getProperty("message.UIDFolder.synchronizing.loading", "Loading messages from folder..."));

      // load the list of uid's.

      FetchProfile fp = new FetchProfile();
      fp.add(UIDFolder.FetchProfileItem.UID);
      // adding FLAGS to make getFirstUnreadMessage() more efficient
      fp.add(FetchProfile.Item.FLAGS);

      if (getLogger().isLoggable(Level.FINE))
        getLogger().log(Level.FINE, "getting messages.");

      Message[] messages = getFolder().getMessages();

      if (getLogger().isLoggable(Level.FINE))
        getLogger().log(Level.FINE, "fetching messages.");

      String messageCount = messages == null ? "null" : Integer.toString(messages.length);

      showStatusMessage(getFolderDisplayUI(), Pooka.getProperty("message.UIDFolder.synchronizing.fetchingMessages", "Fetching") + " " + messageCount + " " + Pooka.getProperty("message.UIDFolder.synchronizing.messages", "messages."));

      getFolder().fetch(messages, fp);
      if (getLogger().isLoggable(Level.FINE))
        getLogger().log(Level.FINE, "done fetching messages.  getting uid's");

      long[] uids = new long[messages.length];

      for (int i = 0; i < messages.length; i++) {
        uids[i] = getUID(messages[i]);
      }

      if (getLogger().isLoggable(Level.FINE))
        getLogger().log(Level.FINE, "synchronizing--uids.length = " + uids.length);

      showStatusMessage(getFolderDisplayUI(), Pooka.getProperty("message.UIDFolder.synchronizing", "Comparing new messages to current list..."));

      long[] addedUids = cache.getAddedMessages(uids, uidValidity);

      if (getLogger().isLoggable(Level.FINE))
        getLogger().log(Level.FINE, "synchronizing--addedUids.length = " + addedUids.length);

      if (addedUids.length > 0) {
        Message[] addedMsgs = ((UIDFolder)getFolder()).getMessagesByUID(addedUids);
        MessageCountEvent mce = new MessageCountEvent(getFolder(), MessageCountEvent.ADDED, false, addedMsgs);

        showStatusMessage(getFolderDisplayUI(), Pooka.getProperty("message.UIDFolder.synchronizing.loadingMessages", "Loading") + " " + addedUids.length + " " + Pooka.getProperty("message.UIDFolder.synchronizing.messages", "messages."));

        messagesAdded(mce);
      }

      long[] removedUids = cache.getRemovedMessages(uids, uidValidity);
      if (getLogger().isLoggable(Level.FINE))
        getLogger().log(Level.FINE, "synchronizing--removedUids.length = " + removedUids.length);

      if (removedUids.length > 0) {
        Message[] removedMsgs = new Message[removedUids.length];
        for (int i = 0 ; i < removedUids.length; i++) {

          MessageInfo mi =  getMessageInfoByUid(removedUids[i]);
          if (mi != null)
            removedMsgs[i] = mi.getMessage();

          if (removedMsgs[i] == null) {
            removedMsgs[i] = new CachingMimeMessage(this, removedUids[i]);
          }
        }
        MessageCountEvent mce = new MessageCountEvent(getFolder(), MessageCountEvent.REMOVED, false, removedMsgs);

        showStatusMessage(getFolderDisplayUI(), Pooka.getProperty("message.UIDFolder.synchronizing.removingMessages", "Removing") + " " + removedUids.length + " " + Pooka.getProperty("message.UIDFolder.synchronizing.messages", "messages."));

        messagesRemoved(mce);
      }

      updateFlags(uids, messages, cacheUidValidity);

    } finally {
      if (getFolderDisplayUI() != null) {
        getFolderDisplayUI().clearStatusMessage();
        getFolderDisplayUI().setBusy(false);
      } else
        Pooka.getUIFactory().clearStatus();
    }

  }

  protected void runMessagesAdded(MessageCountEvent mce) {
    if (folderTableModel != null) {
      Message[] addedMessages = mce.getMessages();

      int fetchBatchSize = 25;
      int loadBatchSize = 25;
      try {
        fetchBatchSize = Integer.parseInt(Pooka.getProperty("Pooka.fetchBatchSize", "50"));
      } catch (NumberFormatException nfe) {
      }

      MessageInfo mi;
      Vector addedProxies = new Vector();
      List addedInfos = new java.util.ArrayList();
      for (int i = 0; i < addedMessages.length; i++) {
        if (addedMessages[i] instanceof CachingMimeMessage) {
          long uid = ((CachingMimeMessage) addedMessages[i]).getUID();
          mi = getMessageInfoByUid(uid);
          if (mi != null) {
            addedInfos.add(mi);
            if (getLogger().isLoggable(Level.FINE))
              getLogger().log(Level.FINE, getFolderID() + ":  this is a duplicate.  not making a new messageinfo for it.");
          } else {
            mi = new MessageInfo(addedMessages[i], CachingFolderInfo.this);
            addedInfos.add(mi);
            addedProxies.add(new MessageProxy(getColumnValues(), mi));
            messageToInfoTable.put(addedMessages[i], mi);
            uidToInfoTable.put(new Long(((CachingMimeMessage) addedMessages[i]).getUID()), mi);
          }

          // we need to autoCache either way.
          /*
            try {
            if (autoCache) {
            showStatusMessage(getFolderDisplayUI(), "caching " + i + " of " + addedMessages.length + " messages....");
            getCache().cacheMessage((MimeMessage)addedMessages[i], ((CachingMimeMessage)addedMessages[i]).getUID(), getUIDValidity(), SimpleFileCache.MESSAGE, false);
            } else {
            getCache().cacheMessage((MimeMessage)addedMessages[i], ((CachingMimeMessage)addedMessages[i]).getUID(), getUIDValidity(), SimpleFileCache.FLAGS_AND_HEADERS, false);
            }
            } catch (MessagingException me) {
            getLogger().log(Level.FINE, "caught exception:  " + me);
            me.printStackTrace();
            }
          */
        } else {
          // it's a 'real' message from the server.

          long uid = -1;
          try {
            uid = getUID(addedMessages[i]);
          } catch (MessagingException me) {
          }

          mi = getMessageInfoByUid(uid);
          if (mi != null) {
            addedInfos.add(mi);
            if (getLogger().isLoggable(Level.FINE))
              getLogger().log(Level.FINE, getFolderID() + ":  this is a duplicate.  not making a new messageinfo for it.");

            // but we still need to autocache it if we're autocaching.
            if (autoCache) {
              mMessageLoader.cacheMessages(new MessageProxy[] { getMessageInfoByUid(uid).getMessageProxy()});
            }
          } else {
            CachingMimeMessage newMsg = new CachingMimeMessage(CachingFolderInfo.this, uid);
            mi = new MessageInfo(newMsg, CachingFolderInfo.this);
            addedInfos.add(mi);
            addedProxies.add(new MessageProxy(getColumnValues(), mi));
            messageToInfoTable.put(newMsg, mi);
            uidToInfoTable.put(new Long(uid), mi);
          }

          /*
            try {
            if (autoCache) {
            showStatusMessage(getFolderDisplayUI(), getFolderID() + ":  " + Pooka.getProperty("info.UIDFolder.synchronizing.cachingMessages", "Caching") + " " + i + " " + Pooka.getProperty("info.UIDFolder.synchronizing.of", "of") + " " + addedMessages.length + Pooka.getProperty("info.UIDFolder.synchronizing.messages", "messages") + "....");
            getCache().cacheMessage((MimeMessage)addedMessages[i], uid, getUIDValidity(), SimpleFileCache.MESSAGE, false);
            } else {
            getCache().cacheMessage((MimeMessage)addedMessages[i], uid, getUIDValidity(), SimpleFileCache.FLAGS_AND_HEADERS, false);
            }
            } catch (MessagingException me) {
            getLogger().log(Level.FINE, "caught exception:  " + me);
            me.printStackTrace();
            }
          */
        }
      }

      try {
        List preloadMessages = addedInfos;
        if (addedInfos.size() > fetchBatchSize) {
          preloadMessages = addedInfos.subList(0, fetchBatchSize);
        }
        MessageInfo[] preloadArray = new MessageInfo[preloadMessages.size()];
        for (int i = 0; i < preloadMessages.size(); i++) {
          preloadArray[i] = (MessageInfo) preloadMessages.get(i);
        }
        fetch(preloadArray, fetchProfile);
      } catch (MessagingException me) {
        getLogger().warning("error prefetching messages:  " + me.toString());
      }
      /*
        for (int i = 0; i < preloadMessages.length; i++) {
        long uid = -1;
        try {
        uid = getUID(preloadMessages[i]);
        } catch (MessagingException me) {
        }
        try {
        // FIXME
        getCache().cacheMessage((MimeMessage)preloadMessages[i], uid, getUIDValidity(), SimpleFileCache.FLAGS_AND_HEADERS, false);
        } catch (Exception e) {

        }
        }
      */

      getCache().writeMsgFile();

      clearStatusMessage(getFolderDisplayUI());

      addedProxies.removeAll(applyFilters(addedProxies));
      if (addedProxies.size() > 0) {
        if (getFolderTableModel() != null)
          getFolderTableModel().addRows(addedProxies);
        setNewMessages(true);
        resetMessageCounts();

        // notify the message loaded thread.
        MessageProxy[] addedArray = (MessageProxy[]) addedProxies.toArray(new MessageProxy[0]);
        //loaderThread.loadMessages(addedArray, net.suberic.pooka.thread.LoadMessageThread.HIGH);
        mMessageLoader.loadMessages(addedArray, net.suberic.pooka.thread.MessageLoader.HIGH);

        if (autoCache) {
          mMessageLoader.cacheMessages(addedArray);
        }

        // change the Message objects in the MessageCountEvent to
        // our UIDMimeMessages.
        Message[] newMsgs = new Message[addedProxies.size()];
        for (int i = 0; i < addedProxies.size(); i++) {
          newMsgs[i] = ((MessageProxy)addedProxies.elementAt(i)).getMessageInfo().getMessage();
        }
        MessageCountEvent newMce = new MessageCountEvent(getFolder(), mce.getType(), mce.isRemoved(), newMsgs);
        fireMessageCountEvent(newMce);
      }

    }
  }

  /**
   * This does the real work when messages are removed.
   *
   * This method should always be run on the FolderThread.
   */
  protected void runMessagesRemoved(MessageCountEvent mce) {
    Message[] removedMessages = mce.getMessages();
    Message[] removedCachingMessages = new Message[removedMessages.length];

    if (getLogger().isLoggable(Level.FINE))
      getLogger().log(Level.FINE, "removedMessages was of size " + removedMessages.length);
    MessageInfo mi;
    Vector removedProxies=new Vector();

    for (int i = 0; i < removedMessages.length; i++) {
      if (getLogger().isLoggable(Level.FINE))
        getLogger().log(Level.FINE, "checking for existence of message.");

      if (removedMessages[i] != null && removedMessages[i] instanceof CachingMimeMessage) {
        removedCachingMessages[i] = removedMessages[i];
        long uid = ((CachingMimeMessage) removedMessages[i]).getUID();
        mi = getMessageInfoByUid(uid);

        if (mi != null) {
          if (getLogger().isLoggable(Level.FINE))
            getLogger().log(Level.FINE, "message exists--removing");
          if ( mi.getMessageProxy() != null) {
            mi.getMessageProxy().close();
            removedProxies.add(mi.getMessageProxy());
          }
          messageToInfoTable.remove(mi);
          uidToInfoTable.remove(new Long(((CachingMimeMessage) removedMessages[i]).getUID()));
        }

        getCache().invalidateCache(((CachingMimeMessage) removedMessages[i]).getUID(), SimpleFileCache.MESSAGE);

      } else {
        // not a CachingMimeMessage.
        long uid = -1;
        try {
          uid = getUID(removedMessages[i]);
        } catch (MessagingException me) {
        }

        mi = getMessageInfoByUid(uid);
        if (mi != null) {
          removedCachingMessages[i] = mi.getMessage();
          if (mi.getMessageProxy() != null)
            mi.getMessageProxy().close();

          if (getLogger().isLoggable(Level.FINE))
            getLogger().log(Level.FINE, "message exists--removing");

          Message localMsg = mi.getMessage();
          removedProxies.add(mi.getMessageProxy());
          messageToInfoTable.remove(localMsg);
          uidToInfoTable.remove(new Long(uid));
        } else {
          removedCachingMessages[i] = removedMessages[i];
        }
        getCache().invalidateCache(uid, SimpleFileCache.MESSAGE);
      }
    }

    MessageCountEvent newMce = new MessageCountEvent(getFolder(), mce.getType(), mce.isRemoved(), removedCachingMessages);

    if (getFolderDisplayUI() != null) {
      if (removedProxies.size() > 0) {
        getFolderDisplayUI().removeRows(removedProxies);
      }
      resetMessageCounts();
      fireMessageCountEvent(newMce);
    } else {
      resetMessageCounts();
      fireMessageCountEvent(newMce);
      if (removedProxies.size() > 0)
        getFolderTableModel().removeRows(removedProxies);
    }
  }

  /**
   * This updates the TableInfo on the changed messages.
   *
   * As defined by java.mail.MessageChangedListener.
   */

  public void runMessageChanged(MessageChangedEvent mce) {
    // if the message is getting deleted, then we don't
    // really need to update the table info.  for that
    // matter, it's likely that we'll get MessagingExceptions
    // if we do, anyway.

    boolean updateInfo = false;
    try {
      updateInfo = (!mce.getMessage().isSet(Flags.Flag.DELETED) || ! Pooka.getProperty("Pooka.autoExpunge", "true").equalsIgnoreCase("true"));
    } catch (MessagingException me) {
      // if we catch a MessagingException, it just means
      // that the message has already been expunged.  in
      // that case, assume it's ok if we don't update; it'll
      // happen in the messagesRemoved().
    }

    if (updateInfo) {
      try {
        Message msg = mce.getMessage();
        long uid = -1;
        uid = getUID(msg);

        if (msg != null){
          if (mce.getMessageChangeType() == MessageChangedEvent.FLAGS_CHANGED)
            getCache().cacheMessage((MimeMessage)msg, uid, uidValidity, SimpleFileCache.FLAGS);
          else if (mce.getMessageChangeType() == MessageChangedEvent.ENVELOPE_CHANGED)
            getCache().cacheMessage((MimeMessage)msg, uid, uidValidity, SimpleFileCache.HEADERS);
        }

        MessageInfo mi = getMessageInfoByUid(uid);
        if (mi != null) {
          MessageProxy mp = mi.getMessageProxy();
          if (mp != null) {
            mp.unloadTableInfo();
            mp.loadTableInfo();
          }
        }

      } catch (MessagingException me) {
        // if we catch a MessagingException, it just means
        // that the message has already been expunged.
      }

      // if we're not just a tableinfochanged event, do a resetmessagecouts.
      // don't do this if we're just a delete.
      if (! (mce instanceof net.suberic.pooka.event.MessageTableInfoChangedEvent)) {
        resetMessageCounts();
      }

    }

    fireMessageChangedEvent(mce);
  }

  /**
   * This sets the given Flag for all the MessageInfos given.
   */
  public void setFlags(MessageInfo[] msgs, Flags flag, boolean value) throws MessagingException {
    // no optimization here.
    for (int i = 0; i < msgs.length; i++) {
      msgs[i].getRealMessage().setFlags(flag, value);
    }
  }

  /**
   * This copies the given messages to the given FolderInfo.
   */
  public void copyMessages(MessageInfo[] msgs, FolderInfo targetFolder) throws MessagingException, OperationCancelledException {
    if (isConnected())
      super.copyMessages(msgs, targetFolder);
    else
      targetFolder.appendMessages(msgs);
  }

  /**
   * This appends the given message to the given FolderInfo.
   */
  public void appendMessages(MessageInfo[] msgs) throws MessagingException, OperationCancelledException {
    if (isAvailable()) {
      if (isConnected()) {
        super.appendMessages(msgs);
      } else {
        // make sure we've loaded
        if (! isLoaded())
          loadFolder();
        getCache().appendMessages(msgs);
      }
    } else {
      throw new MessagingException("cannot append messages to an unavailable folder.");
    }
  }

  /**
   * This expunges the deleted messages from the Folder.
   */
  public void expunge() throws MessagingException, OperationCancelledException {
    if (isConnected())
      getFolder().expunge();
    else if (shouldBeConnected()) {
      openFolder(Folder.READ_WRITE);
      getFolder().expunge();
    } else {
      getCache().expungeMessages();
    }
  }

  /**
   * This attempts to cache the message represented by this MessageInfo.
   */
  public void cacheMessage (MessageInfo info, int cacheStatus) throws MessagingException {
    if (status == CONNECTED) {
      Message m = info.getMessage();
      if (m instanceof CachingMimeMessage) {
        long uid = ((CachingMimeMessage)m).getUID();
        MimeMessage realMessage = getRealMessageById(uid);
        getCache().cacheMessage(realMessage, uid, uidValidity, cacheStatus);
      } else if (m instanceof MimeMessage) {
        long uid = getUID(m);
        getCache().cacheMessage((MimeMessage)m, uid, uidValidity, cacheStatus);
      } else {
        throw new MessagingException(Pooka.getProperty("error.CachingFolderInfo.unknownMessageType", "Error:  unknownMessageType."));
      }
    } else {
      throw new MessagingException(Pooka.getProperty("error.CachingFolderInfo.cacheWhileDisconnected", "Error:  You cannot cache messages unless you\nare connected to the folder."));
    }
  }


  /**
   * Creates a child folder.
   */
  protected FolderInfo createChildFolder(String newFolderName) {
    if (! Pooka.getProperty(getFolderProperty() + "." + newFolderName + ".cacheMessages", "true").equalsIgnoreCase("false")) {
      return new CachingFolderInfo(this, newFolderName);
    } else if (Pooka.getProperty(getParentStore().getStoreProperty() + ".protocol", "mbox").equalsIgnoreCase("imap")) {
      return new UIDFolderInfo(this, newFolderName);
    } else {
      return new FolderInfo(this, newFolderName);
    }
  }

  /**
   * This method closes the Folder.  If you open the Folder using
   * openFolder (which you should), then you should use this method
   * instead of calling getFolder.close().  If you don't, then the
   * FolderInfo will try to reopen the folder.
   */
  public void closeFolder(boolean expunge) throws MessagingException {
    closeFolder(expunge, false);
  }

  /**
   * This method closes the Folder.  If you open the Folder using
   * openFolder (which you should), then you should use this method
   * instead of calling getFolder.close().  If you don't, then the
   * FolderInfo will try to reopen the folder.
   */
  public void closeFolder(boolean expunge, boolean closeDisplay) throws MessagingException {

    if (closeDisplay && getFolderDisplayUI() != null)
      getFolderDisplayUI().closeFolderDisplay();

    if (isLoaded() && isAvailable()) {
      if (isConnected()) {
        try {
          getFolder().close(expunge);
        } catch (java.lang.IllegalStateException ise) {
          throw new MessagingException(ise.getMessage(), ise);
        }
      }

      if (getCache() != null) {
        setStatus(DISCONNECTED);
      } else {
        setStatus(CLOSED);
      }
    }

  }

  /**
   * This unsubscribes this FolderInfo and all of its children, if
   * applicable.
   *
   * For the CachingFolderInfo, this calls super.unsubscribe() and
   * getCache().invalidateCache().
   */
  public void unsubscribe() {
    super.unsubscribe();
    getCache().invalidateCache();
  }

  /**
   * Searches for messages in this folder which match the given
   * SearchTerm.
   *
   * Basically wraps the call to Folder.search(), and then wraps the
   * returned Message objects as MessageInfos.
   */
  public MessageInfo[] search(javax.mail.search.SearchTerm term)
    throws MessagingException, OperationCancelledException {
    if (isConnected()) {
      return super.search(term);
    } else {
      return getCache().search(term);
    }
  }

  /**
   * The resource for the default display filters.
   */
  protected String getDefaultDisplayFiltersResource() {
    if (getCacheHeadersOnly()) {
      return super.getDefaultDisplayFiltersResource();
    } else if (isSentFolder())
      return "CachingFolderInfo.sentFolderDefaultDisplayFilters";
    else
      return "CachingFolderInfo.defaultDisplayFilters";
  }

  /**
   * Returns whether or not a given message is fully cached.
   */
  public boolean isCached(long uid) {
    return getCache().isFullyCached(uid);
  }

  /**
   * This returns the MessageCache associated with this FolderInfo,
   * if any.
   */
  public MessageCache getCache() {
    return cache;
  }

  /**
   * Returns whether or not we should be showing cache information in
   * the FolderDisplay.  Uses the FolderProperty.showCacheInfo property
   * to determine--if this is set to true, we will show the cache info.
   * Otherwise, if we're connected, don't show the info, and if we're
   * not connected, do.
   */
  public boolean showCacheInfo() {
    if (Pooka.getProperty(getFolderProperty() + ".showCacheInfo", "false").equalsIgnoreCase("true"))
      return true;
    else {
      if (getStatus() == CONNECTED) {
        return false;
      } else
        return true;
    }
  }

  /**
   * Returns the cache directory for this FolderInfo.
   */
  public String getCacheDirectory() {
    String localDir = Pooka.getResourceManager().translateName(Pooka.getProperty(getFolderProperty() + ".cacheDir", ""));
    if (!localDir.equals(""))
      return localDir;

    localDir = Pooka.getProperty("Pooka.defaultMailSubDir", "");
    if (localDir.equals(""))
      localDir = Pooka.getPookaManager().getPookaRoot().getAbsolutePath() + File.separator + ".pooka";

    localDir = Pooka.getResourceManager().translateName(localDir);

    localDir = localDir + File.separatorChar + "cache";
    FolderInfo currentFolder = this;
    StringBuffer subDir = new StringBuffer();
    subDir.insert(0, currentFolder.getFolderName());
    subDir.insert(0, File.separatorChar);
    while (currentFolder.getParentFolder() != null) {
      currentFolder = currentFolder.getParentFolder();
      subDir.insert(0, currentFolder.getFolderName());
      subDir.insert(0, File.separatorChar);
    }

    subDir.insert(0, currentFolder.getParentStore().getStoreID());
    subDir.insert(0, File.separatorChar);

    return localDir + subDir.toString();
  }

  public boolean isLoaded() {
    return (getFolder() != null && ( ! (getFolder() instanceof FolderProxy)) && cache != null);
  }

  /**
   * Gets the UID for the given Message.
   */
  public long getUID(Message m) throws MessagingException {
    if (m instanceof SimpleFileCache.LocalMimeMessage) {
      return ((SimpleFileCache.LocalMimeMessage) m).getUID();
    } else {
      return super.getUID(m);
    }
  }

  /**
   * Shows a status message, using the given FolderDisplayUI if not null.
   */
  public void showStatusMessage(net.suberic.pooka.gui.FolderDisplayUI pUI, String message) {
    if (pUI != null)
      pUI.showStatusMessage(message);
    else
      Pooka.getUIFactory().showStatusMessage(message);
  }

  /**
   * This handles the changes if the source property is modified.
   *
   * As defined in net.suberic.util.ValueChangeListener.
   */

  public void valueChanged(String changedValue) {
    if (changedValue.equals(getFolderProperty() + ".autoCache") || changedValue.equals(getParentStore().getStoreProperty() + ".autoCache")) {
      if (! getCacheHeadersOnly()) {
        autoCache =  Pooka.getProperty(getFolderProperty() + ".autoCache", Pooka.getProperty(getFolderProperty() + ".autoCache", Pooka.getProperty(getParentStore().getStoreProperty() + ".autoCache", Pooka.getProperty("Pooka.autoCache", "false")))).equalsIgnoreCase("true");
      }
    } else if (changedValue.equals(getFolderProperty() + ".cacheHeadersOnly") || changedValue.equals(getParentStore().getStoreProperty() + ".cacheHeadersOnly")) {
      if (! getCacheHeadersOnly()) {
        autoCache =  Pooka.getProperty(getFolderProperty() + ".autoCache", Pooka.getProperty(getParentStore().getStoreProperty() + ".autoCache", Pooka.getProperty("Pooka.autoCache", "false"))).equalsIgnoreCase("true");
      }
      createFilters();
      if (getFolderNode() != null)
        getFolderNode().popupMenu = null;
    } else {
      super.valueChanged(changedValue);
    }
  }

  /**
   * Returns if we're caching only headers.
   */
  public boolean getCacheHeadersOnly() {
    return Pooka.getProperty(getFolderProperty() + ".cacheHeadersOnly", Pooka.getProperty(getParentStore().getStoreProperty() + ".cacheHeadersOnly", "false")).equalsIgnoreCase("true");
  }
}
TOP

Related Classes of net.suberic.pooka.cache.CachingFolderInfo

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.