JwmaFolderList.java :  » Web-Mail » Jwma » dtw » webmail » model » Java Open Source

Java Open Source » Web Mail » Jwma 
Jwma » dtw » webmail » model » JwmaFolderList.java
/***
 * jwma Java WebMail
 * Copyright (c) 2000-2003 jwma team
 *
 * jwma is free software; you can distribute and use this source
 * under the terms of the BSD-style license received along with
 * the distribution.
 ***/
package dtw.webmail.model;

import dtw.webmail.util.StringUtil;
import org.apache.log4j.Logger;

import javax.mail.Folder;
import javax.mail.MessagingException;
import java.util.*;

/**
 * Class implementing a list for <tt>JwmaFolder</tt>
 * instances.
 * It has caching functionality, which reduces the need to
 * reconstruct the list after moving and deleting folders.
 *
 * @author Dieter Wimberger
 * @version 0.9.7 07/02/2003
 */
class JwmaFolderList {

  //logging
  private static Logger log = Logger.getLogger(JwmaFolderList.class);

  //class attributes
  public static boolean c_SubscribedOnly = true;

  //instance attributes
  private Folder m_Folder;
  private List m_Folders;
  private boolean m_Recursive;
  private boolean m_SubscribedOnly = c_SubscribedOnly;
  private String m_Pattern;

  /**
   * Constructs a new <tt>JwmaFolderList</tt> instance.
   *
   * @param f the folder to be listed as <tt>javax.mail.Folder</tt>.
   * @param recurse flags if the list should be build recursive.
   */
  private JwmaFolderList(Folder f, boolean recurse) {
    m_Recursive = recurse;
    if (recurse) {
      m_Pattern = "*";
    } else {
      m_Pattern = "%";
    }
    m_Folder = f;
  }//JwmaFolderList

  /**
   * Tests if this <tt>JwmaFolderList</tt> will work
   * only with subscribed folders.
   *
   * @return true if subscribed only, false otherwise.
   */
  public boolean isSubscribedOnly() {
    return m_SubscribedOnly;
  }//isSubscribedOnly

  /**
   * Sets or resets the flag for working only with
   * subscribed folders.
   */
  public void setSubscribedOnly(boolean subscribedOnly) {
    m_SubscribedOnly = subscribedOnly;
  }//setSubscribedOnly

  /**
   * Sets the pattern used for listing folders.
   *
   * @return the pattern as <tt>String</tt>.
   */
  public String getPattern() {
    return m_Pattern;
  }//getPattern

  /**
   * Returns the pattern for listing folders.
   *
   * @param pattern the pattern as <tt>String</tt>.
   */
  public void setPattern(String pattern) {
    m_Pattern = pattern;
  }//setPattern

  /**
   * Returns an Iterator over the <tt>JwmaFolder</tt> instances
   * contained within this list.
   *
   * @return the <tt>Iterator</tt> over the items in this list.
   */
  public Iterator iterator() {
    return m_Folders.listIterator();
  }//iterator


  /**
   * Returns the size of this list.
   *
   * @return the size of this list.
   */
  public int size() {
    return m_Folders.size();
  }//getSize

  /**
   * Returns a sublist of this list, that contains only
   * the folders of the given type.
   *
   * @param type the requested folder type as <tt>int</tt>.
   *
   * @return the list containing all folders of the given type as
   *         <tt>List</tt>.
   */
  public List sublist(int type) {

    if (type == JwmaFolder.TYPE_ALL) {
      return m_Folders;
    } else {
      List folders = new ArrayList();
      for (Iterator iter = m_Folders.listIterator(); iter.hasNext();) {
        JwmaFolderImpl f = (JwmaFolderImpl) iter.next();
        switch (type) {
          case JwmaFolder.TYPE_MESSAGE_CONTAINER:
            if (f.isType(JwmaFolder.TYPE_MAILBOX)
                || f.isType(JwmaFolder.TYPE_MIXED)) {
              folders.add(f);
            }
            break;
          case JwmaFolder.TYPE_FOLDER_CONTAINER:
            if (f.isType(JwmaFolder.TYPE_FOLDER)
                || f.isType(JwmaFolder.TYPE_MIXED)) {
              folders.add(f);
            }
            break;
          default:
            if (f.isType(type)) {
              folders.add(f);
            }
        }
      }
      //force sort
      Collections.sort(folders, LEXOGRAPHICAL);
      return folders;
    }
  }//sublist


  /**
   * Returns a sublist of this list, that contains only
   * the folders of the given type.
   *
   * @param type the requested folder type as <tt>int</tt>.
   *
   * @return the list containing all folders of the given type as
   *         <tt>List</tt>.
   */
  public List sublist(int type, boolean subscribed) {

    if (type == JwmaFolder.TYPE_ALL) {
      return m_Folders;
    } else {
      List folders = new ArrayList();
      for (Iterator iter = m_Folders.listIterator(); iter.hasNext();) {
        JwmaFolderImpl f = (JwmaFolderImpl) iter.next();
        switch (type) {
          case JwmaFolder.TYPE_MESSAGE_CONTAINER:
            if (f.isType(JwmaFolder.TYPE_MAILBOX)
                || f.isType(JwmaFolder.TYPE_MIXED)) {
              if (subscribed) {
                if (f.isSubscribed()) {
                  folders.add(f);
                }
              } else {
                folders.add(f);
              }
            }
            break;
          case JwmaFolder.TYPE_FOLDER_CONTAINER:
            if (f.isType(JwmaFolder.TYPE_FOLDER)
                || f.isType(JwmaFolder.TYPE_MIXED)) {
              if (subscribed) {
                if (f.isSubscribed()) {
                  folders.add(f);
                }
              } else {
                folders.add(f);
              }
            }
            break;
          default:
            if (f.isType(type)) {
              if (subscribed) {
                if (f.isSubscribed()) {
                  folders.add(f);
                }
              } else {
                folders.add(f);
              }
            }
        }
      }
      //force sort
      Collections.sort(folders, LEXOGRAPHICAL);
      return folders;
    }
  }//sublist

  /**
   * Returns a sublist of this list, that contains only
   * the folders of the given type, filtering the given
   * folder.
   * This method can be used to obtain targets for moving
   * messages or other folders.
   *
   * @param type the requested folder type as <tt>int</tt>.
   * @param folder the <tt>JwmaFolderImpl</tt> instance to be filtered
   *        from the list.
   *
   * @return the list containing all folders of the given type as
   *         <tt>List</tt>.
   */
  public List sublist(int type, JwmaFolderImpl folder) {

    List folders = new ArrayList();
    for (Iterator iter = m_Folders.listIterator(); iter.hasNext();) {
      JwmaFolderImpl f = (JwmaFolderImpl) iter.next();
      if (f.equals(folder)) {
        //filter this one
        continue;
      }
      switch (type) {
        case JwmaFolder.TYPE_ALL:
          folders.add(f);
          break;
        case JwmaFolder.TYPE_MESSAGE_CONTAINER:
          if (f.isType(JwmaFolder.TYPE_MAILBOX)
              || f.isType(JwmaFolder.TYPE_MIXED)) {
            folders.add(f);
          }
          break;
        case JwmaFolder.TYPE_FOLDER_CONTAINER:
          if (f.isType(JwmaFolder.TYPE_FOLDER)
              || f.isType(JwmaFolder.TYPE_MIXED)) {
            folders.add(f);
          }
          break;
        default:
          if (f.isType(type)) {
            folders.add(f);
          }
      }
    }
    //force sort
    Collections.sort(folders, LEXOGRAPHICAL);
    return folders;
  }//sublist


  /**
   * Returns a sublist of this list, that contains only
   * the folders of the given type, filtering the given
   * folder.
   * This method can be used to obtain targets for moving
   * messages or other folders.
   *
   * @param type the requested folder type as <tt>int</tt>.
   * @param folder the <tt>JwmaFolderImpl</tt> instance to be filtered
   *        from the list.
   *
   * @return the list containing all folders of the given type as
   *         <tt>List</tt>.
   */
  public List sublist(int type, JwmaFolderImpl folder, boolean subscribed) {

    List folders = new ArrayList();
    for (Iterator iter = m_Folders.listIterator(); iter.hasNext();) {
      JwmaFolderImpl f = (JwmaFolderImpl) iter.next();
      if (f.equals(folder)) {
        //filter this one
        continue;
      }
      switch (type) {
        case JwmaFolder.TYPE_ALL:
          if (subscribed) {
            if (f.isSubscribed()) {
              folders.add(f);
            }
          } else {
            folders.add(f);
          }
          break;
        case JwmaFolder.TYPE_MESSAGE_CONTAINER:
          if (f.isType(JwmaFolder.TYPE_MAILBOX)
              || f.isType(JwmaFolder.TYPE_MIXED)) {
            if (subscribed) {
              if (f.isSubscribed()) {
                folders.add(f);
              }
            } else {
              folders.add(f);
            }
          }
          break;
        case JwmaFolder.TYPE_FOLDER_CONTAINER:
          if (f.isType(JwmaFolder.TYPE_FOLDER)
              || f.isType(JwmaFolder.TYPE_MIXED)) {
            if (subscribed) {
              if (f.isSubscribed()) {
                folders.add(f);
              }
            } else {
              folders.add(f);
            }
          }
          break;
        default:
          if (f.isType(type)) {
            if (subscribed) {
              if (f.isSubscribed()) {
                folders.add(f);
              }
            } else {
              folders.add(f);
            }
          }
      }
    }
    //force sort
    Collections.sort(folders, LEXOGRAPHICAL);
    return folders;
  }//sublist

  /**
   * Returns a sublist of this list, that contains only
   * the folders of the given type, filtering the given
   * folders.
   * This method should be used to obtain a list of subscribed
   * or unsubscribed folders, pasing in the special folders (trash,
   * draft etc.)
   *
   * @param type the requested folder type as <tt>int</tt>.
   * @param exfolders the folders (by path) to be filtered
   *        from the list as <tt>String[]</tt>.
   *
   * @return the list containing all folders of the given type as
   *         <tt>List</tt>.
   */
  public List sublist(int type, String[] exfolders, boolean subscribed) {
    List folders = new ArrayList();
    for (Iterator iter = m_Folders.listIterator(); iter.hasNext();) {
      JwmaFolderImpl f = (JwmaFolderImpl) iter.next();

      if (StringUtil.contains(exfolders, f.getPath())) {
        continue;
      } else {
        switch (type) {
          case JwmaFolder.TYPE_ALL:
            if (subscribed) {
              if (f.isSubscribed()) {
                folders.add(f);
              }
            } else {
              folders.add(f);
            }
            break;
          case JwmaFolder.TYPE_MESSAGE_CONTAINER:
            if (f.isType(JwmaFolder.TYPE_MAILBOX)
                || f.isType(JwmaFolder.TYPE_MIXED)) {
              if (subscribed) {
                if (f.isSubscribed()) {
                  folders.add(f);
                }
              } else {
                folders.add(f);
              }
            }
            break;
          case JwmaFolder.TYPE_FOLDER_CONTAINER:
            if (f.isType(JwmaFolder.TYPE_FOLDER)
                || f.isType(JwmaFolder.TYPE_MIXED)) {
              if (subscribed) {
                if (f.isSubscribed()) {
                  folders.add(f);
                }
              } else {
                folders.add(f);
              }
            }
            break;
          default:
            if (f.isType(type)) {
              if (subscribed) {
                if (f.isSubscribed()) {
                  folders.add(f);
                }
              } else {
                folders.add(f);
              }
            }
        }
      }
    }
    //force sort
    Collections.sort(folders, LEXOGRAPHICAL);
    return folders;
  }//sublist

  /**
   * Tests if this list contains a folder with the
   * given path.
   *
   * @param path the path of the folder as <tt>String</tt>.
   *
   * @return true if this list contains a folder with the given path,
   *         false otherwise.
   */
  public boolean contains(String path) {
    for (Iterator iter = iterator(); iter.hasNext();) {
      if (path.equals(((JwmaFolderImpl) iter.next()).getPath())) {
        return true;
      }
    }
    return false;
  }//contains

  /**
   * Tests if this list contains a given folder.
   *
   * @param folder the folder as <tt>JwmaFolder</tt>.
   *
   * @return true if this list contains the given folder,
   *         false otherwise.
   */
  public boolean contains(JwmaFolder folder) {
    for (Iterator iter = iterator(); iter.hasNext();) {
      if (folder.equals(iter.next())) {
        return true;
      }
    }
    return false;
  }//contains

  /**
   * Creates an array of <tt>JwmaFolder</tt> instances from
   * the given <tt>List</tt>.
   * If the list is empty, then the returned array will be
   * empty, but not null.
   *
   * @param folders the <tt>List</tt> of folders.
   *
   * @return the newly created array.
   */
  public JwmaFolder[] createFolderArray(List folders) {
    //create array from it
    JwmaFolder[] list = new JwmaFolder[folders.size()];
    return (JwmaFolder[]) folders.toArray(list);
  }//createFolderArray

  /**
   * Removes a folder with the given path from this list.
   *
   * @param path the path of the folder to be removed as <tt>String</tt>.
   */
  public void removeFolderFromList(String path) {
    for (Iterator iter = m_Folders.iterator(); iter.hasNext();) {
      if (path.equals(
          ((JwmaFolderImpl) iter.next()).getPath())) {
        iter.remove();
        //done
        break;
      }
    }
  }//removeFolderFromList

  /**
   * Adds a given folder to this list.
   *
   * @param folder the folder to be added as <tt>JwmaFolder</tt>.
   */
  public void addFolderToList(JwmaFolderImpl folder) {
    m_Folders.add(folder);
    Collections.sort(m_Folders, LEXOGRAPHICAL);
  }//addFolderToList

  /**
   * Rebuilds this list of folders.
   */
  public void rebuild()
      throws MessagingException, JwmaException {
    Folder[] folders = m_Folder.list(m_Pattern);
    //build list
    m_Folders = new ArrayList(folders.length);
    buildFolderList(folders);
    Collections.sort(m_Folders, LEXOGRAPHICAL);
  }//rebuild

  /**
   * Builds this list of folders from the given array of folders.
   * If recursive, then it will build a flat list of the complete
   * folder tree.
   *
   * @param folders the array of <tt>javax.mail.Folder</tt> instances
   *        in the root folder.
   */
  private void buildFolderList(Folder[] folders)
      throws JwmaException, MessagingException {

    for (int i = 0; i < folders.length; i++) {
      //add a lightweight JwmaFolderImpl to the list
      m_Folders.add(
          JwmaFolderImpl.createLight(folders[i])
      );
      //recurse if necessary
      //if (m_Recursive) {
      //  buildFolderList(folders[i].list());
      //}
    }
  }//buildFolderList

  /**
   * Factory method that creates a flat list of all folders on the store.
   * The given folder should be the root folder, or the default folder
   * on the store.
   *
   * @param folder the <tt>javax.mail.Folder</tt> instance representing the
   *        root folder.
   *
   * @return the newly created <tt>JwmaFolderList</tt> instance.
   *
   * @throws JwmaException if it fails to build the folder list.
   */
  public static JwmaFolderList createStoreList(Folder folder)
      throws JwmaException {

    try {
      JwmaFolderList flist = new JwmaFolderList(folder, true);
      flist.rebuild();
      //DEBUG:flist.dumpList();
      return flist;
    } catch (MessagingException mex) {
      throw new JwmaException(mex.getMessage()).setException(mex);
    }
  }//createStoreList

  /**
   * Factory method that creates a list of all subfolders of the given
   * folder.
   * There is no recursion into subfolders.
   *
   * @param folder the <tt>javax.mail.Folder</tt> instance to be listed.
   *
   * @return the newly created <tt>JwmaFolderList</tt> instance.
   *
   * @throws JwmaException if it fails to build the folder list.
   */
  public static JwmaFolderList createSubfolderList(Folder folder)
      throws JwmaException {
    try {
      JwmaFolderList flist = new JwmaFolderList(folder, false);
      flist.rebuild();
      return flist;
    } catch (MessagingException mex) {
      throw new JwmaException(mex.getMessage()).setException(mex);
    }
  }//createSubfolderList


  /**
   * Defines a <tt>Comparator</tt> that sorts
   * the folder instances lexographical.
   */
  public static final Comparator LEXOGRAPHICAL =
      new Comparator() {

        public int compare(Object o1, Object o2) {
          JwmaFolder f1 = (JwmaFolder) o1;
          JwmaFolder f2 = (JwmaFolder) o2;
          return f1.getName().compareTo(
              f2.getName()
          );
        }//compare(Object,Object)
      };

}//class JwmaFolderList
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.