From 7fddc9ddfa7c90def211eaa3ce7930b2b350891c Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Wed, 17 Dec 2008 07:38:32 +0000 Subject: [PATCH] * Added OneToOneEncoder and OneToOneDecoder * Removed most duplicate code by extending them --- .../codec/http/HttpMessageEncoder.java | 21 +++-- .../handler/codec/oneone/OneToOneDecoder.java | 85 +++++++++++++++++++ .../handler/codec/oneone/OneToOneEncoder.java | 78 +++++++++++++++++ .../handler/codec/oneone/package-info.java | 28 ++++++ .../CompatibleObjectEncoder.java | 23 ++--- .../codec/serialization/ObjectEncoder.java | 29 +++---- .../handler/codec/string/StringDecoder.java | 30 ++----- .../handler/codec/string/StringEncoder.java | 28 ++---- 8 files changed, 236 insertions(+), 86 deletions(-) create mode 100644 src/main/java/org/jboss/netty/handler/codec/oneone/OneToOneDecoder.java create mode 100644 src/main/java/org/jboss/netty/handler/codec/oneone/OneToOneEncoder.java create mode 100644 src/main/java/org/jboss/netty/handler/codec/oneone/package-info.java diff --git a/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageEncoder.java b/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageEncoder.java index 45a1f58548..468558438d 100644 --- a/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageEncoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/http/HttpMessageEncoder.java @@ -21,7 +21,6 @@ */ package org.jboss.netty.handler.codec.http; -import static org.jboss.netty.channel.Channels.*; import static org.jboss.netty.handler.codec.http.HttpCodecUtil.*; import java.util.List; @@ -29,10 +28,10 @@ import java.util.Set; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBuffers; +import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipelineCoverage; -import org.jboss.netty.channel.MessageEvent; -import org.jboss.netty.channel.SimpleChannelHandler; +import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; /** * encodes an http message @@ -43,23 +42,23 @@ import org.jboss.netty.channel.SimpleChannelHandler; * @version $Rev$, $Date$ */ @ChannelPipelineCoverage("one") -public abstract class HttpMessageEncoder extends SimpleChannelHandler { +public abstract class HttpMessageEncoder extends OneToOneEncoder { + @Override - public void writeRequested(ChannelHandlerContext ctx, MessageEvent e) throws Exception { - if (!(e.getMessage() instanceof HttpMessage)) { - ctx.sendDownstream(e); - return; + protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { + if (!(msg instanceof HttpMessage)) { + return msg; } - HttpMessage request = (HttpMessage) e.getMessage(); + HttpMessage request = (HttpMessage) msg; ChannelBuffer buf = ChannelBuffers.dynamicBuffer( - e.getChannel().getConfig().getBufferFactory()); + channel.getConfig().getBufferFactory()); encodeInitialLine(buf, request); encodeHeaders(buf, request); buf.writeBytes(CRLF); if (request.getContent() != null) { buf.writeBytes(request.getContent()); } - write(ctx, e.getChannel(), e.getFuture(), buf, e.getRemoteAddress()); + return buf; } /** diff --git a/src/main/java/org/jboss/netty/handler/codec/oneone/OneToOneDecoder.java b/src/main/java/org/jboss/netty/handler/codec/oneone/OneToOneDecoder.java new file mode 100644 index 0000000000..603ee6cdb8 --- /dev/null +++ b/src/main/java/org/jboss/netty/handler/codec/oneone/OneToOneDecoder.java @@ -0,0 +1,85 @@ +/* + * JBoss, Home of Professional Open Source + * + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * by the @author tags. See the COPYRIGHT.txt in the distribution for a + * full listing of individual contributors. + * + * This 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 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.netty.handler.codec.oneone; + +import static org.jboss.netty.channel.Channels.*; + +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelEvent; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.ChannelUpstreamHandler; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder; +import org.jboss.netty.handler.codec.frame.Delimiters; +import org.jboss.netty.handler.codec.frame.FrameDecoder; + +/** + * Transforms a received message into another message. Please note that this + * decoder must be used with a proper {@link FrameDecoder} such as + * {@link DelimiterBasedFrameDecoder} if you are using a stream-based transport + * such as TCP/IP. A typical decoder setup would be: + *
+ * {@link ChannelPipeline} pipeline = ...;
+ *
+ * // Decoders
+ * pipeline.addLast("frameDecoder", new {@link DelimiterBasedFrameDecoder}(80, {@link Delimiters#nulDelimiter()}));
+ * pipeline.addLast("customDecoder", new {@link OneToOneDecoder}() { ... });
+ *
+ * // Encoder
+ * pipeline.addLast("customEncoder", new {@link OneToOneEncoder}() { ... });
+ * 
+ * + * @author The Netty Project (netty-dev@lists.jboss.org) + * @author Trustin Lee (tlee@redhat.com) + * + * @version $Rev:231 $, $Date:2008-06-12 16:44:50 +0900 (목, 12 6월 2008) $ + * + * @apiviz.landmark + */ +public abstract class OneToOneDecoder implements ChannelUpstreamHandler { + + /** + * Creates a new instance with the current system character set. + */ + protected OneToOneDecoder() { + super(); + } + + public void handleUpstream( + ChannelHandlerContext ctx, ChannelEvent evt) throws Exception { + if (!(evt instanceof MessageEvent)) { + ctx.sendUpstream(evt); + return; + } + + MessageEvent e = (MessageEvent) evt; + fireMessageReceived( + ctx, e.getChannel(), + decode(ctx, e.getChannel(), e.getMessage()), + e.getRemoteAddress()); + } + + protected abstract Object decode( + ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception; +} diff --git a/src/main/java/org/jboss/netty/handler/codec/oneone/OneToOneEncoder.java b/src/main/java/org/jboss/netty/handler/codec/oneone/OneToOneEncoder.java new file mode 100644 index 0000000000..dced91e78d --- /dev/null +++ b/src/main/java/org/jboss/netty/handler/codec/oneone/OneToOneEncoder.java @@ -0,0 +1,78 @@ +/* + * JBoss, Home of Professional Open Source + * + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * by the @author tags. See the COPYRIGHT.txt in the distribution for a + * full listing of individual contributors. + * + * This 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 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.netty.handler.codec.oneone; + +import static org.jboss.netty.channel.Channels.*; + +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.ChannelDownstreamHandler; +import org.jboss.netty.channel.ChannelEvent; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelPipeline; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder; +import org.jboss.netty.handler.codec.frame.Delimiters; + +/** + * Transforms a received message into another message. A typical decoder setup + * would be: + *
+ * {@link ChannelPipeline} pipeline = ...;
+ *
+ * // Decoders
+ * pipeline.addLast("frameDecoder", new {@link DelimiterBasedFrameDecoder}(80, {@link Delimiters#nulDelimiter()}));
+ * pipeline.addLast("customDecoder", new {@link OneToOneDecoder}() { ... });
+ *
+ * // Encoder
+ * pipeline.addLast("customEncoder", new {@link OneToOneEncoder}() { ... });
+ * 
+ * + * @author The Netty Project (netty-dev@lists.jboss.org) + * @author Trustin Lee (tlee@redhat.com) + * + * @version $Rev:231 $, $Date:2008-06-12 16:44:50 +0900 (목, 12 6월 2008) $ + * + * @apiviz.landmark + */ +public abstract class OneToOneEncoder implements ChannelDownstreamHandler { + + protected OneToOneEncoder() { + super(); + } + + public void handleDownstream( + ChannelHandlerContext ctx, ChannelEvent evt) throws Exception { + if (!(evt instanceof MessageEvent)) { + ctx.sendDownstream(evt); + return; + } + + MessageEvent e = (MessageEvent) evt; + write(ctx, e.getChannel(), e.getFuture(), + encode(ctx, e.getChannel(), e.getMessage()), + e.getRemoteAddress()); + } + + protected abstract Object encode( + ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception; +} diff --git a/src/main/java/org/jboss/netty/handler/codec/oneone/package-info.java b/src/main/java/org/jboss/netty/handler/codec/oneone/package-info.java new file mode 100644 index 0000000000..f2cafac183 --- /dev/null +++ b/src/main/java/org/jboss/netty/handler/codec/oneone/package-info.java @@ -0,0 +1,28 @@ +/* + * JBoss, Home of Professional Open Source + * + * Copyright 2008, Red Hat Middleware LLC, and individual contributors + * by the @author tags. See the COPYRIGHT.txt in the distribution for a + * full listing of individual contributors. + * + * This 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 2.1 of + * the License, or (at your option) any later version. + * + * This software 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 software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +/** + * Simplistic abstract classes which help implement encoder and decoder that + * transform an object into another object and vice versa. + */ +package org.jboss.netty.handler.codec.oneone; \ No newline at end of file diff --git a/src/main/java/org/jboss/netty/handler/codec/serialization/CompatibleObjectEncoder.java b/src/main/java/org/jboss/netty/handler/codec/serialization/CompatibleObjectEncoder.java index 835dac5696..437e06b838 100644 --- a/src/main/java/org/jboss/netty/handler/codec/serialization/CompatibleObjectEncoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/serialization/CompatibleObjectEncoder.java @@ -22,8 +22,6 @@ */ package org.jboss.netty.handler.codec.serialization; -import static org.jboss.netty.channel.Channels.*; - import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; @@ -33,11 +31,10 @@ import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBufferFactory; import org.jboss.netty.buffer.ChannelBufferOutputStream; import org.jboss.netty.buffer.ChannelBuffers; -import org.jboss.netty.channel.ChannelDownstreamHandler; -import org.jboss.netty.channel.ChannelEvent; +import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipelineCoverage; -import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; /** * An encoder which serializes a Java object into a {@link ChannelBuffer} @@ -52,7 +49,7 @@ import org.jboss.netty.channel.MessageEvent; * @version $Rev:231 $, $Date:2008-06-12 16:44:50 +0900 (목, 12 6월 2008) $ */ @ChannelPipelineCoverage("one") -public class CompatibleObjectEncoder implements ChannelDownstreamHandler { +public class CompatibleObjectEncoder extends OneToOneEncoder { private final AtomicReference buffer = new AtomicReference(); @@ -93,14 +90,8 @@ public class CompatibleObjectEncoder implements ChannelDownstreamHandler { return new ObjectOutputStream(out); } - public void handleDownstream( - ChannelHandlerContext context, ChannelEvent evt) throws Exception { - if (!(evt instanceof MessageEvent)) { - context.sendDownstream(evt); - return; - } - - MessageEvent e = (MessageEvent) evt; + @Override + protected Object encode(ChannelHandlerContext context, Channel channel, Object msg) throws Exception { ChannelBuffer buffer = buffer(context); ObjectOutputStream oout = this.oout; if (resetInterval != 0) { @@ -113,11 +104,11 @@ public class CompatibleObjectEncoder implements ChannelDownstreamHandler { buffer.discardReadBytes(); } } - oout.writeObject(e.getMessage()); + oout.writeObject(msg); oout.flush(); ChannelBuffer encoded = buffer.readBytes(buffer.readableBytes()); - write(context, e.getChannel(), e.getFuture(), encoded, e.getRemoteAddress()); + return encoded; } private ChannelBuffer buffer(ChannelHandlerContext ctx) throws Exception { diff --git a/src/main/java/org/jboss/netty/handler/codec/serialization/ObjectEncoder.java b/src/main/java/org/jboss/netty/handler/codec/serialization/ObjectEncoder.java index b0daed16b9..b65c791559 100644 --- a/src/main/java/org/jboss/netty/handler/codec/serialization/ObjectEncoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/serialization/ObjectEncoder.java @@ -23,18 +23,16 @@ package org.jboss.netty.handler.codec.serialization; import static org.jboss.netty.buffer.ChannelBuffers.*; -import static org.jboss.netty.channel.Channels.*; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import org.jboss.netty.buffer.ChannelBuffer; import org.jboss.netty.buffer.ChannelBufferOutputStream; -import org.jboss.netty.channel.ChannelDownstreamHandler; -import org.jboss.netty.channel.ChannelEvent; +import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipelineCoverage; -import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; /** * An encoder which serializes a Java object into a {@link ChannelBuffer}. @@ -57,7 +55,7 @@ import org.jboss.netty.channel.MessageEvent; * @apiviz.landmark */ @ChannelPipelineCoverage("all") -public class ObjectEncoder implements ChannelDownstreamHandler { +public class ObjectEncoder extends OneToOneEncoder { private static final byte[] LENGTH_PLACEHOLDER = new byte[4]; private final int estimatedLength; @@ -88,26 +86,19 @@ public class ObjectEncoder implements ChannelDownstreamHandler { this.estimatedLength = estimatedLength; } - public void handleDownstream( - ChannelHandlerContext context, ChannelEvent evt) throws Exception { - if (!(evt instanceof MessageEvent)) { - context.sendDownstream(evt); - return; - } - - MessageEvent e = (MessageEvent) evt; + @Override + protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { ChannelBufferOutputStream bout = new ChannelBufferOutputStream(dynamicBuffer( - estimatedLength, e.getChannel().getConfig().getBufferFactory())); + estimatedLength, ctx.getChannel().getConfig().getBufferFactory())); bout.write(LENGTH_PLACEHOLDER); ObjectOutputStream oout = new CompactObjectOutputStream(bout); - oout.writeObject(e.getMessage()); + oout.writeObject(msg); oout.flush(); oout.close(); - ChannelBuffer msg = bout.buffer(); - msg.setInt(0, msg.writerIndex() - 4); - - write(context, e.getChannel(), e.getFuture(), msg, e.getRemoteAddress()); + ChannelBuffer encoded = bout.buffer(); + encoded.setInt(0, encoded.writerIndex() - 4); + return encoded; } } diff --git a/src/main/java/org/jboss/netty/handler/codec/string/StringDecoder.java b/src/main/java/org/jboss/netty/handler/codec/string/StringDecoder.java index 31ef2b12fe..4e35f31642 100644 --- a/src/main/java/org/jboss/netty/handler/codec/string/StringDecoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/string/StringDecoder.java @@ -22,20 +22,17 @@ */ package org.jboss.netty.handler.codec.string; -import static org.jboss.netty.channel.Channels.*; - import java.nio.charset.Charset; import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.ChannelEvent; +import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineCoverage; -import org.jboss.netty.channel.ChannelUpstreamHandler; -import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder; import org.jboss.netty.handler.codec.frame.Delimiters; import org.jboss.netty.handler.codec.frame.FrameDecoder; +import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; /** * Decodes a received {@link ChannelBuffer} into a {@link String}. Please @@ -70,7 +67,7 @@ import org.jboss.netty.handler.codec.frame.FrameDecoder; * @apiviz.landmark */ @ChannelPipelineCoverage("all") -public class StringDecoder implements ChannelUpstreamHandler { +public class StringDecoder extends OneToOneDecoder { private final String charsetName; @@ -102,21 +99,12 @@ public class StringDecoder implements ChannelUpstreamHandler { charsetName = charset.name(); } - public void handleUpstream( - ChannelHandlerContext context, ChannelEvent evt) throws Exception { - if (!(evt instanceof MessageEvent)) { - context.sendUpstream(evt); - return; + @Override + public Object decode( + ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { + if (!(msg instanceof ChannelBuffer)) { + return msg; } - - MessageEvent e = (MessageEvent) evt; - if (!(e.getMessage() instanceof ChannelBuffer)) { - context.sendUpstream(evt); - return; - } - - fireMessageReceived( - context, e.getChannel(), - ((ChannelBuffer) e.getMessage()).toString(charsetName)); + return ((ChannelBuffer) msg).toString(charsetName); } } diff --git a/src/main/java/org/jboss/netty/handler/codec/string/StringEncoder.java b/src/main/java/org/jboss/netty/handler/codec/string/StringEncoder.java index 6689c46d3b..e8b7febba3 100644 --- a/src/main/java/org/jboss/netty/handler/codec/string/StringEncoder.java +++ b/src/main/java/org/jboss/netty/handler/codec/string/StringEncoder.java @@ -23,19 +23,17 @@ package org.jboss.netty.handler.codec.string; import static org.jboss.netty.buffer.ChannelBuffers.*; -import static org.jboss.netty.channel.Channels.*; import java.nio.charset.Charset; import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.channel.ChannelDownstreamHandler; -import org.jboss.netty.channel.ChannelEvent; +import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineCoverage; -import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.handler.codec.frame.DelimiterBasedFrameDecoder; import org.jboss.netty.handler.codec.frame.Delimiters; +import org.jboss.netty.handler.codec.oneone.OneToOneEncoder; /** * Encodes the requested {@link String} into a {@link ChannelBuffer}. @@ -68,7 +66,7 @@ import org.jboss.netty.handler.codec.frame.Delimiters; * @apiviz.landmark */ @ChannelPipelineCoverage("all") -public class StringEncoder implements ChannelDownstreamHandler { +public class StringEncoder extends OneToOneEncoder { private final String charsetName; @@ -87,20 +85,12 @@ public class StringEncoder implements ChannelDownstreamHandler { charsetName = charset.name(); } - public void handleDownstream( - ChannelHandlerContext context, ChannelEvent evt) throws Exception { - if (!(evt instanceof MessageEvent)) { - context.sendDownstream(evt); - return; + @Override + protected Object encode( + ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { + if (!(msg instanceof String)) { + return msg; } - - MessageEvent e = (MessageEvent) evt; - if (!(e.getMessage() instanceof String)) { - context.sendDownstream(evt); - return; - } - - write(context, e.getChannel(), e.getFuture(), - copiedBuffer(String.valueOf(e.getMessage()), charsetName)); + return copiedBuffer(String.valueOf(msg), charsetName); } }