com.duroty.task.IMAPServiceTask.java Source code

Java tutorial

Introduction

Here is the source code for com.duroty.task.IMAPServiceTask.java

Source

/*
* Copyright (C) 2006 Jordi Marqus Ferr
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; see the file DUROTY.txt.
*
* Author: Jordi Marqus Ferr
* c/Mallorca 295 principal B 08037 Barcelona Spain
* Phone: +34 625397324
*/

/**
 *
 */
package com.duroty.task;

import com.duroty.hibernate.MailPreferences;
import com.duroty.hibernate.Users;

import com.duroty.jmx.mbean.ApplicationConstants;
import com.duroty.jmx.mbean.Constants;

import com.duroty.lucene.mail.indexer.MailIndexerConstants;
import com.duroty.lucene.utils.FileUtilities;

import com.duroty.service.Mailet;
import com.duroty.service.Servible;
import com.duroty.service.analyzer.BayesianAnalysis;

import com.duroty.utils.GeneralOperations;
import com.duroty.utils.log.DLog;
import com.duroty.utils.mail.MailUtilities;

import com.sun.mail.imap.IMAPFolder;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import org.hibernate.criterion.Restrictions;

import org.jboss.varia.scheduler.Schedulable;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.mail.Flags;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Store;
import javax.mail.internet.MimeMessage;
import javax.mail.search.FlagTerm;
import javax.mail.search.SearchTerm;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
 * @author durot
 *
 */
public class IMAPServiceTask implements Schedulable, Servible, MailIndexerConstants {
    /**
    * DOCUMENT ME!
    */
    private static final List pool = new ArrayList(10);

    /**
     * DOCUMENT ME!
     */
    private Context ctx = null;

    /**
     * DOCUMENT ME!
     */
    private boolean init = false;

    /**
     * DOCUMENT ME!
     */
    private int poolSize = 10;

    /**
     * DOCUMENT ME!
     */
    private String durotyMailFactory;

    /**
     * DOCUMENT ME!
     */
    private String hibernateSessionFactory;

    /**
     * DOCUMENT ME!
     */
    private String imapInbox;

    /**
     * DOCUMENT ME!
     */
    private String imapSent;

    /**
     * DOCUMENT ME!
     */
    private String imapDraft;

    /**
     * @throws NamingException
     * @throws IOException
     *
     */
    public IMAPServiceTask(int poolSize) throws NamingException, IOException {
        super();
        this.poolSize = poolSize;

        Map options = ApplicationConstants.options;

        try {
            ctx = new InitialContext();

            HashMap mail = (HashMap) ctx.lookup((String) options.get(Constants.MAIL_CONFIG));

            this.durotyMailFactory = (String) mail.get(Constants.DUROTY_MAIL_FACTOTY);
            this.hibernateSessionFactory = (String) mail.get(Constants.HIBERNATE_SESSION_FACTORY);

            this.imapInbox = (String) mail.get(Constants.MAIL_SERVER_INBOX);
            this.imapSent = (String) mail.get(Constants.MAIL_SERVER_SENT);
            this.imapDraft = (String) mail.get(Constants.MAIL_SERVER_DRAFT);

            String tempDir = System.getProperty("java.io.tmpdir");

            if (!tempDir.endsWith(File.separator)) {
                tempDir = tempDir + File.separator;
            }

            FileUtilities.deleteMotLocks(new File(tempDir));
            FileUtilities.deleteLuceneLocks(new File(tempDir));
        } finally {
        }
    }

    /* (non-Javadoc)
     * @see org.jboss.varia.scheduler.Schedulable#perform(java.util.Date, long)
     */
    public void perform(Date arg0, long arg1) {
        if (isInit()) {
            DLog.log(DLog.DEBUG, this.getClass(), "IMAPServiceTask is running and wait.");

            return;
        }

        flush();
    }

    /**
     * DOCUMENT ME!
     */
    private void flush() {
        setInit(true);

        SessionFactory hfactory = null;
        Session hsession = null;
        javax.mail.Session msession = null;
        Store store = null;
        Folder rootFolder = null;
        Folder folder = null;

        try {
            hfactory = (SessionFactory) ctx.lookup(hibernateSessionFactory);
            hsession = hfactory.openSession();
            msession = (javax.mail.Session) ctx.lookup(durotyMailFactory);
            store = msession.getStore("imap");

            String imapHost = msession.getProperty("mail.imap.host");

            Query query = hsession.getNamedQuery("users-mail");
            query.setBoolean("active", true);
            query.setString("role", "mail");

            ScrollableResults scroll = query.scroll();

            while (scroll.next()) {
                Users user = (Users) scroll.get(0);

                String repositoryName = user.getUseUsername();

                store.connect(imapHost, repositoryName, user.getUsePassword());

                rootFolder = store.getDefaultFolder();

                if ((rootFolder.getType() & Folder.HOLDS_FOLDERS) != 0) {
                    folder = store.getFolder(this.imapInbox);

                    Message[] messages = getMimeMessages(folder, new Flags(Flags.Flag.SEEN), false);
                    MailUtilities.setFolderOpenAndReady(folder, Folder.READ_WRITE);

                    if ((messages != null) && (messages.length > 0)) {
                        for (int i = 0; i < messages.length; i++) {
                            if (pool.size() >= poolSize) {
                                DLog.log(DLog.WARN, this.getClass(), "PoolSize " + pool.size());

                                break;
                            }

                            MimeMessage mime = null;

                            if (messages[i] instanceof MimeMessage) {
                                mime = new MimeMessage((MimeMessage) messages[i]);

                                String messageName = null;

                                if (folder instanceof IMAPFolder) {
                                    messageName = String.valueOf(((IMAPFolder) folder).getUID(messages[i]));
                                } else {
                                    messageName = String.valueOf(messages[i].getMessageNumber());
                                }

                                messageName += this.imapInbox;

                                boolean existMessage = existMessageName(hfactory.openSession(), user, messageName);

                                if (existMessage) {
                                    messages[i].setFlag(Flags.Flag.SEEN, true);
                                } else {
                                    String key = messageName + "--" + repositoryName;

                                    if (!poolContains(key)) {
                                        addPool(key);

                                        if (!isSpam(user, mime)) {
                                            Mailet mailet = new Mailet(this, messageName, repositoryName, mime);

                                            Thread thread = new Thread(mailet, key);
                                            thread.start();

                                            //cal controlar si el borrem
                                            messages[i].setFlag(Flags.Flag.SEEN, true);
                                        } else {
                                            messages[i].setFlag(Flags.Flag.SEEN, true);
                                            messages[i].setFlag(Flags.Flag.DELETED, true);
                                        }
                                    }
                                }

                                Thread.sleep(100);
                            }
                        }
                    }

                    MailUtilities.setFolderClose(folder, true);
                    folder = null;
                    messages = null;

                    folder = store.getFolder(this.imapSent);
                    messages = getMimeMessages(folder, new Flags(Flags.Flag.SEEN), false);
                    MailUtilities.setFolderOpenAndReady(folder, Folder.READ_WRITE);

                    if (!folder.exists()) {
                        folder.create(Folder.HOLDS_MESSAGES);
                    }

                    if (!folder.isSubscribed()) {
                        folder.setSubscribed(true);
                    }

                    if ((messages != null) && (messages.length > 0)) {
                        for (int i = 0; i < messages.length; i++) {
                            if (pool.size() >= poolSize) {
                                DLog.log(DLog.WARN, this.getClass(), "PoolSize " + pool.size());

                                break;
                            }

                            MimeMessage mime = null;

                            if (messages[i] instanceof MimeMessage) {
                                mime = new MimeMessage((MimeMessage) messages[i]);

                                mime.addHeader("X-DBox", "SENT");

                                String messageName = null;

                                if (folder instanceof IMAPFolder) {
                                    messageName = String.valueOf(((IMAPFolder) folder).getUID(messages[i]));
                                } else {
                                    messageName = String.valueOf(messages[i].getMessageNumber());
                                }

                                messageName += this.imapSent;

                                boolean existMessage = existMessageName(hfactory.openSession(), user, messageName);

                                if (existMessage) {
                                    messages[i].setFlag(Flags.Flag.SEEN, true);
                                } else {
                                    String key = messageName + "--" + repositoryName;

                                    if (!poolContains(key)) {
                                        addPool(key);

                                        if (!isSpam(user, mime)) {
                                            Mailet mailet = new Mailet(this, messageName, repositoryName, mime);

                                            Thread thread = new Thread(mailet, key);
                                            thread.start();

                                            //cal controlar si el borrem
                                            messages[i].setFlag(Flags.Flag.SEEN, true);
                                        } else {
                                            messages[i].setFlag(Flags.Flag.SEEN, true);
                                            messages[i].setFlag(Flags.Flag.DELETED, true);
                                        }
                                    }
                                }

                                Thread.sleep(100);
                            }
                        }
                    }

                    MailUtilities.setFolderClose(folder, true);
                    folder = null;
                    messages = null;

                    folder = store.getFolder(this.imapDraft);
                    messages = getMimeMessages(folder, new Flags(Flags.Flag.SEEN), false);
                    MailUtilities.setFolderOpenAndReady(folder, Folder.READ_WRITE);

                    if (!folder.exists()) {
                        folder.create(Folder.HOLDS_MESSAGES);
                    }

                    if (!folder.isSubscribed()) {
                        folder.setSubscribed(true);
                    }

                    if ((messages != null) && (messages.length > 0)) {
                        for (int i = 0; i < messages.length; i++) {
                            if (pool.size() >= poolSize) {
                                DLog.log(DLog.WARN, this.getClass(), "PoolSize " + pool.size());

                                break;
                            }

                            MimeMessage mime = null;

                            if (messages[i] instanceof MimeMessage) {
                                mime = new MimeMessage((MimeMessage) messages[i]);

                                mime.addHeader("X-DBox", "DRAFT");

                                String messageName = null;

                                if (folder instanceof IMAPFolder) {
                                    messageName = String.valueOf(((IMAPFolder) folder).getUID(messages[i]));
                                } else {
                                    messageName = String.valueOf(messages[i].getMessageNumber());
                                }

                                messageName += this.imapDraft;

                                boolean existMessage = existMessageName(hfactory.openSession(), user, messageName);

                                if (existMessage) {
                                    messages[i].setFlag(Flags.Flag.SEEN, true);
                                } else {
                                    String key = messageName + "--" + repositoryName;

                                    if (!poolContains(key)) {
                                        addPool(key);

                                        if (!isSpam(user, mime)) {
                                            Mailet mailet = new Mailet(this, messageName, repositoryName, mime);

                                            Thread thread = new Thread(mailet, key);
                                            thread.start();

                                            //cal controlar si el borrem
                                            messages[i].setFlag(Flags.Flag.SEEN, true);
                                        } else {
                                            messages[i].setFlag(Flags.Flag.SEEN, true);
                                            messages[i].setFlag(Flags.Flag.DELETED, true);
                                        }
                                    }
                                }

                                Thread.sleep(100);
                            }
                        }
                    }

                    MailUtilities.setFolderClose(folder, true);
                    folder = null;
                }

                MailUtilities.setFolderClose(rootFolder, true);
                MailUtilities.setStoreClose(store);
            }
        } catch (Exception e) {
            System.gc();
            pool.clear();

            StringWriter writer = new StringWriter();
            e.printStackTrace(new PrintWriter(writer));
            DLog.log(DLog.ERROR, this.getClass(), writer.toString());
        } catch (OutOfMemoryError e) {
            System.gc();
            pool.clear();

            StringWriter writer = new StringWriter();
            e.printStackTrace(new PrintWriter(writer));
            DLog.log(DLog.ERROR, this.getClass(), writer.toString());
        } catch (Throwable e) {
            System.gc();
            pool.clear();

            StringWriter writer = new StringWriter();
            e.printStackTrace(new PrintWriter(writer));
            DLog.log(DLog.ERROR, this.getClass(), writer.toString());
        } finally {
            System.gc();

            GeneralOperations.closeMailFolder(folder, false);
            GeneralOperations.closeMailFolder(rootFolder, false);
            GeneralOperations.closeMailStore(store);
            GeneralOperations.closeHibernateSession(hsession);

            setInit(false);
        }
    }

    /**
     * DOCUMENT ME!
     *
     * @param key DOCUMENT ME!
     */
    public void addPool(String key) {
        pool.add(key);
    }

    /**
     * DOCUMENT ME!
     *
     * @param key DOCUMENT ME!
     */
    public void removePool(String key) {
        pool.remove(key);
    }

    /**
     * DOCUMENT ME!
     *
     * @param key DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public boolean poolContains(String key) {
        return pool.contains(key);
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public synchronized boolean isInit() {
        synchronized (IMAPServiceTask.class) {
            return this.init;
        }
    }

    /**
     * DOCUMENT ME!
     *
     * @param init DOCUMENT ME!
     */
    public synchronized void setInit(boolean init) {
        synchronized (IMAPServiceTask.class) {
            this.init = init;
        }
    }

    /**
     * DOCUMENT ME!
     *
     * @param user DOCUMENT ME!
     * @param mime DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    private boolean isSpam(Users user, MimeMessage mime) {
        boolean control = false;
        double probability = 0.0;

        try {
            BayesianAnalysis bayesianAnalysis = new BayesianAnalysis();
            bayesianAnalysis.init(null);
            bayesianAnalysis.service(user.getUseUsername(), null, mime);

            String[] aux = mime.getHeader(BayesianAnalysis.messageIsSpamProbability);

            if ((aux != null) && (aux.length > 0)) {
                for (int i = 0; i < aux.length; i++) {
                    probability = Double.parseDouble(aux[i].trim());

                    break;
                }
            }

            Iterator it = user.getMailPreferenceses().iterator();

            MailPreferences mailPreferences = (MailPreferences) it.next();

            if (mailPreferences.getMaprSpamTolerance() == -1) {
                return false;
            }

            double tolerance = ((double) mailPreferences.getMaprSpamTolerance()) / 100;

            if ((probability > 0.0) && (tolerance < 1.0) && (probability >= tolerance)) {
                control = true;
            }

            return control;
        } catch (NamingException e) {
            return false;
        } catch (Exception ex) {
            return false;
        } catch (java.lang.OutOfMemoryError ex) {
            System.gc();

            return false;
        } catch (Throwable ex) {
            return false;
        }
    }

    /**
     * DOCUMENT ME!
     *
     * @param folder DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    private Message[] getMimeMessages(Folder folder, Flags flags, boolean aux) {
        try {
            MailUtilities.setFolderOpenAndReady(folder, Folder.READ_ONLY);

            SearchTerm search = new FlagTerm(flags, aux);

            return folder.search(search);
        } catch (Exception ex) {
            return null;
        } finally {
            GeneralOperations.closeMailFolder(folder, false);
        }
    }

    /**
     * DOCUMENT ME!
     *
     * @param hsession DOCUMENT ME!
     * @param user DOCUMENT ME!
     * @param messageName DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    private boolean existMessageName(Session hsession, Users user, String messageName) {
        try {
            Criteria crit = hsession.createCriteria(com.duroty.hibernate.Message.class);
            crit.add(Restrictions.eq("users", user));
            crit.add(Restrictions.eq("mesName", messageName));

            com.duroty.hibernate.Message message = (com.duroty.hibernate.Message) crit.uniqueResult();

            if (message != null) {
                return true;
            } else {
                return false;
            }
        } catch (Exception ex) {
            return false;
        } finally {
            GeneralOperations.closeHibernateSession(hsession);
        }
    }
}