/* * The contents of this file are subject to the terms * of the Common Development and Distribution License * (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/CDDLv1.0.html or * glassfish/bootstrap/legal/CDDLv1.0.txt. * See the License for the specific language governing * permissions and limitations under the License. * * When distributing Covered Code, include this CDDL * Header Notice in each file and include the License file * at glassfish/bootstrap/legal/CDDLv1.0.txt. * If applicable, add the following below the CDDL Header, * with the fields enclosed by brackets [] replaced by * you own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * Copyright 2006-2008 Sun Microsystems, Inc. All rights reserved. */ package com.sun.grizzly; import com.sun.grizzly.util.Copyable; import com.sun.grizzly.util.SelectionKeyActionAttachment; import java.io.IOException; import java.net.Socket; import java.nio.channels.ClosedChannelException; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.logging.Logger; /** * * @author Charlie Hunt */ public class BaseSelectionKeyHandler implements SelectionKeyHandler { protected Logger logger = Controller.logger(); /** * Associated SelectorHandler */ protected SelectorHandler selectorHandler; public BaseSelectionKeyHandler() { } public BaseSelectionKeyHandler(SelectorHandler selectorHandler) { this.selectorHandler = selectorHandler; } /** * {@inheritDoc} */ public SelectorHandler getSelectorHandler() { return selectorHandler; } /** * {@inheritDoc} */ public void setSelectorHandler(SelectorHandler selectorHandler) { this.selectorHandler = selectorHandler; } /** * {@inheritDoc} */ public void process(SelectionKey key) { Object attachment = key.attachment(); // NOTE: If attachment == null, instanceof will evaluate to false. // If attachment == null does not generate NullPointerException if (attachment instanceof SelectionKeyActionAttachment) { ((SelectionKeyActionAttachment) attachment).process(key); } } /** * {@inheritDoc} */ public void postProcess(SelectionKey key) { // Currently nothing to do here. } /** * @deprecated */ public void register(SelectionKey key, long currentTime) { throw new UnsupportedOperationException(getClass().getName() + " use of this API not allowed."); } /** * {@inheritDoc} */ public void register(SelectionKey key, int selectionKeyOps) { doRegisterKey(key, selectionKeyOps); } /** * Registers SelectionKey to handle certain operations */ protected void doRegisterKey(SelectionKey key, int selectionKeyOps) { if (!key.isValid()) { return; } key.interestOps(key.interestOps() | selectionKeyOps); } /** * {@inheritDoc} */ public void register(SelectableChannel channel, int selectionKeyOps) throws ClosedChannelException { if (!channel.isOpen()) { return; } Selector selector = selectorHandler.getSelector(); SelectionKey key = channel.keyFor(selector); if (key == null) { channel.register(selector, selectionKeyOps); } else { doRegisterKey(key, selectionKeyOps); } } /** * {@inheritDoc} */ public void register(Iterator keyIterator, int selectionKeyOps) { SelectionKey key; while (keyIterator.hasNext()) { key = keyIterator.next(); keyIterator.remove(); doRegisterKey(key, selectionKeyOps); } } /** * @deprecated */ public void expire(SelectionKey key, long currentTime) { // Do nothing. } /** * {@inheritDoc} */ public void expire(Iterator keyIterator) { // Do nothing. } /** * Cancel a SelectionKey and close its associated Channel. * @param key SelectionKey to cancel */ public void cancel(SelectionKey key) { if (!keyIsValid(key)) { return; } closeChannel(key); clearKeyAttachment(key); cancelKey(key); } /** * {@inheritDoc} */ public void close(SelectionKey key) { cancel(key); } /** * {@inheritDoc} */ public void copyTo(Copyable copy) { BaseSelectionKeyHandler copyHandler = (BaseSelectionKeyHandler) copy; copyHandler.selectorHandler = selectorHandler; } public Logger getLogger() { return logger; } public void setLogger(Logger logger) { this.logger = logger; } protected void cancelKey(SelectionKey key) { key.cancel(); key = null; } protected boolean keyIsValid(SelectionKey key) { if (key != null && key.isValid()) { return true; } else { return false; } } protected void closeChannel(SelectionKey key) { if (selectorHandler != null) { selectorHandler.closeChannel(key.channel()); } else { closeChannel(key.channel()); } } protected Object clearKeyAttachment(SelectionKey key) { return key.attach(null); } @SuppressWarnings("empty-statement") protected void closeChannel(SelectableChannel channel) { if (channel instanceof SocketChannel) { Socket socket = ((SocketChannel) channel).socket(); try{ if (!socket.isInputShutdown()) socket.shutdownInput(); } catch (IOException ex){ ; } try{ if (!socket.isOutputShutdown()) socket.shutdownOutput(); } catch (IOException ex){ ; } try{ socket.close(); } catch (IOException ex){ ; } } try{ channel.close(); } catch (IOException ex){ ; // LOG ME } } }