Revert "Revert "new codec API"" finally I want the new API :)
This reverts commit 28b2c9197ed8f14bf784b15ec48136886a81084f. Project: http://git-wip-us.apache.org/repos/asf/mina/repo Commit: http://git-wip-us.apache.org/repos/asf/mina/commit/6eb647ef Tree: http://git-wip-us.apache.org/repos/asf/mina/tree/6eb647ef Diff: http://git-wip-us.apache.org/repos/asf/mina/diff/6eb647ef Branch: refs/heads/new-codec Commit: 6eb647efdbf50aeeb4692781591c250c0824831b Parents: 28b2c91 Author: Julien Vermillard <[email protected]> Authored: Sun Jan 13 10:35:01 2013 +0100 Committer: Julien Vermillard <[email protected]> Committed: Sun Jan 13 10:35:01 2013 +0100 ---------------------------------------------------------------------- .../mina/filter/codec/ProtocolCodecFactory.java | 6 +- .../mina/filter/codec/ProtocolCodecFilter.java | 93 ++++++--------- .../apache/mina/filter/codec/ProtocolDecoder.java | 54 ++------- .../apache/mina/filter/codec/ProtocolEncoder.java | 36 +----- 4 files changed, 59 insertions(+), 130 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mina/blob/6eb647ef/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFactory.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFactory.java b/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFactory.java index f408e4c..7406b41 100644 --- a/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFactory.java +++ b/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFactory.java @@ -31,17 +31,17 @@ import org.apache.mina.api.IoSession; * * @author <a href="http://mina.apache.org">Apache MINA Project</a> */ -public interface ProtocolCodecFactory { +public interface ProtocolCodecFactory<MESSAGE,ENCODED> { /** * Returns a new (or reusable) instance of {@link ProtocolEncoder} which * encodes message objects into binary or protocol-specific data. */ - ProtocolEncoder getEncoder(IoSession session); + ProtocolEncoder<MESSAGE,ENCODED> getEncoder(IoSession session); /** * Returns a new (or reusable) instance of {@link ProtocolDecoder} which * decodes binary or protocol-specific data into message objects. */ - ProtocolDecoder getDecoder(IoSession session); + ProtocolDecoder<ENCODED,MESSAGE> getDecoder(IoSession session); } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/mina/blob/6eb647ef/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFilter.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFilter.java b/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFilter.java index baa4227..2938cf3 100644 --- a/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFilter.java +++ b/core/src/main/java/org/apache/mina/filter/codec/ProtocolCodecFilter.java @@ -19,8 +19,6 @@ */ package org.apache.mina.filter.codec; -import java.nio.ByteBuffer; - import org.apache.mina.api.AbstractIoFilter; import org.apache.mina.api.IoFilter; import org.apache.mina.api.IoSession; @@ -38,22 +36,24 @@ import org.slf4j.LoggerFactory; * * @author <a href="http://mina.apache.org">Apache MINA Project</a> */ -public class ProtocolCodecFilter extends AbstractIoFilter { +public class ProtocolCodecFilter<MESSAGE,ENCODED> extends AbstractIoFilter { /** A logger for this class */ private static final Logger LOGGER = LoggerFactory.getLogger(ProtocolCodecFilter.class); private static final Class<?>[] EMPTY_PARAMS = new Class[0]; /** key for session attribute holding the encoder */ - private final AttributeKey<ProtocolEncoder> ENCODER = new AttributeKey<ProtocolEncoder>(ProtocolEncoder.class, + @SuppressWarnings("rawtypes") + private final AttributeKey<ProtocolEncoder> ENCODER = new AttributeKey<ProtocolEncoder>(ProtocolEncoder.class, "internal_encoder"); /** key for session attribute holding the decoder */ - private final AttributeKey<ProtocolDecoder> DECODER = new AttributeKey<ProtocolDecoder>(ProtocolDecoder.class, + @SuppressWarnings("rawtypes") + private final AttributeKey<ProtocolDecoder> DECODER = new AttributeKey<ProtocolDecoder>(ProtocolDecoder.class, "internal_decoder"); /** The factory responsible for creating the encoder and decoder */ - private final ProtocolCodecFactory factory; + private final ProtocolCodecFactory<MESSAGE,ENCODED> factory; /** * @@ -61,7 +61,7 @@ public class ProtocolCodecFilter extends AbstractIoFilter { * * @param factory The associated factory */ - public ProtocolCodecFilter(final ProtocolCodecFactory factory) { + public ProtocolCodecFilter(final ProtocolCodecFactory<MESSAGE,ENCODED> factory) { if (factory == null) { throw new IllegalArgumentException("factory"); } @@ -76,7 +76,7 @@ public class ProtocolCodecFilter extends AbstractIoFilter { * @param encoder The class responsible for encoding the message * @param decoder The class responsible for decoding the message */ - public ProtocolCodecFilter(final ProtocolEncoder encoder, final ProtocolDecoder decoder) { + public ProtocolCodecFilter(final ProtocolEncoder<MESSAGE,ENCODED> encoder, final ProtocolDecoder<ENCODED,MESSAGE> decoder) { if (encoder == null) { throw new IllegalArgumentException("encoder"); } @@ -86,14 +86,14 @@ public class ProtocolCodecFilter extends AbstractIoFilter { } // Create the inner Factory based on the two parameters - this.factory = new ProtocolCodecFactory() { + this.factory = new ProtocolCodecFactory<MESSAGE,ENCODED>() { @Override - public ProtocolEncoder getEncoder(final IoSession session) { + public ProtocolEncoder<MESSAGE,ENCODED> getEncoder(final IoSession session) { return encoder; } @Override - public ProtocolDecoder getDecoder(final IoSession session) { + public ProtocolDecoder<ENCODED,MESSAGE> getDecoder(final IoSession session) { return decoder; } }; @@ -107,8 +107,8 @@ public class ProtocolCodecFilter extends AbstractIoFilter { * @param encoderClass The class responsible for encoding the message * @param decoderClass The class responsible for decoding the message */ - public ProtocolCodecFilter(final Class<? extends ProtocolEncoder> encoderClass, - final Class<? extends ProtocolDecoder> decoderClass) { + public ProtocolCodecFilter(final Class<? extends ProtocolEncoder<MESSAGE,ENCODED>> encoderClass, + final Class<? extends ProtocolDecoder<ENCODED,MESSAGE>> decoderClass) { Assert.assertNotNull(encoderClass, "Encoder Class"); Assert.assertNotNull(decoderClass, "Decoder Class"); @@ -124,7 +124,7 @@ public class ProtocolCodecFilter extends AbstractIoFilter { throw new IllegalArgumentException("decoderClass doesn't have a public default constructor."); } - final ProtocolEncoder encoder; + final ProtocolEncoder<MESSAGE,ENCODED> encoder; try { encoder = encoderClass.newInstance(); @@ -132,7 +132,7 @@ public class ProtocolCodecFilter extends AbstractIoFilter { throw new IllegalArgumentException("encoderClass cannot be initialized"); } - final ProtocolDecoder decoder; + final ProtocolDecoder<ENCODED,MESSAGE> decoder; try { decoder = decoderClass.newInstance(); @@ -141,14 +141,14 @@ public class ProtocolCodecFilter extends AbstractIoFilter { } // Create the inner factory based on the two parameters. - this.factory = new ProtocolCodecFactory() { + this.factory = new ProtocolCodecFactory<MESSAGE,ENCODED>() { @Override - public ProtocolEncoder getEncoder(final IoSession session) { + public ProtocolEncoder<MESSAGE,ENCODED> getEncoder(final IoSession session) { return encoder; } @Override - public ProtocolDecoder getDecoder(final IoSession session) { + public ProtocolDecoder<ENCODED,MESSAGE> getDecoder(final IoSession session) { return decoder; } }; @@ -160,7 +160,7 @@ public class ProtocolCodecFilter extends AbstractIoFilter { * @param session The associated session we will get the encoder from * @return The encoder instance, if any */ - public ProtocolEncoder getEncoder(final IoSession session) { + public ProtocolEncoder<MESSAGE,ENCODED> getEncoder(final IoSession session) { return factory.getEncoder(session); } @@ -170,7 +170,7 @@ public class ProtocolCodecFilter extends AbstractIoFilter { * @param session The associated session we will get the decoder from * @return The decoder instance, if any */ - public ProtocolDecoder getDecoder(final IoSession session) { + public ProtocolDecoder<ENCODED,MESSAGE> getDecoder(final IoSession session) { return factory.getDecoder(session); } @@ -185,25 +185,16 @@ public class ProtocolCodecFilter extends AbstractIoFilter { * </code> */ @Override - public void messageReceived(final IoSession session, final Object message, + public void messageReceived(final IoSession session, final Object in, final ReadFilterChainController controller) { LOGGER.debug("Processing a MESSAGE_RECEIVED for session {}", session); - if (!(message instanceof ByteBuffer)) { - controller.callReadNextFilter(message); - return; - } - - final ByteBuffer in = (ByteBuffer) message; - final ProtocolDecoder decoder = getDecoder(session); + final ProtocolDecoder<ENCODED,MESSAGE> decoder = getDecoder(session); - // Loop until we don't have anymore byte in the buffer, - // or until the decoder throws an unrecoverable exception or - // can't decoder a message, because there are not enough - // data in the buffer - while (in.hasRemaining()) { - // Call the decoder with the read bytes - decoder.decode(session, in, controller); + // Loop until the codec cannot decode more + MESSAGE msg; + while ( (msg = decoder.decode(session, (ENCODED)in)) != null) { + controller.callReadNextFilter(msg); } } @@ -214,9 +205,11 @@ public class ProtocolCodecFilter extends AbstractIoFilter { public void messageWriting(IoSession session, WriteRequest message, WriteFilterChainController controller) { LOGGER.debug("Processing a MESSAGE_WRITTING for session {}", session); - final ProtocolEncoder encoder = session.getAttribute(ENCODER, null); - - encoder.encode(session, message, controller); + final ProtocolEncoder<MESSAGE,ENCODED> encoder = session.getAttribute(ENCODER, null); + ENCODED encoded = encoder.encode(session,(MESSAGE) message.getMessage()); + message.setMessage(encoded); + + controller.callWriteNextFilter(message); } /** @@ -226,9 +219,9 @@ public class ProtocolCodecFilter extends AbstractIoFilter { public void sessionOpened(final IoSession session) { // Initialize the encoder and decoder if we use a factory if (factory != null) { - final ProtocolEncoder encoder = factory.getEncoder(session); + final ProtocolEncoder<MESSAGE,ENCODED> encoder = factory.getEncoder(session); session.setAttribute(ENCODER, encoder); - final ProtocolDecoder decoder = factory.getDecoder(session); + final ProtocolDecoder<ENCODED,MESSAGE> decoder = factory.getDecoder(session); session.setAttribute(DECODER, decoder); } } @@ -257,17 +250,7 @@ public class ProtocolCodecFilter extends AbstractIoFilter { * method. */ private void disposeEncoder(final IoSession session) { - final ProtocolEncoder encoder = session.removeAttribute(ENCODER); - - if (encoder == null) { - return; - } - - try { - encoder.dispose(session); - } catch (final Throwable t) { - LOGGER.warn("Failed to dispose: " + encoder.getClass().getName() + " (" + encoder + ')'); - } + session.removeAttribute(ENCODER); } /** @@ -275,13 +258,9 @@ public class ProtocolCodecFilter extends AbstractIoFilter { * method. */ private void disposeDecoder(final IoSession session) { - final ProtocolDecoder decoder = session.removeAttribute(DECODER); - if (decoder == null) { - return; - } - + final ProtocolDecoder<ENCODED,MESSAGE> decoder = session.removeAttribute(DECODER); try { - decoder.dispose(session); + decoder.finishDecode(session); } catch (final Throwable t) { LOGGER.warn("Failed to dispose: " + decoder.getClass().getName() + " (" + decoder + ')'); } http://git-wip-us.apache.org/repos/asf/mina/blob/6eb647ef/core/src/main/java/org/apache/mina/filter/codec/ProtocolDecoder.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mina/filter/codec/ProtocolDecoder.java b/core/src/main/java/org/apache/mina/filter/codec/ProtocolDecoder.java index f77e4db..435f9d1 100644 --- a/core/src/main/java/org/apache/mina/filter/codec/ProtocolDecoder.java +++ b/core/src/main/java/org/apache/mina/filter/codec/ProtocolDecoder.java @@ -19,54 +19,26 @@ */ package org.apache.mina.filter.codec; -import java.nio.ByteBuffer; - import org.apache.mina.api.IoSession; -import org.apache.mina.filterchain.ReadFilterChainController; -import org.apache.mina.util.IoBuffer; /** * Decodes binary or protocol-specific data into higher-level message objects. - * MINA invokes {@link #decode(IoSession, IoBuffer, ProtocolDecoderOutput)} - * method with read data, and then the decoder implementation puts decoded - * messages into {@link ProtocolDecoderOutput} by calling - * {@link ProtocolDecoderOutput#write(Object)}. - * <p> - * Please refer to - * <a href="../../../../../xref-examples/org/apache/mina/examples/reverser/TextLineDecoder.html"><code>TextLineDecoder</code></a> - * example. * * @author <a href="http://mina.apache.org">Apache MINA Project</a> * - * @see ProtocolDecoderException */ -public interface ProtocolDecoder { - - /** - * Decodes binary or protocol-specific content into higher-level message objects. - * MINA invokes {@link #decode(IoSession, IoBuffer, ProtocolDecoderOutput)} - * method with read data, and then the decoder implementation puts decoded - * messages into {@link ProtocolDecoderOutput}. - * - * @throws Exception if the read data violated protocol specification - */ - Object decode(IoSession session, ByteBuffer in, ReadFilterChainController controller);// throws Exception; - - /** - * Invoked when the specified <tt>session</tt> is closed. This method is useful - * when you deal with the protocol which doesn't specify the length of a message - * such as HTTP response without <tt>content-length</tt> header. Implement this - * method to process the remaining data that {@link #decode(IoSession, ByteBuffer, ProtocolDecoderOutput)} - * method didn't process completely. - * - * @throws Exception if the read data violated protocol specification - */ - Object finishDecode(IoSession session) throws Exception; +public interface ProtocolDecoder<INPUT,OUTPUT> { - /** - * Releases all resources related with this decoder. - * - * @throws Exception if failed to dispose all resources - */ - void dispose(IoSession session) throws Exception; + /** + * Decode binary or protocol-specific content of type <code>INPUT</code> into higher-level protocol message objects, of type OUTPUT + * @param session the session for this message + * @param input the received message to decode + * @return the decoded message or <code>null</code> if nothing was decoded + */ + OUTPUT decode(IoSession session, INPUT input); + + /** + * Finish decoding, for example if the decoder accumulated some unused input, it should discard it, or throw an Exception + */ + void finishDecode(IoSession session); } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/mina/blob/6eb647ef/core/src/main/java/org/apache/mina/filter/codec/ProtocolEncoder.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/mina/filter/codec/ProtocolEncoder.java b/core/src/main/java/org/apache/mina/filter/codec/ProtocolEncoder.java index 71a3834..6bbc55e 100644 --- a/core/src/main/java/org/apache/mina/filter/codec/ProtocolEncoder.java +++ b/core/src/main/java/org/apache/mina/filter/codec/ProtocolEncoder.java @@ -19,43 +19,21 @@ */ package org.apache.mina.filter.codec; +import java.nio.ByteBuffer; + import org.apache.mina.api.IoSession; -import org.apache.mina.filterchain.WriteFilterChainController; -import org.apache.mina.session.WriteRequest; -import org.apache.mina.util.IoBuffer; /** - * Encodes higher-level message objects into binary or protocol-specific data. - * MINA invokes {@link #encode(IoSession, Object, ProtocolEncoderOutput)} - * method with message which is popped from the session write queue, and then - * the encoder implementation puts encoded messages (typically {@link IoBuffer}s) - * into {@link ProtocolEncoderOutput} by calling {@link ProtocolEncoderOutput#write(Object)}. - * <p> - * Please refer to - * <a href="../../../../../xref-examples/org/apache/mina/examples/reverser/TextLineEncoder.html"><code>TextLineEncoder</code></a> - * example. - * + * In charge of encoding a message of type MESSAGE into another form (could be a {@link ByteBuffer} or any other protocol level construction. + * * @author <a href="http://mina.apache.org">Apache MINA Project</a> * - * @see ProtocolEncoderException */ -public interface ProtocolEncoder { +public interface ProtocolEncoder<INPUT /* message type */, OUTPUT> { /** - * Encodes higher-level message objects into binary or protocol-specific data. - * MINA invokes {@link #encode(IoSession, Object, ProtocolEncoderOutput)} - * method with message which is popped from the session write queue, and then - * the encoder implementation puts encoded messages (typically {@link ByteBuffer}s) - * into {@link ProtocolEncoderOutput}. - * - * @throws Exception if the message violated protocol specification + * Encodes higher-level message objects of type <code>INPUT</code> into binary or protocol-specific data of type <code>OUTPUT</code>. */ - Object encode(IoSession session, WriteRequest message, WriteFilterChainController controller); // throws Exception; + OUTPUT encode(IoSession session, INPUT message); - /** - * Releases all resources related with this encoder. - * - * @throws Exception if failed to dispose all resources - */ - void dispose(IoSession session) throws Exception; } \ No newline at end of file
