edu.stanford.muse.email.EmailStore.java Source code

Java tutorial

Introduction

Here is the source code for edu.stanford.muse.email.EmailStore.java

Source

/*
 Copyright (C) 2012 The Stanford MobiSocial Laboratory
    
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
    
   http://www.apache.org/licenses/LICENSE-2.0
    
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
package edu.stanford.muse.email;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import edu.stanford.muse.util.Pair;
import edu.stanford.muse.util.Util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.mail.Folder;
import javax.mail.MessagingException;
import javax.mail.Store;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/** a store is an account, a source of email. */
public abstract class EmailStore implements Serializable {
    private static Log log = LogFactory.getLog(EmailStore.class);
    private final static long serialVersionUID = 1L;

    String displayName;
    public String emailAddress;
    boolean DEBUG = false;
    private String cacheDir;

    List<FolderInfo> folderInfos; // folder lists and counts, could be accessed while it is still being computed
    private List<String> defaultFolderNames; // specific default folder name for analysis, e.g. [Gmail]/Sent Mail for gmail

    // the following used for reporting intermediate status
    boolean doneReadingFolderCounts; // will be set when all folders have been identified and counts read
    String folderBeingScanned; // the folder currently being scanned
    String folderBeingScannedShortName; // the folder currently being scanned

    public boolean isFolderCountReadingComplete() {
        return doneReadingFolderCounts;
    }

    public String folderBeingScanned() {
        return folderBeingScanned;
    }

    public synchronized void addDefaultFolderName(String folderName) {
        if (defaultFolderNames == null)
            defaultFolderNames = new ArrayList<String>();
        defaultFolderNames.add(folderName);
    }

    /** obliterate any passwords that may be stored */
    public void wipePasswords() {
        /* default: do nothing */ }

    public List<String> getDefaultFolderNames() {
        return defaultFolderNames;
    }

    // returns a string for this store that uniquely identifies the account (e.g. user@server, or directory etc.)
    abstract public String getAccountID();

    public String getFolderInfosAsJson() {
        Gson gson = new Gson();
        JsonObject result = new JsonObject();
        // hoping for TSO :-)
        result.add("doneReadingFolderCounts", new JsonPrimitive(doneReadingFolderCounts));

        List<FolderInfo> tmp = new ArrayList<FolderInfo>();
        if (folderInfos != null)
            tmp.addAll(folderInfos);
        if (folderBeingScanned != null && !doneReadingFolderCounts) {
            String s = (folderBeingScannedShortName == null) ? folderBeingScanned : folderBeingScannedShortName;
            tmp.add(new FolderInfo(getAccountID(), folderBeingScanned, s, -1));
        }

        log.info("Folder infos currently available: " + tmp.size());

        // check long names, sometimes it is null in case of errors
        for (FolderInfo fi : tmp)
            if (Util.nullOrEmpty(fi.longName))
                log.warn("Null or empty long name for folder " + fi);

        JsonElement je = gson.toJsonTree(tmp);
        result.add("folderInfos", je);
        return result.toString();
    }

    // constructor for de-serialization
    EmailStore() {
    }

    EmailStore(String name, String emailAddress) {
        this.displayName = name;
        // display name is often used in html pages for attributes and javascript, so its probably very bad to have " or '
        displayName = displayName.replaceAll("\\\\", "/");
        displayName = displayName.replaceAll("'", "");

        this.emailAddress = emailAddress;
    }

    public void setCacheDir(String dir) {
        this.cacheDir = dir;
    }

    abstract public void computeFoldersAndCounts(String cacheDir) throws MessagingException;

    public String getDisplayName() {
        return displayName;
    }

    /** returns folder and # of messages in it. -1 if folder cannot be opened. */
    protected abstract Pair<Folder, Integer> openFolder(Store store, String fname) throws MessagingException;

    protected abstract Folder openFolderWithoutCount(Store store, String fname) throws MessagingException;

    /** establishes a new connection using this email store */
    abstract public Store connect() throws MessagingException;

    /* controls printing of imap traffic */
    public void setDebug(boolean b) {
        DEBUG = b;
    }

    /** returns an OPEN folder in R/O mode */
    public Folder get_folder(Store store, String folder_name) throws MessagingException {
        return openFolderWithoutCount(store, folder_name);
    }

    /** returns # of messages in the given folder */
    public int getNMessages(String fname) throws MessagingException {
        // first check if we've already cached it
        if (this.folderInfos != null)
            for (FolderInfo fi : this.folderInfos)
                if (fi.longName.equals(fname))
                    return fi.messageCount;

        Store store = connect();
        Pair<Folder, Integer> pair = openFolder(store, fname);
        Folder f = pair.getFirst();
        if (f == null)
            return -1;
        int count = pair.getSecond();
        if (count != -1)
            f.close(false);
        store.close();
        return count;
    }

    /** returns # of messages in each of the given folders */
    public int[] getNMessages(String[] fnames) throws MessagingException {
        Store store = connect();
        int x[] = new int[fnames.length];
        for (int i = 0; i < x.length; i++) {
            Pair<Folder, Integer> pair = openFolder(store, fnames[i]);
            Folder f = pair.getFirst();
            if (f == null) {
                x[i] = -1;
                continue;
            }
            int count = pair.getSecond();
            if (count != -1)
                f.close(false);
            x[i] = count;
        }
        try {
            store.close();
        } catch (Exception e) {
            log.warn("Exception in closing folder " + this + ":" + e);
        }
        return x;
    }
}