All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.mail.imap.IdleManager.1 Maven / Gradle / Ivy

There is a newer version: 1.6.7
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.mail.imap;

import java.io.IOException;
import java.nio.*;
import java.nio.channels.*;
import java.util.*;
import java.util.logging.*;
import java.util.concurrent.ConcurrentLinkedQueue;

import javax.mail.*;

import com.sun.mail.util.MailLogger;

/*
can only do select on SocketChannels, so need a SocketFactory that returns
Sockets implemented on top of SocketChannels.  ARGH!!!

user needs to call watch(Folder) after doing anything with the folder
*/
// XXX - add logging
public class IdleManager implements Runnable {
    private Selector selector;
    private MailLogger logger;
    private volatile boolean die = false;
    private Queue toWatch = new ConcurrentLinkedQueue();

    public IdleManager(Session session) throws IOException {
	logger = new MailLogger(this.getClass(), "DEBUG IMAP", session);
	selector = Selector.open();
    }

    public synchronized void watch(Folder f)
				throws IOException, MessagingException {
	if (!(f instanceof IMAPFolder))
	    throw new MessagingException("Can only watch IMAP folders");
	IMAPFolder folder = (IMAPFolder)f;
	SocketChannel sc = folder.getChannel();
	if (sc == null)
	    throw new MessagingException("Folder is not using SocketChannels");
	logger.log(Level.FINEST, "IdleManager watching {0}", folder);
logger.finest("ADD");
	toWatch.add(folder);
logger.finest("WAKEUP");
	selector.wakeup();
logger.finest("RETURN");
    }

    //@Override
    public void run() {
	die = false;
	try {
	    for (;;) {
		try {
		    for (;;) {
			IMAPFolder folder = toWatch.remove();
			logger.log(Level.FINEST,
				"IdleManager adding {0} to selector", folder);
			SocketChannel sc = folder.getChannel();
			if (sc == null)
			    continue;	// XXX - should never happen
			try {
			    folder.startIdle();
			    sc.configureBlocking(false);
			    sc.register(selector, SelectionKey.OP_READ, folder);
			} catch (MessagingException ex) {
			    // something went wrong, don't watch this folder
			    logger.log(Level.FINE,
				"IdleManager got exception for folder: " +
				folder, ex);
			}
		    }
		} catch (NoSuchElementException ex) {
		    // no more elements in the queue
		}
		logger.finest("IdleManager waiting...");
		int ns = selector.select();
		if (logger.isLoggable(Level.FINEST))
		    logger.log(Level.FINEST,
			"IdleManager selected {0} channels", ns);
		if (die) {
		    logger.fine("IdleManager exiting");
		    return;
		}
		Set selectedKeys = selector.selectedKeys();
		for (SelectionKey sk : selectedKeys) {
		    selectedKeys.remove(sk);
		    IMAPFolder folder = (IMAPFolder)sk.attachment();
		    logger.log(Level.FINE,
			"IdleManager selected folder: {0}", folder);
		    SelectableChannel sc = sk.channel();
		    sc.configureBlocking(true);
		    try {
			if (!folder.handleIdle(false)) {
			    logger.log(Level.FINE,
				"IdleManager done watching folder {0}", folder);
			    // done watching this folder,
			    // remove it from the selector
			    sk.cancel();
			}
		    } catch (MessagingException ex) {
			// something went wrong, stop watching this folder
			logger.log(Level.FINE,
			    "IdleManager got exception for folder: " + folder,
			    ex);
			sk.cancel();
		    }
		    sc.configureBlocking(false);
		}
	    }
	} catch (IOException ex) {
	    logger.log(Level.FINE, "IdleManager got exception", ex);
	}
    }

    public synchronized void stop() {
	die = true;
	logger.finest("IdleManager stopping");
	selector.wakeup();
	// XXX - close selector and clean up everything?
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy