Package org.apache.mina.protocol.io

Source Code of org.apache.mina.protocol.io.IoAdapter

/*
*   @(#) $Id: IoAdapter.java 188654 2005-06-07 01:31:11Z trustin $
*
*   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.io;


import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IdleStatus;
import org.apache.mina.io.IoHandler;
import org.apache.mina.io.IoSession;
import org.apache.mina.protocol.ProtocolCodecFactory;
import org.apache.mina.protocol.ProtocolDecoder;
import org.apache.mina.protocol.ProtocolEncoder;
import org.apache.mina.protocol.ProtocolHandler;
import org.apache.mina.protocol.ProtocolFilterChain;
import org.apache.mina.protocol.ProtocolProvider;
import org.apache.mina.protocol.ProtocolSession;
import org.apache.mina.protocol.ProtocolViolationException;
import org.apache.mina.util.Queue;

/**
* Adapts the specified {@link ProtocolProvider} to {@link IoHandler}.
* This class is used by {@link IoProtocolAcceptor} and {@link IoProtocolConnector}
* internally.
* <p>
* It is a bridge between I/O layer and Protocol layer.  Protocol layer itself
* cannot do any real I/O, but it translates I/O events to more higher level
* ones and vice versa.
*
* @author Trustin Lee (trustin@apache.org)
* @version $Rev: 188654 $, $Date: 2005-06-07 10:31:11 +0900 $
*/
class IoAdapter
{
    private static final String KEY = "IoAdapter.ProtocolSession";

    private final IoProtocolSessionManagerFilterChain managerFilterChain;

    IoAdapter( IoProtocolSessionManagerFilterChain filters )
    {
        this.managerFilterChain = filters;
    }
   
    public ProtocolFilterChain getFilterChain()
    {
        return managerFilterChain;
    }

    /**
     * Converts the specified <code>protocolProvider</code> to {@link IoAdapter}
     * to use for actual I/O.
     *
     * @return a new I/O handler for the specified <code>protocolProvider</code>
     */
    public IoHandler adapt( ProtocolProvider protocolProvider )
    {
        return new SessionHandlerAdapter( protocolProvider );
    }

    /**
     * Returns {@link ProtocolSession} of the specified {@link IoSession}.
     */
    public ProtocolSession toProtocolSession( IoSession session )
    {
        IoHandler handler = session.getHandler();
        if( handler instanceof SessionHandlerAdapter )
        {
            SessionHandlerAdapter sha = ( SessionHandlerAdapter ) handler;
            return sha.getProtocolSession( session );
        }
        else
        {
            throw new IllegalArgumentException( "Not adapted from IoAdapter." );
        }
    }

    class SessionHandlerAdapter implements IoHandler
    {
        final ProtocolCodecFactory codecFactory;
        final ProtocolHandler handler;

        public SessionHandlerAdapter( ProtocolProvider protocolProvider )
        {
            codecFactory = protocolProvider.getCodecFactory();
            this.handler = protocolProvider.getHandler();
        }
       
        public void sessionCreated( IoSession session ) throws Exception
        {
            handler.sessionCreated( getProtocolSession( session ) );
        }

        public void sessionOpened( IoSession session )
        {
            managerFilterChain.sessionOpened( getProtocolSession( session ) );
        }

        public void sessionClosed( IoSession session )
        {
            managerFilterChain.sessionClosed( getProtocolSession( session ) );
        }

        public void sessionIdle( IoSession session, IdleStatus status )
        {
            managerFilterChain.sessionIdle( getProtocolSession( session ), status );
        }

        public void exceptionCaught( IoSession session, Throwable cause )
        {
            managerFilterChain.exceptionCaught( getProtocolSession( session ), cause );
        }

        public void dataRead( IoSession session, ByteBuffer in )
        {
            IoProtocolSession psession = getProtocolSession( session );
            ProtocolDecoder decoder = psession.decoder;
            try
            {
                synchronized( decoder )
                {
                    decoder.decode( psession, in, psession.decOut );
                }

                Queue queue = psession.decOut.getMessageQueue();
                synchronized( queue )
                {
                    if( !queue.isEmpty() )
                    {
                        do
                        {
                            managerFilterChain.messageReceived( psession, queue.pop() );
                        }
                        while( !queue.isEmpty() );
                    }
                }
            }
            catch( ProtocolViolationException pve )
            {
                pve.setBuffer( in );
                managerFilterChain.exceptionCaught( psession, pve );
            }
            catch( Throwable t )
            {
                managerFilterChain.exceptionCaught( psession, t );
            }
        }

        public void dataWritten( IoSession session, Object marker )
        {
            if( marker == null )
                return;
            managerFilterChain.messageSent( getProtocolSession( session ),
                                 marker );
        }

        void doWrite( IoSession session )
        {
            IoProtocolSession psession = getProtocolSession( session );
            ProtocolEncoder encoder = psession.encoder;
            Queue writeQueue = psession.writeQueue;

            if( writeQueue.isEmpty() )
            {
                return;
            }

            try
            {
                while( !writeQueue.isEmpty() )
                {
                    synchronized( writeQueue )
                    {
                        Object message = writeQueue.pop();
                        if( message == null )
                            break;

                        Queue queue = psession.encOut.getBufferQueue();
                        encoder.encode( psession, message, psession.encOut );
                        for( ;; )
                        {
                            ByteBuffer buf = ( ByteBuffer ) queue.pop();
                            if( buf == null )
                                break;
                            // use marker only if it is the last ByteBuffer
                            Object marker = queue.isEmpty() ? message : null;
                            session.write( buf, marker );
                        }
                    }
                }
            }
            catch( Throwable t )
            {
                managerFilterChain.exceptionCaught( psession, t );
            }
        }

        private IoProtocolSession getProtocolSession( IoSession session )
        {
            IoProtocolSession psession =
                ( IoProtocolSession ) session.getAttribute( KEY );
            if( psession == null )
            {
                synchronized( session )
                {
                    psession =
                        ( IoProtocolSession ) session.getAttribute( KEY );
                    if( psession == null )
                    {
                        psession = new IoProtocolSession(
                                IoAdapter.this.managerFilterChain, session, this );
                        session.setAttribute( KEY, psession );
                    }
                }
            }

            return psession;
        }
    }
}
TOP

Related Classes of org.apache.mina.protocol.io.IoAdapter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.