码迷,mamicode.com
首页 > 编程语言 > 详细

Java内部类学习(四)—— 接口中的静态内部类

时间:2016-01-10 18:27:41      阅读:238      评论:0      收藏:0      [点我收藏+]

标签:

今天在阅读JetServer源码protocal部分的时候碰见了内部类的又一写法。定义一个接口LoginProtocol,包括了一个域和一个方法,然后在其中写了三个内部类,分别实现了该接口,代码如下:

package org.menacheri.jetserver.handlers.netty;

import static org.menacheri.jetserver.event.Events.LOG_IN;
import static org.menacheri.jetserver.event.Events.PROTCOL_VERSION;
import static org.menacheri.jetserver.event.Events.RECONNECT;

import java.util.List;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.ChannelHandler;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder;
import org.jboss.netty.handler.codec.frame.LengthFieldPrepender;
import org.jboss.netty.handler.codec.http.HttpChunkAggregator;
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
import org.jboss.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import org.menacheri.jetserver.event.Events;

/**
 * Applies a protocol to the incoming pipeline which will handle login.
 * Subsequent protocol may also be manipulated by these login handlers.
 * 
 * @author Abraham Menacherry
 * 
 */
public interface LoginProtocol
{
    String LOGIN_HANDLER_NAME = "loginHandler";
    /**
     * Apply a protocol on the pipeline to handle login. Implementations will
     * first "search" if the incoming bytes correspond to the implementations
     * protocol, only if they match, the correspoinding protocol will be
     * applied.
     * 
     * @param buffer
     *            The incoming buffer, by default around 5 bytes will be read
     *            and passed on to detect the protocol
     * @param pipeline
     *            The channelpipeline on which the login protocol handlers need
     *            to be set.
     * @return Returs true if the protocol was applied, else false.
     */
    public boolean applyProtocol(ChannelBuffer buffer, ChannelPipeline pipeline);

    /**
     * Searches the incoming bytes of a client connection to determine if its an
     * HTTP connection, in which case Websocket or HTTP related handlers will be
     * applied on the piepline.
     * 
     * @author Abraham Menacherry
     * 
     */
    public static class HTTPProtocol implements LoginProtocol
    {
        private WebSocketLoginHandler webSocketLoginHandler;
        @Override
        public boolean applyProtocol(ChannelBuffer buffer,
                ChannelPipeline pipeline)
        {
            boolean isThisProtocol = false;
            final int magic1 = buffer.getUnsignedByte(buffer.readerIndex());
            final int magic2 = buffer.getUnsignedByte(buffer.readerIndex() + 1);
            if (isHttp(magic1, magic2))
            {
                pipeline.addLast("decoder", new HttpRequestDecoder());
                pipeline.addLast("aggregator", new HttpChunkAggregator(65536));
                pipeline.addLast("encoder", new HttpResponseEncoder());
                pipeline.addLast("handler", new WebSocketServerProtocolHandler("/jetsocket"));
                pipeline.addLast(LOGIN_HANDLER_NAME, webSocketLoginHandler);
                isThisProtocol = true;
            }
            return isThisProtocol;
        }

        /**
         * Method which checks if the first 2 incoming parameters are G, E or
         * similar combiantions which signal that its an HTTP protocol, since
         * some protocols like jetserver‘s default protocol send the length
         * first (which is 2 arbitrary bytes), its better if this protocol is
         * searched last to avoid switching to HTTP protocol prematurely.
         * 
         * @param magic1
         * @param magic2
         * @return true if the two incoming bytes match any of the first two
         *         letter of HTTP headers like GET, POST etc.
         */
        protected boolean isHttp(int magic1, int magic2)
        {
            return magic1 == G && magic2 == E || // GET
                    magic1 == P && magic2 == O || // POST
                    magic1 == P && magic2 == U || // PUT
                    magic1 == H && magic2 == E || // HEAD
                    magic1 == O && magic2 == P || // OPTIONS
                    magic1 == P && magic2 == A || // PATCH
                    magic1 == D && magic2 == E || // DELETE
                    magic1 == T && magic2 == R || // TRACE
                    magic1 == C && magic2 == O; // CONNECT
        }

        public WebSocketLoginHandler getWebSocketLoginHandler()
        {
            return webSocketLoginHandler;
        }

        public void setWebSocketLoginHandler(WebSocketLoginHandler webSocketLoginHandler)
        {
            this.webSocketLoginHandler = webSocketLoginHandler;
        }
    }

    /**
     * This is the default protocol of jetserver. If incoming event is of type
     * LOG_IN and also has appropriate protocol version as defined in the
     * {@link Events} class, then this protocol will be applied. The 3rd and 4th
     * bytes of the incoming transmission are searched to get this information.
     * 
     * @author Abraham Menacherry
     * 
     */
    public static class DefaultJetProtocol implements LoginProtocol
    {

        private int frameSize = 1024;
        private EventDecoder eventDecoder;
        private LoginHandler loginHandler;
        private LengthFieldPrepender lengthFieldPrepender;

        @Override
        public boolean applyProtocol(ChannelBuffer buffer,
                ChannelPipeline pipeline)
        {
            boolean isThisProtocol = false;
            final int opcode = buffer.getUnsignedByte(buffer.readerIndex() + 2);
            final int protocolVersion = buffer.getUnsignedByte(buffer
                    .readerIndex() + 3);
            if (isJetProtocol(opcode, protocolVersion))
            {
                pipeline.addLast("framer", createLengthBasedFrameDecoder());
                pipeline.addLast("eventDecoder", eventDecoder);
                pipeline.addLast(LOGIN_HANDLER_NAME, loginHandler);
                pipeline.addLast("lengthFieldPrepender", lengthFieldPrepender);
                isThisProtocol = true;
            }
            return isThisProtocol;
        }

        protected boolean isJetProtocol(int magic1, int magic2)
        {
            return ((magic1 == LOG_IN || magic1 == RECONNECT) && magic2 == PROTCOL_VERSION);
        }

        public ChannelHandler createLengthBasedFrameDecoder()
        {
            return new LengthFieldBasedFrameDecoder(frameSize, 0, 2, 0, 2);
        }

        public int getFrameSize()
        {
            return frameSize;
        }

        public void setFrameSize(int frameSize)
        {
            this.frameSize = frameSize;
        }

        public EventDecoder getEventDecoder()
        {
            return eventDecoder;
        }

        public void setEventDecoder(EventDecoder eventDecoder)
        {
            this.eventDecoder = eventDecoder;
        }

        public LoginHandler getLoginHandler()
        {
            return loginHandler;
        }

        public void setLoginHandler(LoginHandler loginHandler)
        {
            this.loginHandler = loginHandler;
        }

        public LengthFieldPrepender getLengthFieldPrepender()
        {
            return lengthFieldPrepender;
        }

        public void setLengthFieldPrepender(
                LengthFieldPrepender lengthFieldPrepender)
        {
            this.lengthFieldPrepender = lengthFieldPrepender;
        }
    }

    public static class CompositeProtocol implements LoginProtocol
    {
        private List<LoginProtocol> protocols;

        @Override
        public boolean applyProtocol(ChannelBuffer buffer,
                ChannelPipeline pipeline)
        {
            if (null != protocols)
            {
                for (LoginProtocol protocol : protocols)
                {
                    if (protocol.applyProtocol(buffer, pipeline))
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        public List<LoginProtocol> getProtocols()
        {
            return protocols;
        }

        public void setProtocols(List<LoginProtocol> protocols)
        {
            this.protocols = protocols;
        }
    }
}

 在用Spring框架进行注入的时候,引用的方法是:接口所在的包名.接口名.内部类名字:

<!-- Login Protocols these decide what handlers are in the pipeline during 
        login of a client to jetserver -->
    <bean id="httpLoginProtocol" class="org.menacheri.jetserver.handlers.netty.LoginProtocol.HTTPProtocol" >
        <property name="webSocketLoginHandler" ref="webSocketLoginHandler" ></property>
    </bean>
    
    <bean id="defaultJetLoginProtocol" class="org.menacheri.jetserver.handlers.netty.LoginProtocol.DefaultJetProtocol" >
        <property name="eventDecoder" ref="eventDecoder"></property>
        <property name="loginHandler" ref="loginHandler"></property>
        <property name="lengthFieldPrepender" ref="lengthFieldPrepender"></property>
    </bean>
    
    
    <bean id="compositeLoginProtocol" class="org.menacheri.jetserver.handlers.netty.LoginProtocol.CompositeProtocol" scope="prototype">
        <property name="protocols">
            <list>
                <ref bean="defaultJetLoginProtocol"/>
                <ref bean="httpLoginProtocol"/>
            </list>
        </property>
    </bean>

 

Java内部类学习(四)—— 接口中的静态内部类

标签:

原文地址:http://www.cnblogs.com/Guoyutian/p/5118738.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!