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.fabric.netty.util.NettyUtil;
018    import com.liferay.portal.kernel.io.AnnotatedObjectInputStream;
019    
020    import io.netty.buffer.ByteBuf;
021    import io.netty.buffer.ByteBufInputStream;
022    import io.netty.channel.ChannelHandler;
023    import io.netty.channel.ChannelHandlerContext;
024    import io.netty.channel.ChannelPipeline;
025    import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
026    
027    import java.io.ObjectInputStream;
028    
029    import java.util.Map.Entry;
030    
031    /**
032     * @author Shuyang Zhou
033     */
034    public class AnnotatedObjectDecoder extends LengthFieldBasedFrameDecoder {
035    
036            public static final String NAME = AnnotatedObjectDecoder.class.getName();
037    
038            public AnnotatedObjectDecoder() {
039                    super(Integer.MAX_VALUE, 0, 4, 0, 4);
040            }
041    
042            public void addFirst(
043                    ObjectDecodeChannelInboundHandler<?>...
044                            objectDecodeChannelInboundHandlers) {
045    
046                    _channelPipeline.addFirst(objectDecodeChannelInboundHandlers);
047            }
048    
049            public void addFirst(
050                    String name, ObjectDecodeChannelInboundHandler<?>
051                            objectDecodeChannelInboundHandler) {
052    
053                    _channelPipeline.addFirst(name, objectDecodeChannelInboundHandler);
054            }
055    
056            public void addLast(
057                    ObjectDecodeChannelInboundHandler<?>...
058                            objectDecodeChannelInboundHandlers) {
059    
060                    _channelPipeline.addLast(objectDecodeChannelInboundHandlers);
061            }
062    
063            public void addLast(
064                    String name, ObjectDecodeChannelInboundHandler<?>
065                            objectDecodeChannelInboundHandler) {
066    
067                    _channelPipeline.addLast(name, objectDecodeChannelInboundHandler);
068            }
069    
070            public <T extends ObjectDecodeChannelInboundHandler<?>> T remove(
071                    Class<T> handlerType) {
072    
073                    return _channelPipeline.remove(handlerType);
074            }
075    
076            public void remove(
077                    ObjectDecodeChannelInboundHandler<?>
078                            objectDecodeChannelInboundHandler) {
079    
080                    _channelPipeline.remove(objectDecodeChannelInboundHandler);
081            }
082    
083            public ObjectDecodeChannelInboundHandler<?> remove(String name) {
084                    return (ObjectDecodeChannelInboundHandler<?>)
085                            _channelPipeline.remove(name);
086            }
087    
088            public ObjectDecodeChannelInboundHandler<?> removeFirst() {
089                    return (ObjectDecodeChannelInboundHandler<?>)
090                            _channelPipeline.removeFirst();
091            }
092    
093            public ObjectDecodeChannelInboundHandler<?> removeLast() {
094                    return (ObjectDecodeChannelInboundHandler<?>)
095                            _channelPipeline.removeLast();
096            }
097    
098            @Override
099            protected Object decode(
100                            ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf)
101                    throws Exception {
102    
103                    ByteBuf decodeByteBuf = (ByteBuf)super.decode(
104                            channelHandlerContext, byteBuf);
105    
106                    if (decodeByteBuf == null) {
107                            return null;
108                    }
109    
110                    ObjectInputStream objectInputStream = new AnnotatedObjectInputStream(
111                            new ByteBufInputStream(decodeByteBuf));
112    
113                    Object object = objectInputStream.readObject();
114    
115                    for (Entry<String, ChannelHandler> entry : _channelPipeline) {
116                            ObjectDecodeChannelInboundHandler<?>
117                                    objectDecodeChannelInboundHandler =
118                                            (ObjectDecodeChannelInboundHandler<?>)entry.getValue();
119    
120                            object = objectDecodeChannelInboundHandler.channelRead(
121                                    channelHandlerContext, object, byteBuf);
122                    }
123    
124                    return object;
125            }
126    
127            @Override
128            protected ByteBuf extractFrame(
129                    ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, int index,
130                    int length) {
131    
132                    return byteBuf.slice(index, length);
133            }
134    
135            private final ChannelPipeline _channelPipeline =
136                    NettyUtil.createEmptyChannelPipeline();
137    
138    }