More robust type parameter detection
- Also removed unnecessary constructors which were added due to incomplete type parameter detection logic
This commit is contained in:
parent
d0a3c2d95e
commit
53c27ef5ae
@ -53,14 +53,7 @@ public abstract class ByteToMessageCodec<I> extends ChannelDuplexHandler
|
|||||||
};
|
};
|
||||||
|
|
||||||
protected ByteToMessageCodec() {
|
protected ByteToMessageCodec() {
|
||||||
this(ByteToMessageCodec.class, 0);
|
outboundMsgMatcher = TypeParameterMatcher.find(this, ByteToMessageCodec.class, "I");
|
||||||
}
|
|
||||||
|
|
||||||
protected ByteToMessageCodec(
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
Class<? extends ByteToMessageCodec> parameterizedHandlerType,
|
|
||||||
int messageTypeParamIndex) {
|
|
||||||
outboundMsgMatcher = TypeParameterMatcher.find(this, parameterizedHandlerType, messageTypeParamIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -18,9 +18,7 @@ package io.netty.handler.codec;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.MessageBuf;
|
import io.netty.buffer.MessageBuf;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelOutboundMessageHandler;
|
|
||||||
import io.netty.channel.ChannelOutboundMessageHandlerAdapter;
|
import io.netty.channel.ChannelOutboundMessageHandlerAdapter;
|
||||||
import io.netty.channel.ChannelPipeline;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,21 +40,6 @@ import io.netty.channel.ChannelPipeline;
|
|||||||
*/
|
*/
|
||||||
public abstract class MessageToByteEncoder<I> extends ChannelOutboundMessageHandlerAdapter<I> {
|
public abstract class MessageToByteEncoder<I> extends ChannelOutboundMessageHandlerAdapter<I> {
|
||||||
|
|
||||||
/**
|
|
||||||
* The types which will be accepted by the encoder. If a received message is an other type it will be just forwared
|
|
||||||
* to the next {@link ChannelOutboundMessageHandler} in the {@link ChannelPipeline}
|
|
||||||
*/
|
|
||||||
protected MessageToByteEncoder() {
|
|
||||||
this(MessageToByteEncoder.class, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected MessageToByteEncoder(
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
Class<? extends MessageToByteEncoder> parameterizedHandlerType,
|
|
||||||
int messageTypeParamIndex) {
|
|
||||||
super(parameterizedHandlerType, messageTypeParamIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void flush(ChannelHandlerContext ctx, I msg) throws Exception {
|
protected void flush(ChannelHandlerContext ctx, I msg) throws Exception {
|
||||||
try {
|
try {
|
||||||
|
@ -19,9 +19,7 @@ import io.netty.buffer.MessageBuf;
|
|||||||
import io.netty.channel.ChannelDuplexHandler;
|
import io.netty.channel.ChannelDuplexHandler;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundMessageHandler;
|
import io.netty.channel.ChannelInboundMessageHandler;
|
||||||
import io.netty.channel.ChannelInboundMessageHandlerAdapter;
|
|
||||||
import io.netty.channel.ChannelOutboundMessageHandler;
|
import io.netty.channel.ChannelOutboundMessageHandler;
|
||||||
import io.netty.channel.ChannelOutboundMessageHandlerAdapter;
|
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.util.internal.TypeParameterMatcher;
|
import io.netty.util.internal.TypeParameterMatcher;
|
||||||
|
|
||||||
@ -88,22 +86,8 @@ public abstract class MessageToMessageCodec<INBOUND_IN, OUTBOUND_IN>
|
|||||||
private final TypeParameterMatcher outboundMsgMatcher;
|
private final TypeParameterMatcher outboundMsgMatcher;
|
||||||
|
|
||||||
protected MessageToMessageCodec() {
|
protected MessageToMessageCodec() {
|
||||||
inboundMsgMatcher = TypeParameterMatcher.find(this, MessageToMessageCodec.class, 0);
|
inboundMsgMatcher = TypeParameterMatcher.find(this, MessageToMessageCodec.class, "INBOUND_IN");
|
||||||
outboundMsgMatcher = TypeParameterMatcher.find(this, MessageToMessageCodec.class, 1);
|
outboundMsgMatcher = TypeParameterMatcher.find(this, MessageToMessageCodec.class, "OUTBOUND_IN");
|
||||||
}
|
|
||||||
|
|
||||||
protected MessageToMessageCodec(
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
Class<? extends ChannelInboundMessageHandlerAdapter> parameterizedInboundHandlerType,
|
|
||||||
int inboundMessageTypeParamIndex,
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
Class<? extends ChannelOutboundMessageHandlerAdapter> parameterizedOutboundHandlerType,
|
|
||||||
int outboundMessageTypeParamIndex) {
|
|
||||||
|
|
||||||
inboundMsgMatcher = TypeParameterMatcher.find(
|
|
||||||
this, parameterizedInboundHandlerType, inboundMessageTypeParamIndex);
|
|
||||||
outboundMsgMatcher = TypeParameterMatcher.find(
|
|
||||||
this, parameterizedOutboundHandlerType, outboundMessageTypeParamIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -44,17 +44,6 @@ import io.netty.channel.ChannelInboundMessageHandlerAdapter;
|
|||||||
*/
|
*/
|
||||||
public abstract class MessageToMessageDecoder<I> extends ChannelInboundMessageHandlerAdapter<I> {
|
public abstract class MessageToMessageDecoder<I> extends ChannelInboundMessageHandlerAdapter<I> {
|
||||||
|
|
||||||
protected MessageToMessageDecoder() {
|
|
||||||
super(MessageToMessageDecoder.class, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected MessageToMessageDecoder(
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
Class<? extends ChannelInboundMessageHandlerAdapter> parameterizedHandlerType,
|
|
||||||
int messageTypeParamIndex) {
|
|
||||||
super(parameterizedHandlerType, messageTypeParamIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final void messageReceived(ChannelHandlerContext ctx, I msg) throws Exception {
|
protected final void messageReceived(ChannelHandlerContext ctx, I msg) throws Exception {
|
||||||
ctx.nextInboundMessageBuffer().unfoldAndAdd(decode(ctx, msg));
|
ctx.nextInboundMessageBuffer().unfoldAndAdd(decode(ctx, msg));
|
||||||
|
@ -17,9 +17,7 @@ package io.netty.handler.codec;
|
|||||||
|
|
||||||
import io.netty.buffer.MessageBuf;
|
import io.netty.buffer.MessageBuf;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelOutboundMessageHandler;
|
|
||||||
import io.netty.channel.ChannelOutboundMessageHandlerAdapter;
|
import io.netty.channel.ChannelOutboundMessageHandlerAdapter;
|
||||||
import io.netty.channel.ChannelPipeline;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ChannelOutboundMessageHandlerAdapter} which encodes from one message to an other message
|
* {@link ChannelOutboundMessageHandlerAdapter} which encodes from one message to an other message
|
||||||
@ -44,22 +42,6 @@ import io.netty.channel.ChannelPipeline;
|
|||||||
*/
|
*/
|
||||||
public abstract class MessageToMessageEncoder<I> extends ChannelOutboundMessageHandlerAdapter<I> {
|
public abstract class MessageToMessageEncoder<I> extends ChannelOutboundMessageHandlerAdapter<I> {
|
||||||
|
|
||||||
/**
|
|
||||||
* The types which will be accepted by the decoder. If a received message is an other type it will be just forwared
|
|
||||||
* to the next {@link ChannelOutboundMessageHandler} in the {@link ChannelPipeline}
|
|
||||||
*/
|
|
||||||
protected MessageToMessageEncoder() {
|
|
||||||
super(MessageToMessageEncoder.class, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected MessageToMessageEncoder(
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
Class<? extends ChannelOutboundMessageHandlerAdapter> parameterizedHandlerType,
|
|
||||||
int messageTypeParamIndex) {
|
|
||||||
|
|
||||||
super(parameterizedHandlerType, messageTypeParamIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final void flush(ChannelHandlerContext ctx, I msg) throws Exception {
|
protected final void flush(ChannelHandlerContext ctx, I msg) throws Exception {
|
||||||
try {
|
try {
|
||||||
|
@ -16,80 +16,113 @@
|
|||||||
|
|
||||||
package io.netty.util.internal;
|
package io.netty.util.internal;
|
||||||
|
|
||||||
|
import java.lang.reflect.GenericDeclaration;
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.ArrayList;
|
import java.lang.reflect.TypeVariable;
|
||||||
import java.util.Collections;
|
import java.util.HashMap;
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public abstract class TypeParameterMatcher {
|
public abstract class TypeParameterMatcher {
|
||||||
|
|
||||||
private static final TypeParameterMatcher NOOP = new NoOpTypeParameterMatcher();
|
private static final TypeParameterMatcher NOOP = new NoOpTypeParameterMatcher();
|
||||||
|
|
||||||
private static final ThreadLocal<Map<Class<?>, TypeParameterMatcher>> typeMap =
|
private static final ThreadLocal<Map<Class<?>, Map<String, TypeParameterMatcher>>> typeMap =
|
||||||
new ThreadLocal<Map<Class<?>, TypeParameterMatcher>>() {
|
new ThreadLocal<Map<Class<?>, Map<String, TypeParameterMatcher>>>() {
|
||||||
@Override
|
@Override
|
||||||
protected Map<Class<?>, TypeParameterMatcher> initialValue() {
|
protected Map<Class<?>, Map<String, TypeParameterMatcher>> initialValue() {
|
||||||
return new IdentityHashMap<Class<?>, TypeParameterMatcher>();
|
return new IdentityHashMap<Class<?>, Map<String, TypeParameterMatcher>>();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static TypeParameterMatcher find(
|
public static TypeParameterMatcher find(
|
||||||
final Object object, final Class<?> parameterizedSuperClass, final int typeParamIndex) {
|
final Object object, final GenericDeclaration parameterizedSuperclass, final String typeParamName) {
|
||||||
|
|
||||||
final Map<Class<?>, TypeParameterMatcher> typeMap = TypeParameterMatcher.typeMap.get();
|
final Map<Class<?>, Map<String, TypeParameterMatcher>> typeMap = TypeParameterMatcher.typeMap.get();
|
||||||
final Class<?> thisClass = object.getClass();
|
final Class<?> thisClass = object.getClass();
|
||||||
|
|
||||||
TypeParameterMatcher matcher = typeMap.get(thisClass);
|
Map<String, TypeParameterMatcher> map = typeMap.get(thisClass);
|
||||||
|
if (map == null) {
|
||||||
|
map = new HashMap<String, TypeParameterMatcher>();
|
||||||
|
typeMap.put(thisClass, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeParameterMatcher matcher = map.get(typeParamName);
|
||||||
if (matcher == null) {
|
if (matcher == null) {
|
||||||
Class<?> currentClass = thisClass;
|
Class<?> messageType = find0(object, parameterizedSuperclass, typeParamName);
|
||||||
for (;;) {
|
if (messageType == Object.class) {
|
||||||
if (currentClass.getSuperclass() == parameterizedSuperClass) {
|
matcher = NOOP;
|
||||||
Type[] types = ((ParameterizedType) currentClass.getGenericSuperclass()).getActualTypeArguments();
|
} else if (PlatformDependent.hasJavassist()) {
|
||||||
if (types.length - 1 < typeParamIndex) {
|
try {
|
||||||
List<Type> typeList = new ArrayList<Type>(types.length);
|
matcher = JavassistTypeParameterMatcherGenerator.generate(messageType);
|
||||||
Collections.addAll(typeList, types);
|
} catch (Exception e) {
|
||||||
throw new IllegalStateException(
|
// Will not usually happen, but just in case.
|
||||||
"invalid typeParamIndex: " + typeParamIndex + " (typeParams: " + typeList + ')');
|
matcher = new ReflectiveMatcher(messageType);
|
||||||
}
|
|
||||||
|
|
||||||
Type t = types[typeParamIndex];
|
|
||||||
Class<?> messageType;
|
|
||||||
if (t instanceof Class) {
|
|
||||||
messageType = (Class<?>) t;
|
|
||||||
} else if (t instanceof ParameterizedType) {
|
|
||||||
messageType = (Class<?>) ((ParameterizedType) t).getRawType();
|
|
||||||
} else {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"cannot determine the type of the type parameter of " +
|
|
||||||
thisClass.getSimpleName() + ": " + t);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (messageType == Object.class) {
|
|
||||||
matcher = NOOP;
|
|
||||||
} else if (PlatformDependent.hasJavassist()) {
|
|
||||||
try {
|
|
||||||
matcher = JavassistTypeParameterMatcherGenerator.generate(messageType);
|
|
||||||
} catch (Exception e) {
|
|
||||||
// Will not usually happen, but just in case.
|
|
||||||
matcher = new ReflectiveMatcher(messageType);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
matcher = new ReflectiveMatcher(messageType);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
currentClass = currentClass.getSuperclass();
|
} else {
|
||||||
|
matcher = new ReflectiveMatcher(messageType);
|
||||||
}
|
}
|
||||||
|
map.put(typeParamName, matcher);
|
||||||
typeMap.put(thisClass, matcher);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return matcher;
|
return matcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Class<?> find0(
|
||||||
|
final Object object, GenericDeclaration parameterizedSuperclass, String typeParamName) {
|
||||||
|
|
||||||
|
final Class<?> thisClass = object.getClass();
|
||||||
|
Class<?> currentClass = thisClass;
|
||||||
|
for (;;) {
|
||||||
|
if (currentClass.getSuperclass() == parameterizedSuperclass) {
|
||||||
|
int typeParamIndex = -1;
|
||||||
|
TypeVariable<?>[] typeParams = currentClass.getSuperclass().getTypeParameters();
|
||||||
|
for (int i = 0; i < typeParams.length; i ++) {
|
||||||
|
if (typeParamName.equals(typeParams[i].getName())) {
|
||||||
|
typeParamIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeParamIndex < 0) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"unknown type parameter '" + typeParamName + "': " + parameterizedSuperclass);
|
||||||
|
}
|
||||||
|
|
||||||
|
Type[] actualTypeParams =
|
||||||
|
((ParameterizedType) currentClass.getGenericSuperclass()).getActualTypeArguments();
|
||||||
|
|
||||||
|
Type actualTypeParam = actualTypeParams[typeParamIndex];
|
||||||
|
if (actualTypeParam instanceof Class) {
|
||||||
|
return (Class<?>) actualTypeParam;
|
||||||
|
}
|
||||||
|
if (actualTypeParam instanceof ParameterizedType) {
|
||||||
|
return (Class<?>) ((ParameterizedType) actualTypeParam).getRawType();
|
||||||
|
}
|
||||||
|
if (actualTypeParam instanceof TypeVariable) {
|
||||||
|
// Resolved type parameter points to another type parameter.
|
||||||
|
TypeVariable<?> v = (TypeVariable<?>) actualTypeParam;
|
||||||
|
currentClass = thisClass;
|
||||||
|
parameterizedSuperclass = v.getGenericDeclaration();
|
||||||
|
typeParamName = v.getName();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fail(thisClass, typeParamName);
|
||||||
|
}
|
||||||
|
currentClass = currentClass.getSuperclass();
|
||||||
|
if (currentClass == null) {
|
||||||
|
return fail(thisClass, typeParamName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Class<?> fail(Class<?> type, String typeParamName) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"cannot determine the type of the type parameter '" + typeParamName + "': " + type);
|
||||||
|
}
|
||||||
|
|
||||||
public abstract boolean match(Object msg);
|
public abstract boolean match(Object msg);
|
||||||
|
|
||||||
private static final class ReflectiveMatcher extends TypeParameterMatcher {
|
private static final class ReflectiveMatcher extends TypeParameterMatcher {
|
||||||
|
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2013 The Netty Project
|
||||||
|
*
|
||||||
|
* The Netty Project licenses this file to you under the Apache License,
|
||||||
|
* version 2.0 (the "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at:
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.netty.util.internal;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class TypeParameterMatcherTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimple() throws Exception {
|
||||||
|
Object o = new TypeQ();
|
||||||
|
|
||||||
|
TypeParameterMatcher m;
|
||||||
|
|
||||||
|
m = TypeParameterMatcher.find(o, TypeX.class, "A");
|
||||||
|
assertFalse(m.match(new Object()));
|
||||||
|
assertFalse(m.match(new A()));
|
||||||
|
assertFalse(m.match(new AA()));
|
||||||
|
assertTrue(m.match(new AAA()));
|
||||||
|
assertFalse(m.match(new B()));
|
||||||
|
assertFalse(m.match(new BB()));
|
||||||
|
assertFalse(m.match(new BBB()));
|
||||||
|
assertFalse(m.match(new C()));
|
||||||
|
assertFalse(m.match(new CC()));
|
||||||
|
|
||||||
|
try {
|
||||||
|
TypeParameterMatcher.find(o, TypeX.class, "B");
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
|
||||||
|
m = TypeParameterMatcher.find(new TypeQ<BBB>() { }, TypeX.class, "B");
|
||||||
|
assertFalse(m.match(new Object()));
|
||||||
|
assertFalse(m.match(new A()));
|
||||||
|
assertFalse(m.match(new AA()));
|
||||||
|
assertFalse(m.match(new AAA()));
|
||||||
|
assertFalse(m.match(new B()));
|
||||||
|
assertFalse(m.match(new BB()));
|
||||||
|
assertTrue(m.match(new BBB()));
|
||||||
|
assertFalse(m.match(new C()));
|
||||||
|
assertFalse(m.match(new CC()));
|
||||||
|
|
||||||
|
m = TypeParameterMatcher.find(o, TypeX.class, "C");
|
||||||
|
assertFalse(m.match(new Object()));
|
||||||
|
assertFalse(m.match(new A()));
|
||||||
|
assertFalse(m.match(new AA()));
|
||||||
|
assertFalse(m.match(new AAA()));
|
||||||
|
assertFalse(m.match(new B()));
|
||||||
|
assertFalse(m.match(new BB()));
|
||||||
|
assertFalse(m.match(new BBB()));
|
||||||
|
assertFalse(m.match(new C()));
|
||||||
|
assertTrue(m.match(new CC()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TypeX<A, B, C> {
|
||||||
|
A a;
|
||||||
|
B b;
|
||||||
|
C c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TypeY<D extends C, E extends A, F extends B> extends TypeX<E, F, D> { }
|
||||||
|
|
||||||
|
public static class TypeZ<G extends AA, H extends BB> extends TypeY<CC, G, H> { }
|
||||||
|
|
||||||
|
public static class TypeQ<I extends BBB> extends TypeZ<AAA, I> { }
|
||||||
|
|
||||||
|
@SuppressWarnings("ClassMayBeInterface")
|
||||||
|
public static class A { }
|
||||||
|
public static class AA extends A { }
|
||||||
|
public static class AAA extends AA { }
|
||||||
|
|
||||||
|
@SuppressWarnings("ClassMayBeInterface")
|
||||||
|
public static class B { }
|
||||||
|
public static class BB extends B { }
|
||||||
|
public static class BBB extends BB { }
|
||||||
|
|
||||||
|
@SuppressWarnings("ClassMayBeInterface")
|
||||||
|
public static class C { }
|
||||||
|
public static class CC extends C { }
|
||||||
|
}
|
@ -54,14 +54,7 @@ public abstract class ChannelInboundMessageHandlerAdapter<I>
|
|||||||
private final TypeParameterMatcher msgMatcher;
|
private final TypeParameterMatcher msgMatcher;
|
||||||
|
|
||||||
protected ChannelInboundMessageHandlerAdapter() {
|
protected ChannelInboundMessageHandlerAdapter() {
|
||||||
this(ChannelInboundMessageHandlerAdapter.class, 0);
|
msgMatcher = TypeParameterMatcher.find(this, ChannelInboundMessageHandlerAdapter.class, "I");
|
||||||
}
|
|
||||||
|
|
||||||
protected ChannelInboundMessageHandlerAdapter(
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
Class<? extends ChannelInboundMessageHandlerAdapter> parameterizedHandlerType,
|
|
||||||
int messageTypeParamIndex) {
|
|
||||||
msgMatcher = TypeParameterMatcher.find(this, parameterizedHandlerType, messageTypeParamIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -39,14 +39,7 @@ public abstract class ChannelOutboundMessageHandlerAdapter<I>
|
|||||||
private boolean closeOnFailedFlush = true;
|
private boolean closeOnFailedFlush = true;
|
||||||
|
|
||||||
protected ChannelOutboundMessageHandlerAdapter() {
|
protected ChannelOutboundMessageHandlerAdapter() {
|
||||||
this(ChannelOutboundMessageHandlerAdapter.class, 0);
|
msgMatcher = TypeParameterMatcher.find(this, ChannelOutboundMessageHandlerAdapter.class, "I");
|
||||||
}
|
|
||||||
|
|
||||||
protected ChannelOutboundMessageHandlerAdapter(
|
|
||||||
@SuppressWarnings("rawtypes")
|
|
||||||
Class<? extends ChannelOutboundMessageHandlerAdapter> parameterizedHandlerType,
|
|
||||||
int messageTypeParamIndex) {
|
|
||||||
msgMatcher = TypeParameterMatcher.find(this, parameterizedHandlerType, messageTypeParamIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final boolean isCloseOnFailedFlush() {
|
protected final boolean isCloseOnFailedFlush() {
|
||||||
|
Loading…
Reference in New Issue
Block a user