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.ProtectedAnnotatedObjectInputStream;
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,
051                    ObjectDecodeChannelInboundHandler<?>
052                            objectDecodeChannelInboundHandler) {
053    
054                    _channelPipeline.addFirst(name, objectDecodeChannelInboundHandler);
055            }
056    
057            public void addLast(
058                    ObjectDecodeChannelInboundHandler<?>...
059                            objectDecodeChannelInboundHandlers) {
060    
061                    _channelPipeline.addLast(objectDecodeChannelInboundHandlers);
062            }
063    
064            public void addLast(
065                    String name,
066                    ObjectDecodeChannelInboundHandler<?>
067                            objectDecodeChannelInboundHandler) {
068    
069                    _channelPipeline.addLast(name, objectDecodeChannelInboundHandler);
070            }
071    
072            public <T extends ObjectDecodeChannelInboundHandler<?>> T remove(
073                    Class<T> handlerType) {
074    
075                    return _channelPipeline.remove(handlerType);
076            }
077    
078            public void remove(
079                    ObjectDecodeChannelInboundHandler<?>
080                            objectDecodeChannelInboundHandler) {
081    
082                    _channelPipeline.remove(objectDecodeChannelInboundHandler);
083            }
084    
085            public ObjectDecodeChannelInboundHandler<?> remove(String name) {
086                    return (ObjectDecodeChannelInboundHandler<?>)
087                            _channelPipeline.remove(name);
088            }
089    
090            public ObjectDecodeChannelInboundHandler<?> removeFirst() {
091                    return (ObjectDecodeChannelInboundHandler<?>)
092                            _channelPipeline.removeFirst();
093            }
094    
095            public ObjectDecodeChannelInboundHandler<?> removeLast() {
096                    return (ObjectDecodeChannelInboundHandler<?>)
097                            _channelPipeline.removeLast();
098            }
099    
100            @Override
101            protected Object decode(
102                            ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf)
103                    throws Exception {
104    
105                    ByteBuf decodeByteBuf = (ByteBuf)super.decode(
106                            channelHandlerContext, byteBuf);
107    
108                    if (decodeByteBuf == null) {
109                            return null;
110                    }
111    
112                    ObjectInputStream objectInputStream =
113                            new ProtectedAnnotatedObjectInputStream(
114                                    new ByteBufInputStream(decodeByteBuf));
115    
116                    Object object = objectInputStream.readObject();
117    
118                    for (Entry<String, ChannelHandler> entry : _channelPipeline) {
119                            ObjectDecodeChannelInboundHandler<?>
120                                    objectDecodeChannelInboundHandler =
121                                            (ObjectDecodeChannelInboundHandler<?>)entry.getValue();
122    
123                            object = objectDecodeChannelInboundHandler.channelRead(
124                                    channelHandlerContext, object, byteBuf);
125                    }
126    
127                    return object;
128            }
129    
130            @Override
131            protected ByteBuf extractFrame(
132                    ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, int index,
133                    int length) {
134    
135                    return byteBuf.slice(index, length);
136            }
137    
138            private final ChannelPipeline _channelPipeline =
139                    NettyUtil.createEmptyChannelPipeline();
140    
141    }