package it.rafa.test; import it.rafa.protocol.BTLikeMessage; import java.io.IOException; import java.util.logging.Logger; import org.glassfish.grizzly.Buffer; import org.glassfish.grizzly.filterchain.BaseFilter; import org.glassfish.grizzly.filterchain.FilterChainContext; import org.glassfish.grizzly.filterchain.NextAction; import org.glassfish.grizzly.memory.MemoryManager; public class MyProtocolFilter extends BaseFilter { private static final Logger logger = Logger.getLogger(MyProtocolFilter.class.getName()); private static final int HEADER_SIZE = 2; /** * Method is called, when new data was read from the Connection and ready * to be processed. * * @param ctx Context of {@link FilterChainContext} processing * @return the next action * @throws java.io.IOException */ @Override public NextAction handleRead(final FilterChainContext ctx) throws IOException { logger.info("handling a message..."+ ctx.getMessage()); // Get the source buffer from the context final Buffer sourceBuffer = ctx.getMessage(); final int sourceBufferLength = sourceBuffer.remaining(); // If source buffer doesn't contain header if (sourceBufferLength < HEADER_SIZE) { // stop the filterchain processing and store sourceBuffer to be // used next time return ctx.getStopAction(sourceBuffer); } byte stx = sourceBuffer.get(); byte len = sourceBuffer.get(); logger.info("len=" + len); //The complete message length int intLen = len &0xFF; int completeMessageLength = intLen + 3; // If the source message doesn't contain entire body if (sourceBufferLength < completeMessageLength) { // stop the filterchain processing and store sourceBuffer to be // used next time return ctx.getStopAction(sourceBuffer); } // Check if the source buffer has more than 1 complete GIOP message // If yes - split up the first message and the remainder final Buffer remainder = sourceBufferLength > completeMessageLength ? sourceBuffer.split(completeMessageLength) : null; // Construct a GIOP message final MyMessage myMessage = new MyMessage(); // Set body length myMessage.setLen( intLen ); // Read body final byte[] body = new byte[intLen]; sourceBuffer.get(body); // Set body myMessage.setMsg( body ); logger.info("myMsg= "+myMessage); ctx.setMessage(myMessage); // We can try to dispose the buffer sourceBuffer.tryDispose(); // Instruct FilterChain to store the remainder (if any) and continue execution return ctx.getInvokeAction(remainder); } @Override public NextAction handleWrite(FilterChainContext ctx) throws IOException { Object o = ctx.getMessage(); if( o instanceof MyMessage ) { MyMessage btMsg = (MyMessage) o; byte[] btMsgBytes = btMsg.toArray(); // Retrieve the memory manager final MemoryManager memoryManager = ctx.getConnection().getTransport().getMemoryManager(); // allocate the buffer of required size final Buffer output = memoryManager.allocate(btMsgBytes.length); // Allow Grizzly core to dispose the buffer, once it's written output.allowBufferDispose(true); output.put( btMsgBytes ); // Set the Buffer as a context message ctx.setMessage(output.flip()); } return super.handleWrite(ctx); } }