package org.i2peer.reactor.impl;
import java.io.IOException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.HashSet;
import java.util.Set;
import org.i2peer.reactor.InitiationDispatcher;
import org.i2peer.reactor.EventHandler;
public class DefaultDispatcher implements InitiationDispatcher, Runnable {
private Selector selector;
private boolean isCancelled;
public DefaultDispatcher() throws IOException {
selector = Selector.open();
}
public void handleEvents() throws IOException {
new Thread(this).start();
}
@Override
public void run() {
isCancelled = false;
while (!isCancelled) {
try {
dispatchRequest();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void cancel() {
isCancelled = true;
selector.wakeup();
}
@Override
public void registerHandler(EventHandler handler, int eventType)
throws ClosedChannelException {
if(handler == null) {
throw new IllegalArgumentException("Handler is null");
}
handler.getChannel().register(selector, eventType, handler);
}
@Override
public void deregisterHandler(EventHandler handler, int eventType) {
Set<SelectionKey> keys = new HashSet<SelectionKey>(
selector.keys());
for(SelectionKey key : keys) {
EventHandler mh = (EventHandler) key.attachment();
if(mh.equals(handler)) {
key.cancel();
}
}
}
private void dispatchRequest() throws IOException {
selector.select();
Set<SelectionKey> keys = new HashSet<SelectionKey>(
selector.selectedKeys());
for (SelectionKey key : keys) {
if (key.isValid() && key.attachment() != null) {
EventHandler mh = (EventHandler) key.attachment();
if(key.isWritable()) {
mh.handleEvent(SelectionKey.OP_WRITE);
}
if(key.isReadable()) {
mh.handleEvent(SelectionKey.OP_READ);
}
if(key.isAcceptable()) {
mh.handleEvent(SelectionKey.OP_CONNECT);
}
}
}
selector.selectedKeys().clear();
}
}