/** * Examines the channel buffer and attempts to match the protocol of the request and invoke the * matching {@link ProtocolInitiator}. * * @param ctx The channel handler context * @param channel The channel * @param bufferx The message buffer * @param e The channel event * @return The channel buffer to send upstream, or null if we need more bytes */ protected ChannelBuffer protocolSwitch( ChannelHandlerContext ctx, Channel channel, ChannelBuffer bufferx, ChannelEvent e) { ChannelBuffer cb = preSwitchedBuffer.get(channel); if (cb != null) { cb.writeBytes(bufferx); cb.resetReaderIndex(); } else { cb = bufferx; } // this guy will be set with a matching initiator ProtocolInitiator selectedInitiator = null; // this guy will be set to false if at least 1 initiator had insufficient bytes to match boolean sufficientBytes = true; // ths guy has the total bytes available in the buffer final int bytesAvailable = cb.readableBytes(); for (ProtocolInitiator pi : initiators.values()) { if (pi.requiredBytes() > bytesAvailable) { sufficientBytes = false; } else { if (pi.match(cb)) { selectedInitiator = pi; break; } } } if (selectedInitiator == null) { // we did not get a match if (!sufficientBytes) { // ok, we did not have enough bytes DynamicChannelBuffer dcb = preSwitchedBuffer.get(channel); if (dcb == null) { dcb = new DynamicChannelBuffer(cb.order(), 1024, chanelBufferFactory); preSwitchedBuffer.set(channel, dcb); } dcb.writeBytes(cb); dcb.resetReaderIndex(); return null; } // darn, we have enough bytes for any of the inits, // but none matched throw new RuntimeException("Failed to match any protocol initiator"); } preSwitchedBuffer.remove(channel); // we matched on an initiator, so have it modify the pipeline selectedInitiator.modifyPipeline(ctx, channel, cb); return cb; // if we get here, it means we did not find a protocol match // so pass to the default protocol initiator. }
/** * Registers a new protocol initiator * * @param initiator the protocol initiator to register */ public void registerProtocolInitiator(ProtocolInitiator initiator) { if (initiator == null) throw new IllegalArgumentException("The passed initiator was null"); String key = initiator.getProtocol(); if (key == null || key.trim().isEmpty()) throw new RuntimeException( "The passed initiator had a null or empty protocol [" + initiator + "]"); key = key.trim().toLowerCase(); if (!initiators.containsKey(key)) { synchronized (initiators) { if (!initiators.containsKey(key)) { initiators.put(key, initiator); return; } } } throw new RuntimeException( "An initiator for protocol [" + key + "] has already been registered"); }