com.github.wolf480pl.ircd.netty.codec.MessageHandler.java Source code

Java tutorial

Introduction

Here is the source code for com.github.wolf480pl.ircd.netty.codec.MessageHandler.java

Source

/*
 * This file is part of IRCd4j.
 *
 * Copyright (c) 2014 Wolf480pl <wolf480@interia.pl>
 * IRCd4j is licensed under the GNU Lesser General Public License.
 *
 * IRCd4j is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * IRCd4j is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.github.wolf480pl.ircd.netty.codec;

import java.util.concurrent.atomic.AtomicReference;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.AttributeKey;

import com.github.wolf480pl.ircd.Message;
import com.github.wolf480pl.ircd.Session;
import com.github.wolf480pl.ircd.SessionHandler;
import com.github.wolf480pl.ircd.netty.NettySession;

public class MessageHandler extends SimpleChannelInboundHandler<Message> {
    public static final AttributeKey<Session> ATTR_SESSION = AttributeKey
            .valueOf(MessageHandler.class.getName() + ".SESSION");
    public static final AttributeKey<SessionHandler> ATTR_SESSION_HANDLER = AttributeKey
            .valueOf(MessageHandler.class.getName() + ".SESSION_HANDLER");

    private final AtomicReference<NettySession> session = new AtomicReference<>(null);
    private final SessionHandler handler;

    public MessageHandler(SessionHandler handler) {
        this.handler = handler;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        final Channel ch = ctx.channel();
        NettySession s = new NettySession(ch, handler);
        if (!session.compareAndSet(null, s)) {
            throw new IllegalStateException("Session was set before channel was activated");
        }
        ch.attr(ATTR_SESSION).set(s);
        ch.attr(ATTR_SESSION_HANDLER).set(handler);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        handler.onDisconnect(session.get());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        handler.onInboundThrowable(session.get(), cause);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Message msg) throws Exception {
        final NettySession s = session.get();
        s.validate(ctx.channel());
        handler.messageReceived(s, msg);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object event) {
        if (event instanceof IdleStateEvent) {
            final NettySession s = session.get();
            s.validate(ctx.channel());
            IdleStateEvent evt = (IdleStateEvent) event;
            if (evt.state() != IdleState.WRITER_IDLE) {
                // It's READER_IDLE or ALL_IDLE
                handler.onInboundIdle(session.get());
            }
        }
    }

}