You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by jv...@apache.org on 2013/01/13 10:04:03 UTC

[1/2] git commit: new codec API

new codec API


Project: http://git-wip-us.apache.org/repos/asf/mina/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina/commit/abe18bdf
Tree: http://git-wip-us.apache.org/repos/asf/mina/tree/abe18bdf
Diff: http://git-wip-us.apache.org/repos/asf/mina/diff/abe18bdf

Branch: refs/heads/trunk
Commit: abe18bdf289b7c9bb7ccf4b0a2f1be0a0ec6a7a4
Parents: daec22a
Author: Julien Vermillard <jv...@apache.org>
Authored: Wed Jan 9 21:23:11 2013 +0100
Committer: Julien Vermillard <jv...@apache.org>
Committed: Sat Jan 12 10:11:37 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/abe18bdf/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/abe18bdf/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/abe18bdf/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/abe18bdf/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