* @param selectionKey the selected key.
* @throws IOException if cannot read from the channel.
*/
private void handleRead(final SelectionKey selectionKey) throws IOException {
// Get the client channel that has data to read
SocketChannel client = (SocketChannel) selectionKey.channel();
// current bytecode read
ChannelAttachment channAttachment = (ChannelAttachment) selectionKey.attachment();
ByteBuffer channBuffer = channAttachment.getByteBuffer();
// Read again
int bytesread = client.read(channBuffer);
if (bytesread == -1) {
// close (as the client has been disconnected)
selectionKey.cancel();
client.close();
}
// Client send data, analyze data
// Got header ?
if (channBuffer.position() >= Message.HEADER_SIZE) {
// Yes, got header
// Check if it is a protocol that we manage
byte version = channBuffer.get(0);
if (version != PROTOCOL_VERSION) {
selectionKey.cancel();
client.close();
throw new IllegalStateException("Invalid protocol version : waiting '" + PROTOCOL_VERSION + "', got '" + version
+ "'.");
}
// Get operation asked by client
byte opCode = channBuffer.get(1);
// Length
int length = channBuffer.getInt(2);
if (length < 0) {
selectionKey.cancel();
client.close();
throw new IllegalStateException("Invalid length for client '" + length + "'.");
}
if (length > MAX_LENGTH_INCOMING_MSG) {
selectionKey.cancel();
client.close();
throw new IllegalStateException("Length too big, max length = '" + MAX_LENGTH_INCOMING_MSG + "', current = '"
+ length + "'.");
}
// Correct header and correct length ?
if (channBuffer.position() >= Message.HEADER_SIZE + length) {
// set the limit (specified in the length), else we have a
// default buffer limit
channBuffer.limit(Message.HEADER_SIZE + length);
// duplicate this buffer
ByteBuffer dataBuffer = channBuffer.duplicate();
// skip header (already analyzed)
dataBuffer.position(Message.HEADER_SIZE);
// Switch on operations :
try {
switch (opCode) {
case ProtocolConstants.CLASS_REQUEST:
handleReadClassRequest(selectionKey, dataBuffer);
break;
case ProtocolConstants.RESOURCE_REQUEST:
handleReadResourceRequest(selectionKey, dataBuffer);
break;
case ProtocolConstants.PROVIDER_URL_REQUEST:
handleReadProviderURLRequest(selectionKey, dataBuffer);
break;
default:
// nothing to do
}
} catch (Exception e) {
// clean
selectionKey.cancel();
client.close();
throw new IllegalStateException("Cannot handle request with opCode '" + opCode + "'.", e);
}
}
}