/*
* JBoss, Home of Professional Open Source
* Copyright 2011, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* 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.mobicents.ss7.management.transceiver;
import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Set;
import javolution.util.FastSet;
/**
* <p>
* A multiplex of {@link ShellSelectableChannel} objects.
* </p>
*
* <p>
* A selector may be created by invoking the {@link #open open} method of this class, which will use the system's default
* {@link ChannelProvider </code>selector provider<code>} to create a new selector. A selector remains open until it is closed
* via its {@link #close close} method.
* </p>
*
* <p>
* A selectable channel's registration with a selector is represented by a {@link ChannelSelectionKey} object. A selector
* maintains one set of selection keys:
*
* <ul>
* <li>
* <p>
* The <i>selected-key set</i> is the set of keys such that each key's channel was detected to be ready for at least one of the
* operations identified in the key's interest set during a selection operation. This set is returned by the
* {@link #selectNow() selectNow} method.
* </p>
* </li>
* </ul>
* </p>
*
* <p>
* Every time {@link #selectNow() selectNow} method is called the <i>selected-key set</i> is cleared before adding keys that are
* ready for operation
* </p>
*
*
* @author amit bhayani
*
*/
public class ChannelSelector {
protected Selector selector;
private FastSet<ChannelSelectionKey> selectedKey = new FastSet<ChannelSelectionKey>();
protected ChannelSelector(Selector selector) {
this.selector = selector;
}
/**
* <p>
* Opens a ChannelSelector
* </p>
* <p>
* The new selector is created by invoking the {@link ChannelProvider#openSelector openSelector} method of the system-wide
* default {@link ChannelProvider} object.
* </p>
*
* @return A new selector
* @throws IOException If an I/O error occurs
*/
public static ChannelSelector open() throws IOException {
return ChannelProvider.provider().openSelector();
}
/**
* * Selects a set of keys whose corresponding channels are ready for I/O operations.
*
* <p>
* This method performs a non-blocking selection operation. If no channels have become selectable since the previous
* selection operation then this method immediately returns empty selected-key set.
* </p>
*
* @return
* @throws IOException If an I/O error occurs
*/
public FastSet<ChannelSelectionKey> selectNow() throws IOException {
selectedKey.clear();
selector.selectNow();
Set<SelectionKey> selection = selector.selectedKeys();
for (SelectionKey key : selection) {
if (key.isAcceptable()) {
ChannelSelectionKey k = (ChannelSelectionKey) key.attachment();
selectedKey.add(k);
} else {
if (key.isReadable()) {
ChannelSelectionKey k = (ChannelSelectionKey) key.attachment();
((ShellChannel) k.channel()).doRead();
if (k.isReadable()) {
selectedKey.add(k);
}
}
if (key.isWritable()) {
ChannelSelectionKey k = (ChannelSelectionKey) key.attachment();
((ShellChannel) k.channel()).doWrite();
if (k.isWritable()) {
selectedKey.add(k);
}
}
}
}// for
selection.clear();
return selectedKey;
}
/**
* Closes this selector.
*
* @throws IOException If an I/O error occurs
*/
public void close() throws IOException {
selector.close();
}
}