[#624] Add varargs constructor to MessageToByteEncoder, MessageToMessage(Encoder|Decoder|Codec) to implement default isEncodable/isDecodable()

.. and modify all their subtypes to take advantage of this improvement.
This commit is contained in:
Trustin Lee 2012-09-23 17:01:31 +09:00
parent 0f0479547d
commit a156f67804
28 changed files with 123 additions and 120 deletions

View File

@ -66,6 +66,8 @@ public class HttpChunkAggregator extends MessageToMessageDecoder<Object, HttpMes
* a {@link TooLongFrameException} will be raised.
*/
public HttpChunkAggregator(int maxContentLength) {
super(HttpMessage.class, HttpChunk.class);
if (maxContentLength <= 0) {
throw new IllegalArgumentException(
"maxContentLength must be a positive integer: " +
@ -106,11 +108,6 @@ public class HttpChunkAggregator extends MessageToMessageDecoder<Object, HttpMes
}
}
@Override
public boolean isDecodable(Object msg) throws Exception {
return msg instanceof HttpMessage || msg instanceof HttpChunk;
}
@Override
public HttpMessage decode(ChannelHandlerContext ctx, Object msg) throws Exception {
HttpMessage currentMessage = this.currentMessage;

View File

@ -48,11 +48,7 @@ public abstract class HttpContentDecoder extends MessageToMessageDecoder<Object,
* Creates a new instance.
*/
protected HttpContentDecoder() {
}
@Override
public boolean isDecodable(Object msg) throws Exception {
return msg instanceof HttpMessage || msg instanceof HttpChunk;
super(HttpMessage.class, HttpChunk.class);
}
@Override

View File

@ -55,11 +55,9 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec<HttpMessa
* Creates a new instance.
*/
protected HttpContentEncoder() {
}
@Override
public boolean isDecodable(Object msg) throws Exception {
return msg instanceof HttpMessage;
super(
new Class<?>[] { HttpMessage.class },
new Class<?>[] { HttpMessage.class, HttpChunk.class });
}
@Override
@ -74,11 +72,6 @@ public abstract class HttpContentEncoder extends MessageToMessageCodec<HttpMessa
return msg;
}
@Override
public boolean isEncodable(Object msg) throws Exception {
return msg instanceof HttpMessage || msg instanceof HttpChunk;
}
@Override
public Object encode(ChannelHandlerContext ctx, Object msg)
throws Exception {

View File

@ -50,11 +50,7 @@ public abstract class HttpMessageEncoder extends MessageToByteEncoder<Object> {
* Creates a new instance.
*/
protected HttpMessageEncoder() {
}
@Override
public boolean isEncodable(Object msg) throws Exception {
return msg instanceof HttpMessage || msg instanceof HttpChunk;
super(HttpMessage.class, HttpChunk.class);
}
@Override

View File

@ -32,9 +32,8 @@ import io.netty.handler.codec.MessageToByteEncoder;
@Sharable
public class WebSocket00FrameEncoder extends MessageToByteEncoder<WebSocketFrame> {
@Override
public boolean isEncodable(Object msg) throws Exception {
return msg instanceof WebSocketFrame;
public WebSocket00FrameEncoder() {
super(WebSocketFrame.class);
}
@Override

View File

@ -90,17 +90,14 @@ public class WebSocket08FrameEncoder extends MessageToByteEncoder<WebSocketFrame
* false.
*/
public WebSocket08FrameEncoder(boolean maskPayload) {
super(WebSocketFrame.class);
this.maskPayload = maskPayload;
}
@Override
public boolean isEncodable(Object msg) throws Exception {
return msg instanceof WebSocketFrame;
}
public void encode(
ChannelHandlerContext ctx, WebSocketFrame msg, ByteBuf out) throws Exception {
@Override
public void encode(ChannelHandlerContext ctx,
WebSocketFrame msg, ByteBuf out) throws Exception {
byte[] mask;
ByteBuf data = msg.getBinaryData();

View File

@ -49,6 +49,8 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<Object> {
* Creates a new instance with the specified parameters.
*/
public SpdyFrameEncoder(int version, int compressionLevel, int windowBits, int memLevel) {
super(SpdyDataFrame.class, SpdyControlFrame.class);
if (version < SpdyConstants.SPDY_MIN_VERSION || version > SpdyConstants.SPDY_MAX_VERSION) {
throw new IllegalArgumentException(
"unknown version: " + version);
@ -74,11 +76,6 @@ public class SpdyFrameEncoder extends MessageToByteEncoder<Object> {
});
}
@Override
public boolean isEncodable(Object msg) throws Exception {
return msg instanceof SpdyDataFrame || msg instanceof SpdyControlFrame;
}
@Override
public void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {
if (msg instanceof SpdyDataFrame) {

View File

@ -52,6 +52,8 @@ public class SpdyHttpDecoder extends MessageToMessageDecoder<Object, HttpMessage
* a {@link TooLongFrameException} will be raised.
*/
public SpdyHttpDecoder(int version, int maxContentLength) {
super(SpdyDataFrame.class, SpdyControlFrame.class);
if (version < SpdyConstants.SPDY_MIN_VERSION || version > SpdyConstants.SPDY_MAX_VERSION) {
throw new IllegalArgumentException(
"unsupported version: " + version);

View File

@ -129,6 +129,8 @@ public class SpdyHttpEncoder extends MessageToMessageEncoder<Object, Object> {
* @param version the protocol version
*/
public SpdyHttpEncoder(int version) {
super(HttpMessage.class, HttpChunk.class);
if (version < SpdyConstants.SPDY_MIN_VERSION || version > SpdyConstants.SPDY_MAX_VERSION) {
throw new IllegalArgumentException(
"unsupported version: " + version);
@ -136,13 +138,6 @@ public class SpdyHttpEncoder extends MessageToMessageEncoder<Object, Object> {
spdyVersion = version;
}
@Override
public boolean isEncodable(Object msg) throws Exception {
return msg instanceof HttpRequest ||
msg instanceof HttpResponse ||
msg instanceof HttpChunk;
}
@Override
public Object encode(ChannelHandlerContext ctx, Object msg) throws Exception {

View File

@ -103,19 +103,7 @@ public class SpdySessionHandler
break;
}
if (msg instanceof SpdyDataFrame ||
msg instanceof SpdySynStreamFrame ||
msg instanceof SpdySynReplyFrame ||
msg instanceof SpdyRstStreamFrame ||
msg instanceof SpdySettingsFrame ||
msg instanceof SpdyPingFrame ||
msg instanceof SpdyGoAwayFrame ||
msg instanceof SpdyHeadersFrame ||
msg instanceof SpdyWindowUpdateFrame) {
handleInboundMessage(ctx, msg);
} else {
ctx.nextInboundMessageBuffer().add(msg);
}
handleInboundMessage(ctx, msg);
}
ctx.fireInboundBufferUpdated();
}

View File

@ -82,6 +82,43 @@ final class CodecUtil {
msg.getClass().getSimpleName()));
}
private static final Class<?>[] EMPTY_TYPES = new Class<?>[0];
static Class<?>[] acceptedMessageTypes(Class<?>[] acceptedMsgTypes) {
if (acceptedMsgTypes == null) {
return EMPTY_TYPES;
}
int numElem = 0;
for (Class<?> c: acceptedMsgTypes) {
if (c == null) {
break;
}
numElem ++;
}
Class<?>[] newAllowedMsgTypes = new Class[numElem];
for (int i = 0; i < numElem; i ++) {
newAllowedMsgTypes[i] = acceptedMsgTypes[i];
}
return newAllowedMsgTypes;
}
static boolean acceptMessage(Class<?>[] acceptedMsgTypes, Object msg) {
if (acceptedMsgTypes.length == 0) {
return true;
}
for (Class<?> c: acceptedMsgTypes) {
if (c.isInstance(msg)) {
return true;
}
}
return false;
}
private CodecUtil() {
// Unused
}

View File

@ -83,6 +83,8 @@ public class LengthFieldPrepender extends MessageToByteEncoder<ByteBuf> {
*/
public LengthFieldPrepender(
int lengthFieldLength, boolean lengthIncludesLengthFieldLength) {
super(ByteBuf.class);
if (lengthFieldLength != 1 && lengthFieldLength != 2 &&
lengthFieldLength != 3 && lengthFieldLength != 4 &&
lengthFieldLength != 8) {
@ -95,11 +97,6 @@ public class LengthFieldPrepender extends MessageToByteEncoder<ByteBuf> {
this.lengthIncludesLengthFieldLength = lengthIncludesLengthFieldLength;
}
@Override
public boolean isEncodable(Object msg) throws Exception {
return msg instanceof ByteBuf;
}
@Override
public void encode(
ChannelHandlerContext ctx,

View File

@ -23,6 +23,12 @@ import io.netty.channel.ChannelOutboundMessageHandlerAdapter;
public abstract class MessageToByteEncoder<I> extends ChannelOutboundMessageHandlerAdapter<I> {
private final Class<?>[] acceptedMsgTypes;
protected MessageToByteEncoder(Class<?>... acceptedMsgTypes) {
this.acceptedMsgTypes = CodecUtil.acceptedMessageTypes(acceptedMsgTypes);
}
@Override
public void flush(ChannelHandlerContext ctx, ChannelFuture future) throws Exception {
MessageBuf<I> in = ctx.outboundMessageBuffer();
@ -61,7 +67,7 @@ public abstract class MessageToByteEncoder<I> extends ChannelOutboundMessageHand
* @param msg the message
*/
public boolean isEncodable(Object msg) throws Exception {
return true;
return CodecUtil.acceptMessage(acceptedMsgTypes, msg);
}
public abstract void encode(ChannelHandlerContext ctx, I msg, ByteBuf out) throws Exception;

View File

@ -53,6 +53,19 @@ public abstract class MessageToMessageCodec<INBOUND_IN, INBOUND_OUT, OUTBOUND_IN
}
};
private final Class<?>[] acceptedInboundMsgTypes;
private final Class<?>[] acceptedOutboundMsgTypes;
protected MessageToMessageCodec() {
this(null, null);
}
protected MessageToMessageCodec(
Class<?>[] acceptedInboundMsgTypes, Class<?>[] acceptedOutboundMsgTypes) {
this.acceptedInboundMsgTypes = CodecUtil.acceptedMessageTypes(acceptedInboundMsgTypes);
this.acceptedOutboundMsgTypes = CodecUtil.acceptedMessageTypes(acceptedOutboundMsgTypes);
}
@Override
public MessageBuf<INBOUND_IN> newInboundBuffer(ChannelHandlerContext ctx) throws Exception {
return decoder.newInboundBuffer(ctx);
@ -80,7 +93,7 @@ public abstract class MessageToMessageCodec<INBOUND_IN, INBOUND_OUT, OUTBOUND_IN
* @param msg the message
*/
public boolean isDecodable(Object msg) throws Exception {
return true;
return CodecUtil.acceptMessage(acceptedInboundMsgTypes, msg);
}
/**
@ -89,7 +102,7 @@ public abstract class MessageToMessageCodec<INBOUND_IN, INBOUND_OUT, OUTBOUND_IN
* @param msg the message
*/
public boolean isEncodable(Object msg) throws Exception {
return true;
return CodecUtil.acceptMessage(acceptedOutboundMsgTypes, msg);
}
public abstract OUTBOUND_OUT encode(ChannelHandlerContext ctx, OUTBOUND_IN msg) throws Exception;

View File

@ -24,6 +24,12 @@ import io.netty.channel.ChannelInboundMessageHandler;
public abstract class MessageToMessageDecoder<I, O>
extends ChannelInboundHandlerAdapter implements ChannelInboundMessageHandler<I> {
private final Class<?>[] acceptedMsgTypes;
protected MessageToMessageDecoder(Class<?>... acceptedMsgTypes) {
this.acceptedMsgTypes = CodecUtil.acceptedMessageTypes(acceptedMsgTypes);
}
@Override
public MessageBuf<I> newInboundBuffer(ChannelHandlerContext ctx) throws Exception {
return Unpooled.messageBuffer();
@ -77,7 +83,7 @@ public abstract class MessageToMessageDecoder<I, O>
* @param msg the message
*/
public boolean isDecodable(Object msg) throws Exception {
return true;
return CodecUtil.acceptMessage(acceptedMsgTypes, msg);
}
public abstract O decode(ChannelHandlerContext ctx, I msg) throws Exception;

View File

@ -22,6 +22,12 @@ import io.netty.channel.ChannelOutboundMessageHandlerAdapter;
public abstract class MessageToMessageEncoder<I, O> extends ChannelOutboundMessageHandlerAdapter<I> {
private final Class<?>[] acceptedMsgTypes;
protected MessageToMessageEncoder(Class<?>... acceptedMsgTypes) {
this.acceptedMsgTypes = CodecUtil.acceptedMessageTypes(acceptedMsgTypes);
}
@Override
public void flush(ChannelHandlerContext ctx, ChannelFuture future) throws Exception {
MessageBuf<I> in = ctx.outboundMessageBuffer();
@ -65,7 +71,7 @@ public abstract class MessageToMessageEncoder<I, O> extends ChannelOutboundMessa
* @param msg the message
*/
public boolean isEncodable(Object msg) throws Exception {
return true;
return CodecUtil.acceptMessage(acceptedMsgTypes, msg);
}
public abstract O encode(ChannelHandlerContext ctx, I msg) throws Exception;

View File

@ -53,17 +53,14 @@ public class Base64Decoder extends MessageToMessageDecoder<ByteBuf, ByteBuf> {
}
public Base64Decoder(Base64Dialect dialect) {
super(ByteBuf.class);
if (dialect == null) {
throw new NullPointerException("dialect");
}
this.dialect = dialect;
}
@Override
public boolean isDecodable(Object msg) throws Exception {
return msg instanceof ByteBuf;
}
@Override
public ByteBuf decode(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
return Base64.decode(msg, msg.readerIndex(), msg.readableBytes(), dialect);

View File

@ -54,6 +54,8 @@ public class Base64Encoder extends MessageToMessageEncoder<ByteBuf, ByteBuf> {
}
public Base64Encoder(boolean breakLines, Base64Dialect dialect) {
super(ByteBuf.class);
if (dialect == null) {
throw new NullPointerException("dialect");
}
@ -62,11 +64,6 @@ public class Base64Encoder extends MessageToMessageEncoder<ByteBuf, ByteBuf> {
this.dialect = dialect;
}
@Override
public boolean isEncodable(Object msg) throws Exception {
return msg instanceof ByteBuf;
}
@Override
public ByteBuf encode(ChannelHandlerContext ctx,
ByteBuf msg) throws Exception {

View File

@ -49,9 +49,8 @@ import io.netty.handler.codec.MessageToMessageDecoder;
*/
public class ByteArrayDecoder extends MessageToMessageDecoder<ByteBuf, byte[]> {
@Override
public boolean isDecodable(Object msg) throws Exception {
return msg instanceof ByteBuf;
public ByteArrayDecoder() {
super(ByteBuf.class);
}
@Override

View File

@ -51,14 +51,13 @@ import io.netty.handler.codec.MessageToMessageEncoder;
*/
public class ByteArrayEncoder extends MessageToMessageEncoder<byte[], ByteBuf> {
@Override
public MessageBuf<byte[]> newOutboundBuffer(ChannelHandlerContext ctx) throws Exception {
return Unpooled.messageBuffer();
public ByteArrayEncoder() {
super(byte[].class);
}
@Override
public boolean isEncodable(Object msg) throws Exception {
return msg instanceof byte[];
public MessageBuf<byte[]> newOutboundBuffer(ChannelHandlerContext ctx) throws Exception {
return Unpooled.messageBuffer();
}
@Override

View File

@ -74,6 +74,8 @@ public class ProtobufDecoder extends MessageToMessageDecoder<ByteBuf, MessageLit
}
public ProtobufDecoder(MessageLite prototype, ExtensionRegistry extensionRegistry) {
super(ByteBuf.class);
if (prototype == null) {
throw new NullPointerException("prototype");
}
@ -81,11 +83,6 @@ public class ProtobufDecoder extends MessageToMessageDecoder<ByteBuf, MessageLit
this.extensionRegistry = extensionRegistry;
}
@Override
public boolean isDecodable(Object msg) throws Exception {
return msg instanceof ByteBuf;
}
@Override
public MessageLite decode(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
if (msg.hasArray()) {

View File

@ -59,9 +59,8 @@ import com.google.protobuf.MessageLite;
@Sharable
public class ProtobufEncoder extends MessageToMessageEncoder<Object, ByteBuf> {
@Override
public boolean isEncodable(Object msg) throws Exception {
return msg instanceof MessageLite || msg instanceof MessageLite.Builder;
public ProtobufEncoder() {
super(MessageLite.class, MessageLite.Builder.class);
}
@Override

View File

@ -44,11 +44,7 @@ public class ProtobufVarint32LengthFieldPrepender extends MessageToByteEncoder<B
* Creates a new instance.
*/
public ProtobufVarint32LengthFieldPrepender() {
}
@Override
public boolean isEncodable(Object msg) throws Exception {
return msg instanceof ByteBuf;
super(ByteBuf.class);
}
@Override

View File

@ -59,6 +59,8 @@ public class CompatibleObjectEncoder extends MessageToByteEncoder<Object> {
* the long term.
*/
public CompatibleObjectEncoder(int resetInterval) {
super(Serializable.class);
if (resetInterval < 0) {
throw new IllegalArgumentException(
"resetInterval: " + resetInterval);
@ -75,11 +77,6 @@ public class CompatibleObjectEncoder extends MessageToByteEncoder<Object> {
return new ObjectOutputStream(out);
}
@Override
public boolean isEncodable(Object msg) throws Exception {
return msg instanceof Serializable;
}
@Override
public void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {
Attribute<ObjectOutputStream> oosAttr = ctx.attr(OOS);

View File

@ -39,9 +39,8 @@ import java.io.Serializable;
public class ObjectEncoder extends MessageToByteEncoder<Object> {
private static final byte[] LENGTH_PLACEHOLDER = new byte[4];
@Override
public boolean isEncodable(Object msg) throws Exception {
return msg instanceof Serializable;
public ObjectEncoder() {
super(Serializable.class);
}
@Override

View File

@ -68,17 +68,14 @@ public class StringDecoder extends MessageToMessageDecoder<ByteBuf, String> {
* Creates a new instance with the specified character set.
*/
public StringDecoder(Charset charset) {
super(ByteBuf.class);
if (charset == null) {
throw new NullPointerException("charset");
}
this.charset = charset;
}
@Override
public boolean isDecodable(Object msg) throws Exception {
return msg instanceof ByteBuf;
}
@Override
public String decode(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
return msg.toString(charset);

View File

@ -50,7 +50,7 @@ import java.nio.charset.Charset;
* @apiviz.landmark
*/
@Sharable
public class StringEncoder extends MessageToMessageEncoder<String, ByteBuf> {
public class StringEncoder extends MessageToMessageEncoder<CharSequence, ByteBuf> {
// TODO Use CharsetEncoder instead.
private final Charset charset;
@ -66,6 +66,8 @@ public class StringEncoder extends MessageToMessageEncoder<String, ByteBuf> {
* Creates a new instance with the specified character set.
*/
public StringEncoder(Charset charset) {
super(CharSequence.class);
if (charset == null) {
throw new NullPointerException("charset");
}
@ -73,12 +75,7 @@ public class StringEncoder extends MessageToMessageEncoder<String, ByteBuf> {
}
@Override
public boolean isEncodable(Object msg) throws Exception {
return msg instanceof String;
}
@Override
public ByteBuf encode(ChannelHandlerContext ctx, String msg) throws Exception {
public ByteBuf encode(ChannelHandlerContext ctx, CharSequence msg) throws Exception {
return Unpooled.copiedBuffer(msg, charset);
}
}

View File

@ -28,6 +28,10 @@ import java.math.BigInteger;
*/
public class NumberEncoder extends MessageToByteEncoder<Number> {
public NumberEncoder() {
super(Number.class);
}
@Override
public void encode(
ChannelHandlerContext ctx, Number msg, ByteBuf out) throws Exception {