001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.fabric.netty.codec.serialization;
016    
017    import com.liferay.portal.kernel.util.ReflectionUtil;
018    
019    import io.netty.buffer.ByteBuf;
020    import io.netty.channel.ChannelHandlerAdapter;
021    import io.netty.channel.ChannelHandlerContext;
022    import io.netty.channel.ChannelPipeline;
023    import io.netty.channel.SimpleChannelInboundHandler;
024    
025    import java.lang.reflect.Field;
026    
027    /**
028     * @author Shuyang Zhou
029     */
030    public abstract class ObjectDecodeChannelInboundHandler<T>
031            extends SimpleChannelInboundHandler<T> {
032    
033            @Override
034            public final void channelRead(
035                    ChannelHandlerContext channelHandlerContext, Object object) {
036    
037                    throw new UnsupportedOperationException();
038            }
039    
040            public Object channelRead(
041                            ChannelHandlerContext channelHandlerContext, Object object,
042                            ByteBuf byteBuf)
043                    throws Exception {
044    
045                    if (acceptInboundMessage(object)) {
046                            try {
047                                    return channelRead0(channelHandlerContext, (T)object, byteBuf);
048                            }
049                            catch (Throwable t) {
050                                    exceptionCaught(channelHandlerContext, t);
051                            }
052                    }
053    
054                    return object;
055            }
056    
057            public abstract T channelRead0(
058                            ChannelHandlerContext channelHandlerContext, T t, ByteBuf byteBuf)
059                    throws Exception;
060    
061            @Override
062            public void handlerAdded(ChannelHandlerContext channelHandlerContext)
063                    throws Exception {
064    
065                    if (_added) {
066                            return;
067                    }
068    
069                    _added = true;
070    
071                    ChannelPipeline channelPipeline = channelHandlerContext.pipeline();
072    
073                    channelPipeline.remove(this);
074    
075                    AnnotatedObjectDecoder annotatedObjectDecoder = channelPipeline.get(
076                            AnnotatedObjectDecoder.class);
077    
078                    if (annotatedObjectDecoder != null) {
079                            _ADDED_FIELD.setBoolean(this, false);
080    
081                            annotatedObjectDecoder.addLast(this);
082                    }
083            }
084    
085            @Override
086            protected final void channelRead0(
087                    ChannelHandlerContext channelHandlerContext, T t) {
088            }
089    
090            private static final Field _ADDED_FIELD;
091    
092            static {
093                    try {
094                            _ADDED_FIELD = ReflectionUtil.getDeclaredField(
095                                    ChannelHandlerAdapter.class, "added");
096                    }
097                    catch (Throwable t) {
098                            throw new ExceptionInInitializerError(t);
099                    }
100            }
101    
102            private boolean _added;
103    
104    }