You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by tr...@apache.org on 2005/04/15 15:59:14 UTC

svn commit: r161461 - in directory/network/trunk/src/java/org/apache/mina: io/ io/datagram/ io/socket/ protocol/ protocol/codec/ protocol/handler/

Author: trustin
Date: Fri Apr 15 06:59:12 2005
New Revision: 161461

URL: http://svn.apache.org/viewcvs?view=rev&rev=161461
Log:
* Renamed MessageCodecFactory to DemuxingProtocolCodecFactory
* Moved DemuxingProtocolHandler to separate package called 'handler' and extracted inner classes to separate classes.
* Fixed JavaDoc warnings

Added:
    directory/network/trunk/src/java/org/apache/mina/protocol/codec/DemuxingProtocolCodecFactory.java   (with props)
    directory/network/trunk/src/java/org/apache/mina/protocol/handler/
    directory/network/trunk/src/java/org/apache/mina/protocol/handler/DemuxingProtocolHandler.java   (with props)
    directory/network/trunk/src/java/org/apache/mina/protocol/handler/MessageHandler.java   (with props)
    directory/network/trunk/src/java/org/apache/mina/protocol/handler/UnknownMessageTypeException.java   (with props)
Removed:
    directory/network/trunk/src/java/org/apache/mina/protocol/DemuxingProtocolHandler.java
    directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageCodecFactory.java
Modified:
    directory/network/trunk/src/java/org/apache/mina/io/IoConnector.java
    directory/network/trunk/src/java/org/apache/mina/io/datagram/DatagramFilterChain.java
    directory/network/trunk/src/java/org/apache/mina/io/datagram/DatagramSessionConfig.java
    directory/network/trunk/src/java/org/apache/mina/io/socket/SocketFilterChain.java
    directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageDecoder.java
    directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageEncoder.java

Modified: directory/network/trunk/src/java/org/apache/mina/io/IoConnector.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/io/IoConnector.java?view=diff&r1=161460&r2=161461
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/io/IoConnector.java (original)
+++ directory/network/trunk/src/java/org/apache/mina/io/IoConnector.java Fri Apr 15 06:59:12 2005
@@ -67,7 +67,7 @@
      * @param localAddress the local address the channel is bound to
      * @throws IOException if failed to connect
      */
-    IoSession connect( SocketAddress address, SocketAddress loadlAddress,
+    IoSession connect( SocketAddress address, SocketAddress localAddress,
                        IoHandler handler ) throws IOException;
 
     /**

Modified: directory/network/trunk/src/java/org/apache/mina/io/datagram/DatagramFilterChain.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/io/datagram/DatagramFilterChain.java?view=diff&r1=161460&r2=161461
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/io/datagram/DatagramFilterChain.java (original)
+++ directory/network/trunk/src/java/org/apache/mina/io/datagram/DatagramFilterChain.java Fri Apr 15 06:59:12 2005
@@ -2,6 +2,7 @@
 
 import org.apache.mina.common.ByteBuffer;
 import org.apache.mina.io.AbstractIoHandlerFilterChain;
+import org.apache.mina.io.IoHandlerFilterChain;
 import org.apache.mina.io.IoSession;
 import org.apache.mina.util.Queue;
 

Modified: directory/network/trunk/src/java/org/apache/mina/io/datagram/DatagramSessionConfig.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/io/datagram/DatagramSessionConfig.java?view=diff&r1=161460&r2=161461
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/io/datagram/DatagramSessionConfig.java (original)
+++ directory/network/trunk/src/java/org/apache/mina/io/datagram/DatagramSessionConfig.java Fri Apr 15 06:59:12 2005
@@ -22,6 +22,8 @@
 import java.nio.channels.DatagramChannel;
 
 import org.apache.mina.common.SessionConfig;
+import org.apache.mina.io.IoSession;
+import org.apache.mina.protocol.ProtocolSession;
 import org.apache.mina.util.BasicSessionConfig;
 
 /**

Modified: directory/network/trunk/src/java/org/apache/mina/io/socket/SocketFilterChain.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/io/socket/SocketFilterChain.java?view=diff&r1=161460&r2=161461
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/io/socket/SocketFilterChain.java (original)
+++ directory/network/trunk/src/java/org/apache/mina/io/socket/SocketFilterChain.java Fri Apr 15 06:59:12 2005
@@ -2,6 +2,7 @@
 
 import org.apache.mina.common.ByteBuffer;
 import org.apache.mina.io.AbstractIoHandlerFilterChain;
+import org.apache.mina.io.IoHandlerFilterChain;
 import org.apache.mina.io.IoSession;
 import org.apache.mina.util.Queue;
 

Added: directory/network/trunk/src/java/org/apache/mina/protocol/codec/DemuxingProtocolCodecFactory.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/protocol/codec/DemuxingProtocolCodecFactory.java?view=auto&rev=161461
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/protocol/codec/DemuxingProtocolCodecFactory.java (added)
+++ directory/network/trunk/src/java/org/apache/mina/protocol/codec/DemuxingProtocolCodecFactory.java Fri Apr 15 06:59:12 2005
@@ -0,0 +1,225 @@
+/*
+ *   @(#) $Id$
+ *
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.mina.protocol.codec;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.protocol.ProtocolCodecFactory;
+import org.apache.mina.protocol.ProtocolDecoder;
+import org.apache.mina.protocol.ProtocolDecoderOutput;
+import org.apache.mina.protocol.ProtocolEncoder;
+import org.apache.mina.protocol.ProtocolEncoderOutput;
+import org.apache.mina.protocol.ProtocolSession;
+import org.apache.mina.protocol.ProtocolViolationException;
+
+/**
+ * A composite {@link ProtocolCodecFactory} that consists of multiple
+ * {@link MessageEncoder}s and {@link MessageDecoder}s.
+ * {@link ProtocolEncoder} and {@link ProtocolDecoder} this factory
+ * returns demultiplex incoming messages and buffers to
+ * appropriate {@link MessageEncoder}s and {@link MessageDecoder}s. 
+ * 
+ * @author The Apache Directory Project (dev@directory.apache.org)
+ * @author Trustin Lee (trustin@apache.org)
+ * @version $Rev$, $Date$
+ * 
+ * @see MessageEncoder
+ * @see MessageDecoder
+ */
+public class DemuxingProtocolCodecFactory implements ProtocolCodecFactory {
+
+    private MessageDecoder[] decoders = new MessageDecoder[0];
+    private final Map encoders = new HashMap();
+    
+    private final ProtocolEncoder protocolEncoder = new ProtocolEncoderImpl();
+
+    private final ProtocolDecoder protocolDecoder = new ProtocolDecoderImpl();
+    
+    public DemuxingProtocolCodecFactory()
+    {
+    }
+    
+    public void register( MessageEncoder encoder )
+    {
+        Iterator it = encoder.getMessageTypes().iterator();
+        while( it.hasNext() )
+        {
+            Class type = (Class) it.next();
+            encoders.put( type, encoder );
+        }
+    }
+    
+    public void register( MessageDecoder decoder )
+    {
+        if( decoder == null )
+        {
+            throw new NullPointerException( "decoder" );
+        }
+        MessageDecoder[] decoders = this.decoders;
+        MessageDecoder[] newDecoders = new MessageDecoder[ decoders.length + 1 ];
+        System.arraycopy( decoders, 0, newDecoders, 0, decoders.length );
+        newDecoders[ decoders.length ] = decoder;
+        this.decoders = newDecoders;
+    }
+    
+    public ProtocolEncoder newEncoder() {
+        return protocolEncoder;
+    }
+
+    public ProtocolDecoder newDecoder() {
+        return protocolDecoder;
+    }
+    
+    private class ProtocolEncoderImpl implements ProtocolEncoder
+    {
+        public void encode( ProtocolSession session, Object message,
+                            ProtocolEncoderOutput out ) throws ProtocolViolationException
+        {
+            Class type = message.getClass();
+            MessageEncoder encoder = findEncoder( type );
+            if( encoder == null )
+            {
+                throw new ProtocolViolationException( "Unexpected message type: " + type );
+            }
+            
+            encoder.encode( session, message, out );
+        }
+        
+        private MessageEncoder findEncoder( Class type )
+        {
+            MessageEncoder encoder = ( MessageEncoder ) encoders.get( type );
+            if( encoder == null )
+            {
+                encoder = findEncoder( type, new HashSet() );
+            }
+
+            return encoder;
+        }
+
+        private MessageEncoder findEncoder( Class type, Set triedClasses )
+        {
+            MessageEncoder encoder;
+
+            if( triedClasses.contains( type ) )
+                return null;
+            triedClasses.add( type );
+
+            encoder = ( MessageEncoder ) encoders.get( type );
+            if( encoder == null )
+            {
+                encoder = findEncoder( type, triedClasses );
+                if( encoder != null )
+                    return encoder;
+
+                Class[] interfaces = type.getInterfaces();
+                for( int i = 0; i < interfaces.length; i ++ )
+                {
+                    encoder = findEncoder( interfaces[ i ], triedClasses );
+                    if( encoder != null )
+                        return encoder;
+                }
+
+                return null;
+            }
+            else
+                return encoder;
+        }
+    }
+    
+    private class ProtocolDecoderImpl extends CumulativeProtocolDecoder
+    {
+        private MessageDecoder currentDecoder;
+
+        protected ProtocolDecoderImpl()
+        {
+            super( 16 );
+        }
+
+        protected boolean doDecode( ProtocolSession session, ByteBuffer in,
+                                    ProtocolDecoderOutput out) throws ProtocolViolationException
+        {
+            if( currentDecoder == null )
+            {
+                MessageDecoder[] decoders = DemuxingProtocolCodecFactory.this.decoders;
+                int undecodables = 0;
+                for( int i = decoders.length - 1; i >= 0; i -- ) 
+                {
+                    MessageDecoder decoder = decoders[i];
+                    int limit = in.limit();
+                    in.position( 0 );
+                    MessageDecoderResult result = decoder.decodable( session, in );
+                    in.position( 0 );
+                    in.limit( limit );
+                    
+                    if( result == MessageDecoder.OK )
+                    {
+                        currentDecoder = decoder;
+                        break;
+                    }
+                    else if( result == MessageDecoder.NOT_OK )
+                    {
+                        undecodables ++;
+                    }
+                    else if( result != MessageDecoder.NEED_DATA )
+                    {
+                        throw new IllegalStateException( "Unexpected decode result (see your decodable()): " + result );
+                    }
+                }
+                
+                if( undecodables == decoders.length )
+                {
+                    // Throw an exception if all decoders cannot decode data.
+                    in.position( in.limit() ); // Skip data
+                    throw new ProtocolViolationException(
+                            "No appropriate message decoder: " + in.getHexDump() );
+                }
+                
+                if( currentDecoder == null )
+                {
+                    // Decoder is not determined yet (i.e. we need more data)
+                    return false;
+                }
+            }
+            
+            MessageDecoderResult result = currentDecoder.decode( session, in, out );
+            if( result == MessageDecoder.OK )
+            {
+                currentDecoder = null;
+                return true;
+            }
+            else if( result == MessageDecoder.NEED_DATA )
+            {
+                return false;
+            }
+            else if( result == MessageDecoder.NOT_OK )
+            {
+                throw new ProtocolViolationException( "Message decoder returned NOT_OK." );
+            }
+            else
+            {
+                throw new IllegalStateException( "Unexpected decode result (see your decode()): " + result );
+            }
+        }
+    }
+}

Propchange: directory/network/trunk/src/java/org/apache/mina/protocol/codec/DemuxingProtocolCodecFactory.java
------------------------------------------------------------------------------
    svn:keywords = HeadURL Id LastChangedBy LastChangedDate LastChangedRevision

Modified: directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageDecoder.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageDecoder.java?view=diff&r1=161460&r2=161461
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageDecoder.java (original)
+++ directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageDecoder.java Fri Apr 15 06:59:12 2005
@@ -30,7 +30,7 @@
  * @author Trustin Lee (trustin@apache.org)
  * @version $Rev$, $Date$
  * 
- * @see MessageCodecFactory
+ * @see DemuxingProtocolCodecFactory
  */
 public interface MessageDecoder {
     /**

Modified: directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageEncoder.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageEncoder.java?view=diff&r1=161460&r2=161461
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageEncoder.java (original)
+++ directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageEncoder.java Fri Apr 15 06:59:12 2005
@@ -29,7 +29,7 @@
  * @author Trustin Lee (trustin@apache.org)
  * @version $Rev$, $Date$
  * 
- * @see MessageCodecFactory
+ * @see DemuxingProtocolCodecFactory
  */
 public interface MessageEncoder extends ProtocolEncoder
 {  

Added: directory/network/trunk/src/java/org/apache/mina/protocol/handler/DemuxingProtocolHandler.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/protocol/handler/DemuxingProtocolHandler.java?view=auto&rev=161461
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/protocol/handler/DemuxingProtocolHandler.java (added)
+++ directory/network/trunk/src/java/org/apache/mina/protocol/handler/DemuxingProtocolHandler.java Fri Apr 15 06:59:12 2005
@@ -0,0 +1,117 @@
+/*
+ * @(#) $Id$
+ */
+package org.apache.mina.protocol.handler;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.mina.protocol.ProtocolHandler;
+import org.apache.mina.protocol.ProtocolSession;
+
+/**
+ * A {@link ProtocolHandler} that demuxes <code>messageReceived</code> events
+ * to the appropriate {@link MessageHandler}.
+ * 
+ * You can freely register and deregister {@link MessageHandler}s using
+ * {@link #registerMessageType(Class, MessageHandler)} and
+ * {@link #deregisterMessageType(Class)}.
+ * 
+ * @author The Apache Directory Project
+ * @version $Rev$, $Date$
+ */
+public abstract class DemuxingProtocolHandler implements ProtocolHandler
+{
+    private final Map type2handler = new HashMap();
+
+    /**
+     * Creates a new instance with no registered {@link MessageHandler}s.
+     */
+    protected DemuxingProtocolHandler()
+    {
+    }
+
+    /**
+     * Registers a {@link MessageHandler} that receives the messages of
+     * the specified <code>type</code>.
+     */
+    protected void registerMessageType( Class type, MessageHandler handler )
+    {
+        synchronized( type2handler )
+        {
+            type2handler.put( type, handler );
+        }
+    }
+
+    /**
+     * Deregisters a {@link MessageHandler} that receives the messages of
+     * the specified <code>type</code>.
+     */
+    protected void deregisterMessageType( Class clazz )
+    {
+        synchronized( type2handler )
+        {
+            type2handler.remove( clazz );
+        }
+    }
+
+    /**
+     * Forwards the received events into the appropriate {@link MessageHandler}
+     * which is registered by {@link #registerMessageType(Class, MessageHandler)}.
+     */
+    public void messageReceived( ProtocolSession session, Object message )
+    {
+        MessageHandler handler = findHandler( message.getClass() );
+        if( handler != null )
+        {
+            handler.messageReceived( session, message );
+        }
+        else
+        {
+            throw new UnknownMessageTypeException(
+                    "No message handler found for message: " + message );
+        }
+    }
+
+    private MessageHandler findHandler( Class type )
+    {
+        MessageHandler handler = ( MessageHandler ) type2handler.get( type );
+        if( handler == null )
+        {
+            handler = findHandler( type, new HashSet() );
+        }
+
+        return handler;
+    }
+
+    private MessageHandler findHandler( Class type, Set triedClasses )
+    {
+        MessageHandler handler;
+
+        if( triedClasses.contains( type ) )
+            return null;
+        triedClasses.add( type );
+
+        handler = ( MessageHandler ) type2handler.get( type );
+        if( handler == null )
+        {
+            handler = findHandler( type, triedClasses );
+            if( handler != null )
+                return handler;
+
+            Class[] interfaces = type.getInterfaces();
+            for( int i = 0; i < interfaces.length; i ++ )
+            {
+                handler = findHandler( interfaces[ i ], triedClasses );
+                if( handler != null )
+                    return handler;
+            }
+
+            return null;
+        }
+        else
+            return handler;
+    }
+}

Propchange: directory/network/trunk/src/java/org/apache/mina/protocol/handler/DemuxingProtocolHandler.java
------------------------------------------------------------------------------
    svn:keywords = HeadURL Id LastChangedBy LastChangedDate LastChangedRevision

Added: directory/network/trunk/src/java/org/apache/mina/protocol/handler/MessageHandler.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/protocol/handler/MessageHandler.java?view=auto&rev=161461
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/protocol/handler/MessageHandler.java (added)
+++ directory/network/trunk/src/java/org/apache/mina/protocol/handler/MessageHandler.java Fri Apr 15 06:59:12 2005
@@ -0,0 +1,50 @@
+/*
+ *   @(#) $Id$
+ *
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.mina.protocol.handler;
+
+import org.apache.mina.protocol.ProtocolSession;
+
+/**
+ * A handler interface that {@link DemuxingProtocolHandler} forwards
+ * <code>messageReceived</code> events to.  You have to register your
+ * handler with the type of message you want to get notified using
+ * {@link DemuxingProtocolHandler#registerMessageType(Class, MessageHandler)}.
+ * 
+ * @author The Apache Directory Project
+ * @version $Rev$, $Date$
+ */
+public interface MessageHandler
+{
+    /**
+     * A {@link MessageHandler} that does nothing.  This is usefule when
+     * you want to ignore messages of the specific type silently.
+     */
+    static MessageHandler NOOP = new MessageHandler()
+    {
+        public void messageReceived( ProtocolSession session, Object message )
+        {
+        }
+    };
+    
+    /**
+     * Invoked when the specific type of message is received from the
+     * specified <code>session</code>.
+     */
+    void messageReceived( ProtocolSession session, Object message );
+}
\ No newline at end of file

Propchange: directory/network/trunk/src/java/org/apache/mina/protocol/handler/MessageHandler.java
------------------------------------------------------------------------------
    svn:keywords = HeadURL Id LastChangedBy LastChangedDate LastChangedRevision

Added: directory/network/trunk/src/java/org/apache/mina/protocol/handler/UnknownMessageTypeException.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/protocol/handler/UnknownMessageTypeException.java?view=auto&rev=161461
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/protocol/handler/UnknownMessageTypeException.java (added)
+++ directory/network/trunk/src/java/org/apache/mina/protocol/handler/UnknownMessageTypeException.java Fri Apr 15 06:59:12 2005
@@ -0,0 +1,54 @@
+/*
+ *   @(#) $Id$
+ *
+ *   Copyright 2004 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.mina.protocol.handler;
+
+
+/**
+ * An exception that is thrown when {@link DemuxingProtocolHandler}
+ * cannot find any {@link MessageHandler}s associated with the specific
+ * message type.  You have to use
+ * {@link DemuxingProtocolHandler#registerMessageType(Class, MessageHandler)}
+ * to associate a message type and a message handler. 
+ * 
+ * @author The Apache Directory Project
+ * @version $Rev$, $Date$
+ */
+public class UnknownMessageTypeException extends RuntimeException
+{
+    private static final long serialVersionUID = 3257290227428047158L;
+
+    public UnknownMessageTypeException()
+    {
+    }
+
+    public UnknownMessageTypeException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+
+    public UnknownMessageTypeException( String message )
+    {
+        super( message );
+    }
+
+    public UnknownMessageTypeException( Throwable cause )
+    {
+        super( cause );
+    }
+}
\ No newline at end of file

Propchange: directory/network/trunk/src/java/org/apache/mina/protocol/handler/UnknownMessageTypeException.java
------------------------------------------------------------------------------
    svn:keywords = HeadURL Id LastChangedBy LastChangedDate LastChangedRevision