directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From trus...@apache.org
Subject svn commit: r161457 - directory/network/trunk/src/java/org/apache/mina/protocol/codec
Date Fri, 15 Apr 2005 13:42:29 GMT
Author: trustin
Date: Fri Apr 15 06:42:28 2005
New Revision: 161457

URL: http://svn.apache.org/viewcvs?view=rev&rev=161457
Log:
Added MessageCodecFactory and its interfaces.

Added:
    directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageCodecFactory.java
  (with props)
    directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageDecoder.java  
(with props)
    directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageEncoder.java  
(with props)

Added: directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageCodecFactory.java
URL: http://svn.apache.org/viewcvs/directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageCodecFactory.java?view=auto&rev=161457
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageCodecFactory.java
(added)
+++ directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageCodecFactory.java
Fri Apr 15 06:42:28 2005
@@ -0,0 +1,226 @@
+/*
+ *   @(#) $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;
+import org.apache.mina.protocol.codec.MessageDecoder.DecodeResult;
+
+/**
+ * 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 MessageCodecFactory 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 MessageCodecFactory()
+    {
+    }
+    
+    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 = MessageCodecFactory.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 );
+                    DecodeResult 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;
+                }
+            }
+            
+            DecodeResult 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/MessageCodecFactory.java
------------------------------------------------------------------------------
    svn:keywords = HeadURL Id LastChangedBy LastChangedDate LastChangedRevision

Added: 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=auto&rev=161457
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageDecoder.java (added)
+++ directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageDecoder.java Fri
Apr 15 06:42:28 2005
@@ -0,0 +1,99 @@
+/*
+ *   @(#) $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 org.apache.mina.common.ByteBuffer;
+import org.apache.mina.protocol.ProtocolDecoderOutput;
+import org.apache.mina.protocol.ProtocolSession;
+import org.apache.mina.protocol.ProtocolViolationException;
+
+/**
+ * Decodes specific messages.
+ * 
+ * @author The Apache Directory Project (dev@directory.apache.org)
+ * @author Trustin Lee (trustin@apache.org)
+ * @version $Rev$, $Date$
+ */
+public interface MessageDecoder {
+    /**
+     * Represents a result from {@link #decodable(ProtocolSession, ByteBuffer)} and
+     * {@link #decode(ProtocolSession, ByteBuffer, ProtocolDecoderOutput)}.  Please
+     * refer to each method's documentation for detailed explanation.
+     */
+    static DecodeResult OK = new DecodeResult( "OK" );
+
+    /**
+     * Represents a result from {@link #decodable(ProtocolSession, ByteBuffer)} and
+     * {@link #decode(ProtocolSession, ByteBuffer, ProtocolDecoderOutput)}.  Please
+     * refer to each method's documentation for detailed explanation.
+     */
+    static DecodeResult NEED_DATA = new DecodeResult( "NEED_DATA" );
+
+    /**
+     * Represents a result from {@link #decodable(ProtocolSession, ByteBuffer)} and
+     * {@link #decode(ProtocolSession, ByteBuffer, ProtocolDecoderOutput)}.  Please
+     * refer to each method's documentation for detailed explanation.
+     */
+    static DecodeResult NOT_OK = new DecodeResult( "NOT_OK" );
+    
+    /**
+     * Checks the specified buffer is decodable by this decoder.
+     * 
+     * @return {@link #OK} if this decoder can decode the specified buffer.
+     *         {@link #NOT_OK} if this decoder cannot decode the specified buffer.
+     *         {@link #NEED_DATA} if more data is required to determine if the
+     *         specified buffer is decodable ({@link #OK}) or not decodable
+     *         {@link #NOT_OK}.
+     */
+    DecodeResult decodable( ProtocolSession session, ByteBuffer in );
+    
+    /**
+     * Decodes binary or protocol-specific content into higher-level message objects.
+     * MINA invokes {@link #decode(ProtocolSession, ByteBuffer, ProtocolDecoderOutput)}
+     * method with read data, and then the decoder implementation puts decoded
+     * messages into {@link ProtocolDecoderOutput}.
+     * 
+     * @return {@link #OK} if you finished decoding messages successfully.
+     *         {@link #NEED_DATA} if you need more data to finish decoding current message.
+     *         {@link #NOT_OK} if you cannot decode current message due to protocol specification
violation.
+     *         
+     * @throws ProtocolViolationException if the read data violated protocol
+     *                                    specification 
+     */
+    DecodeResult decode( ProtocolSession session, ByteBuffer in,
+                         ProtocolDecoderOutput out ) throws ProtocolViolationException;
+    
+    /**
+     * Enumeration type  for decoding results.
+     */
+    public class DecodeResult
+    {
+        private final String name;
+
+        private DecodeResult( String name )
+        {
+            this.name = name;
+        }
+        
+        public String toString()
+        {
+            return name;
+        }
+    }
+}

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

Added: 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=auto&rev=161457
==============================================================================
--- directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageEncoder.java (added)
+++ directory/network/trunk/src/java/org/apache/mina/protocol/codec/MessageEncoder.java Fri
Apr 15 06:42:28 2005
@@ -0,0 +1,38 @@
+/*
+ *   @(#) $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.Set;
+
+import org.apache.mina.protocol.ProtocolEncoder;
+
+/**
+ * Encodes messages of specific types specified by {@link #getMessageTypes()}.
+ * 
+ * @author The Apache Directory Project (dev@directory.apache.org)
+ * @author Trustin Lee (trustin@apache.org)
+ * @version $Rev$, $Date$
+ */
+public interface MessageEncoder extends ProtocolEncoder
+{  
+    /**
+     * Returns the set of message classes this encoder can encode.
+     */
+    Set getMessageTypes();
+}

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



Mime
View raw message