Package de.netseeker.ejoe

Source Code of de.netseeker.ejoe.ConnectionHeader

/*********************************************************************
* ConnectionHeader.java
* created on 04.03.2005 by netseeker
* $Source: /cvsroot/ejoe/EJOE/src/de/netseeker/ejoe/ConnectionHeader.java,v $
* $Date: 2007/03/22 21:01:35 $
* $Revision: 1.35 $
*
* ====================================================================
*
*  Copyright 2005-2006 netseeker aka Michael Manske
*
*  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.
* ====================================================================
*
* This file is part of the ejoe framework.
* For more information on the author, please see
* <http://www.manskes.de/>.
*
*********************************************************************/
package de.netseeker.ejoe;

import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.text.ParseException;

import de.netseeker.ejoe.cache.ByteBufferAllocator;
import de.netseeker.ejoe.io.IOUtil;

/**
* A simple connection header contining informations about compression and blocking/non-blocking io features. The header
* bits are structured as follows:
* |compression|nio|persistent|http|directMode|mixedMode|useAdapter|canHandleServerHandshakeResponse|
*
* @author netseeker
* @since 0.3.0
*/
public class ConnectionHeader implements Serializable
{
    private static final long       serialVersionUID  = 1L;

    private boolean[]               _header;

    private transient ByteBuffer    _waitingBuffer;

    private transient SocketChannel _channel;

    private transient Object        _attachment;

    private transient Object        _attachementInfo;

    private int                     _compressionLevel = EJConstants.DEFAULT_COMPRESSION_LEVEL;

    private String                  _adapterClass;

    private String                  _host;

    private boolean                 _isClient;

    private boolean                 _isConnected;

    /**
     * Creates a new instance of ConnectionHeader.
     */
    public ConnectionHeader(boolean isClient)
    {
        this( null, isClient );
    }

    /**
     * Creates a new instance of ConnectionHeader. The host member will be set to the given host.
     *
     * @param host the host string in the form IP address : port, eg. 127.0.0.1:12577
     */
    public ConnectionHeader(String host, boolean isClient)
    {
        setHost( host );
        _header = new boolean[] { false, true, true, false, false, false, false, true };
        this._isClient = isClient;
    }

    /**
     * Creates a new instance of ConnectionHeader. The host member will be set to the given host and the channel member
     * will be set to given channel.
     *
     * @param channel The channel to which this connection header applies.
     * @param host the host string in the form IP address : port, eg. 127.0.0.1:12577
     */
    public ConnectionHeader(SocketChannel channel, String host, boolean isClient)
    {
        this( host, isClient );
        this._channel = channel;
    }

    /**
     * Creates a new instance of ConnectionHeader. The host member will be set to the given host and the channel member
     * will be set to given channel.
     *
     * @param channel The channel to which this connection header applies.
     * @param host the host string in the form IP address : port, eg. 127.0.0.1:12577
     * @param header The byte representing the settings used for:
     *            <ul>
     *            <li>has compression</li>
     *            <li>has non blocking io</li>
     *            <li>is connected</li>
     *            <li>use persistent connection</li>
     *            </ul>
     */
    public ConnectionHeader(SocketChannel channel, String host, boolean isClient, byte header)
    {
        this( channel, host, isClient );
        fromByte( header );
    }

    /**
     * @param channel
     * @param host
     * @param isClient
     * @param header
     */
    private ConnectionHeader(String host, boolean isClient, final boolean[] header)
    {
        this( null, host, isClient );
        this._header = header;
    }

    /**
     * @return
     */
    public boolean hasCompression()
    {
        return _header[0];
    }

    /**
     * @param enable
     */
    public void setCompression( boolean enable )
    {
        _header[0] = enable;
    }

    /**
     * @param level
     */
    public void setCompressionLevel( int level )
    {
        this._compressionLevel = level;
    }

    /**
     * @return
     */
    public int getCompressionLevel()
    {
        return this._compressionLevel;
    }

    /**
     * @return
     */
    public boolean hasNonBlockingReadWrite()
    {
        return _header[1];
    }

    /**
     * @param enable
     */
    public void setNonBlockingReadWrite( boolean enable )
    {
        _header[1] = enable;
    }

    /**
     * @return
     */
    public boolean isPersistent()
    {
        return _header[2];
    }

    /**
     * @param enable
     */
    public void setPersistent( boolean enable )
    {
        _header[2] = enable;
    }

    /**
     * @return
     */
    public boolean isHttp()
    {
        return _header[3];
    }

    /**
     * @param http
     */
    public void setHttp( boolean enable )
    {
        _header[3] = enable;
    }

    /**
     * @return
     */
    public boolean isDirect()
    {
        return _header[4];
    }

    /**
     * @param enable
     */
    public void setIsDirect( boolean enable )
    {
        _header[4] = enable;
    }

    public boolean isMixed()
    {
        return _header[5];
    }

    public void setIsMixed( boolean enable )
    {
        _header[5] = enable;
    }

    /**
     * @return
     */
    public boolean hasAdapter()
    {
        return _header[6];
    }

    /**
     * @param name
     */
    public void setAdapterName( String name )
    {
        this._header[6] = !(name == null || name.length() == 0);
        this._adapterClass = name;
    }

    /**
     * @return
     */
    public boolean isHandshakeResponseAware()
    {
        return _header[7];
    }

    /**
     * @param enable
     */
    public void setIsHandshakeResponseAware( boolean enable )
    {
        _header[7] = enable;
    }

    /**
     * @return
     */
    public String getAdapterName()
    {
        return this._adapterClass;
    }

    /**
     * @return
     */
    public boolean isConnected()
    {
        return _isConnected;
    }

    /**
     * @param enable
     */
    public void setConnected( boolean enable )
    {
        _isConnected = enable;
    }

    /**
     * @return
     */
    public boolean hasWaitingBuffer()
    {
        return this._waitingBuffer != null; // && this._waitingBuffer.remaining() > 0;
    }

    /**
     * @return
     */
    public ByteBuffer getWaitingBuffer()
    {
        return this._waitingBuffer;
    }

    /**
     * @param buf
     */
    public void setWaitingBuffer( ByteBuffer buf )
    {
        this._waitingBuffer = buf;
    }

    /**
     *
     */
    public void releaseWaitingBuffer()
    {
        if ( this._waitingBuffer != null )
        {
            this._waitingBuffer.clear();
            this._waitingBuffer = null;
        }
    }

    /**
     * @return
     */
    public boolean hasAttachment()
    {
        return this._attachment != null;
    }

    /**
     * @param attachment
     */
    public void setAttachment( Object attachment )
    {
        this._attachment = attachment;
    }

    /**
     * @param attachment
     * @param attachmentInfo
     */
    public void setAttachment( Object attachment, Object attachmentInfo )
    {
        this._attachment = attachment;
        this._attachementInfo = attachmentInfo;
    }

    /**
     * @return
     */
    public boolean isClient()
    {
        return this._isClient;
    }

    /**
     * @return
     */
    public Object getAttachment()
    {
        return this._attachment;
    }

    /**
     * @return
     */
    public Object getAttachementInfo()
    {
        return this._attachementInfo;
    }

    /**
     *
     */
    public void releaseAttachment()
    {
        this._attachment = null;
        this._attachementInfo = null;
    }

    /**
     * @param channel
     */
    public void setChannel( SocketChannel channel )
    {
        this._channel = channel;
    }

    /**
     * @return
     */
    public SocketChannel getChannel()
    {
        return this._channel;
    }

    /**
     * @return
     */
    public String getHost()
    {
        return this._host;
    }

    /**
     * @param host
     */
    public void setHost( String host )
    {
        this._host = host;
    }

    /**
     * Returns a byte representation of the eight most important bits of the connection header
     *
     * @return a byte containing the eight most important bits of the connection header
     */
    public byte toByte()
    {
        return IOUtil.bBitsToByte( _header );
    }

    /**
     * sets the eight most important bits of the connection header based on the bits contained in the given byte
     *
     * @param header
     */
    public void fromByte( byte header )
    {
        _header = IOUtil.byteToBBits( header );
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    public String toString()
    {
        StringBuffer buf = new StringBuffer();
        buf.append( "/" );
        buf.append( IOUtil.bBitsToSBits( _header ) );

        if ( hasAdapter() )
        {
            buf.append( "/" );
            buf.append( getAdapterName().replaceAll( "\\.", "/" ) );
        }

        return buf.toString();
    }

    /**
     * Extracts the header settings from a formatted header string which follows the mask:
     *
     * <pre>
     *        header=12345678[&amp;adapter=somepackage.someadapter]
     * </pre>
     *
     * @param header
     */
    public void fromString( String header ) throws ParseException
    {
        String[] parts = null;
        if ( header.startsWith( "/" ) )
        {
            parts = header.substring( 1 ).split( "/", 2 );
        }
        else
        {
            parts = header.split( "/", 2 );
        }

        if ( parts.length >= 1 )
        {
            if ( parts[0].length() != 8 )
            {
                throw new ParseException( "Length of header bytes part must equals eight!", 0 );
            }
            _header = IOUtil.sBitsToBBits( parts[0] );

            if ( parts.length > 0 )
            {
                setAdapterName( parts[1].replaceAll( "/", "." ) );
            }
        }
        else
        {
            throw new ParseException( "Missing or wrong formatted header part", 0 );
        }
    }

    /**
     * Returns a {@link ByteBuffer} containg all transportable settings of the connection header
     *
     * @return a {@link ByteBuffer} representation of the connection header
     */
    public ByteBuffer toByteBuffer()
    {
        byte[] adapterArr = null;
        int length = 0;

        if ( _adapterClass != null )
        {
            adapterArr = IOUtil.encodeToBytes( _adapterClass );
            length = adapterArr.length;
        }

        // use indirect ByteBuffer because the buffer size will be just some
        // bytes and allocation of indirect buffers is much faster
        ByteBuffer buf = ByteBufferAllocator.allocate( 5 + length );
        buf.put( toByte() );
        buf.putInt( length );
        if ( adapterArr != null )
        {
            buf.put( adapterArr );
        }
        buf.flip();

        return buf;
    }

    /**
     * Returns the byte array representation of this connection header
     *
     * @return an array of bytes containing all transportable settings in the connection header
     */
    public byte[] toBytes()
    {
        ByteBuffer buf = toByteBuffer();
        byte[] result = new byte[buf.limit()];
        buf.get( result );

        return result;
    }

    /**
     * Returns a clean copy of the current instance containing all transportable settings of the connection header
     *
     * @return a clean copy
     */
    public ConnectionHeader copy()
    {
        ConnectionHeader header = new ConnectionHeader( this._host, this._isClient, (boolean[]) this._header.clone() );
        if ( hasAdapter() )
        {
            header.setAdapterName( this._adapterClass );
        }

        return header;
    }
}
TOP

Related Classes of de.netseeker.ejoe.ConnectionHeader

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.