org.xwiki.contrib.mail.internal.AbstractMailStore.java Source code

Java tutorial

Introduction

Here is the source code for org.xwiki.contrib.mail.internal.AbstractMailStore.java

Source

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.xwiki.contrib.mail.internal;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;

import javax.mail.Folder;
import javax.mail.FolderNotFoundException;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.URLName;
import javax.mail.internet.MimeMessage;
import javax.mail.search.MessageIDTerm;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.xwiki.contrib.mail.IStoreManager;
import org.xwiki.contrib.mail.SourceConnectionErrors;
import org.xwiki.contrib.mail.internal.source.StoreSource;

/**
 * @version $Id$
 */
public abstract class AbstractMailStore extends AbstractMailReader implements IStoreManager {

    public abstract Logger getLogger();

    public void setMailSource(StoreSource mailSource) {
        super.setMailSource(mailSource);
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.xwiki.contrib.mail.IMailReader#getMailSource()
     */
    @Override
    public StoreSource getMailSource() {
        return (StoreSource) super.getMailSource();
    }

    public abstract Properties getStoreProperties();

    /**
     * @param folder
     * @param message
     * @throws MessagingException
     */
    public void write(String folder, Message message) throws MessagingException {
        // getLogger().info("Delivering " + message + " to " + this.location + " / " + folder);

        final Store store = getJavamailStore(true);
        store.connect();
        final Folder mailFolder = store.getDefaultFolder().getFolder(folder);
        if (!mailFolder.exists()) {
            mailFolder.create(Folder.HOLDS_MESSAGES);
        }
        mailFolder.open(Folder.READ_WRITE);
        // If message is already archived, do nothing
        final Message existingMessage = read(folder, message.getHeader("Message-ID")[0]);
        if (existingMessage == null) {
            // The Store Provider may add some headers to the message to store, but IMAPMessage are read-only
            // So we clone the message before storing it
            final MimeMessage cloned = cloneEmail(message);
            mailFolder.appendMessages(new Message[] { cloned });
        }

        mailFolder.close(true);
        store.close();
    }

    /**
     * {@inheritDoc}
     * 
     * @throws MessagingException
     * @see org.xwiki.contrib.mail.IMailReader#readFromStore(java.lang.String)
     */
    public Message read(String folder, String messageid) throws MessagingException {
        Store store = getJavamailStore();
        store.connect();

        Folder mailFolder = store.getDefaultFolder().getFolder(folder);
        mailFolder.open(Folder.READ_ONLY);
        Message[] messages = mailFolder.search(new MessageIDTerm(messageid));
        mailFolder.close(false);
        store.close();
        if (messages.length > 0) {
            return messages[0];
        }
        return null;
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.xwiki.contrib.mail.IMailReader#readFromStore(java.lang.String)
     */
    @Override
    public List<Message> read(String folder, boolean onlyUnred, int max) throws MessagingException {
        Store store = getJavamailStore();
        store.connect();
        Folder mailFolder = store.getDefaultFolder();
        if (StringUtils.isNotEmpty(folder)) {
            mailFolder = mailFolder.getFolder(folder);
        }
        mailFolder.open(Folder.READ_WRITE);
        Message[] msgsArray = mailFolder.getMessages();
        if (max > 0 && msgsArray.length > max) {
            msgsArray = (Message[]) ArrayUtils.subarray(msgsArray, 0, max);
        }
        List<Message> messages = new ArrayList<Message>(Arrays.asList(msgsArray));
        mailFolder.close(false);
        store.close();
        return messages;
    }

    /**
     * Creates appropriate javamail Store object.
     * 
     * @param debug
     * @return
     * @throws NoSuchProviderException
     */
    protected Store getJavamailStore(boolean debug) throws NoSuchProviderException {
        Properties props = getStoreProperties();
        Session session = Session.getInstance(props);
        if (debug) {
            session.setDebug(true);
        }

        String url = getProvider() + ":" + getMailSource().getLocation();

        return session.getStore(new URLName(url));
    }

    /**
     * Creates appropriate javamail Store object.
     * 
     * @return
     * @throws NoSuchProviderException
     */
    protected Store getJavamailStore() throws NoSuchProviderException {
        return getJavamailStore(false);
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.xwiki.contrib.mail.IMailReader#read(java.lang.String, boolean)
     */
    @Override
    public List<Message> read(String folder, boolean onlyUnread) throws MessagingException {
        return read(folder, onlyUnread, -1);
    }

    /**
     * {@inheritDoc}
     * 
     * @see org.xwiki.contrib.mail.IMailReader#check(java.lang.String, boolean)
     */
    @Override
    public int check(String folder, boolean onlyUnread) {
        List<Message> messages = null;

        File storePath = new File(getMailSource().getLocation());
        if (!storePath.exists() || !storePath.canRead()) {
            return SourceConnectionErrors.CONNECTION_ERROR.getCode();
        }

        try {
            messages = read(folder, onlyUnread);
        } catch (FolderNotFoundException e) {
            return SourceConnectionErrors.FOLDER_NOT_FOUND.getCode();
        } catch (MessagingException e) {
            // TODO Very basic implementation of check() ...
            e.printStackTrace();
            return SourceConnectionErrors.UNEXPECTED_EXCEPTION.getCode();
        }
        return messages == null ? -1 : messages.size();
    }

    @Override
    public ArrayList<FolderItem> getFolderTree() throws MessagingException {
        getLogger().debug("getFolderTree");

        assert (getMailSource() != null);

        ArrayList<FolderItem> folderItems = new ArrayList<FolderItem>();

        Store store = getJavamailStore();
        store.connect();
        Folder defaultFolder = store.getDefaultFolder();
        FolderItem item = new FolderItem();
        item.setIndex(0);
        item.setLevel(0);
        item.setName(defaultFolder.getName());
        item.setFullName(defaultFolder.getFullName());
        if ((defaultFolder.getType() & javax.mail.Folder.HOLDS_MESSAGES) != 0) {
            item.setMessageCount(defaultFolder.getMessageCount());
            item.setUnreadMessageCount(defaultFolder.getUnreadMessageCount());
            item.setNewMessageCount(defaultFolder.getNewMessageCount());
        }
        Folder[] folders = defaultFolder.list("*");
        if (ArrayUtils.isEmpty(folders)) {
            folders = defaultFolder.list();
        }

        getLogger().debug("Found folders {}", ArrayUtils.toString(folders));
        int index = 1;
        int level = 1;
        // TODO not really managing folders here, just listing them
        for (Folder folder : folders) {

            item = new FolderItem();
            item.setIndex(index);
            item.setLevel(level);
            item.setName(folder.getName());
            item.setFullName(folder.getFullName());
            if ((folder.getType() & javax.mail.Folder.HOLDS_MESSAGES) != 0) {
                item.setMessageCount(folder.getMessageCount());
                item.setUnreadMessageCount(folder.getUnreadMessageCount());
                item.setNewMessageCount(folder.getNewMessageCount());
                folderItems.add(item);
            }
        }

        store.close();

        return folderItems;

    }

    /**
     * {@inheritDoc}
     * 
     * @throws MessagingException
     * @see org.xwiki.contrib.mail.IMailReader#cloneEmail(javax.mail.Message)
     */
    @Override
    public MimeMessage cloneEmail(Message mail) {
        MimeMessage copy = (MimeMessage) mail;

        try {
            copy = new MimeMessage((MimeMessage) mail);
        } catch (MessagingException e) {
            // failed to copy
        }

        return copy;
    }

}