Add constructor parameters that do not perform type parameter auto-detection for the languages without type parameters
- Fixes #1177 - Add TypeParameterMatcher.get(parameterType) - Add alternative constructors
This commit is contained in:
parent
2b014ce82a
commit
8b722d29a7
@ -56,6 +56,10 @@ public abstract class ByteToMessageCodec<I> extends ChannelDuplexHandler
|
||||
outboundMsgMatcher = TypeParameterMatcher.find(this, ByteToMessageCodec.class, "I");
|
||||
}
|
||||
|
||||
protected ByteToMessageCodec(Class<? extends I> outboundMessageType) {
|
||||
outboundMsgMatcher = TypeParameterMatcher.get(outboundMessageType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeAdd(ChannelHandlerContext ctx) throws Exception {
|
||||
decoder.beforeAdd(ctx);
|
||||
|
@ -40,6 +40,12 @@ import io.netty.channel.ChannelOutboundMessageHandlerAdapter;
|
||||
*/
|
||||
public abstract class MessageToByteEncoder<I> extends ChannelOutboundMessageHandlerAdapter<I> {
|
||||
|
||||
protected MessageToByteEncoder() { }
|
||||
|
||||
protected MessageToByteEncoder(Class<? extends I> outboundMessageType) {
|
||||
super(outboundMessageType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush(ChannelHandlerContext ctx, I msg) throws Exception {
|
||||
try {
|
||||
|
@ -90,6 +90,12 @@ public abstract class MessageToMessageCodec<INBOUND_IN, OUTBOUND_IN>
|
||||
outboundMsgMatcher = TypeParameterMatcher.find(this, MessageToMessageCodec.class, "OUTBOUND_IN");
|
||||
}
|
||||
|
||||
protected MessageToMessageCodec(
|
||||
Class<? extends INBOUND_IN> inboundMessageType, Class<? extends OUTBOUND_IN> outboundMessageType) {
|
||||
inboundMsgMatcher = TypeParameterMatcher.get(inboundMessageType);
|
||||
outboundMsgMatcher = TypeParameterMatcher.get(outboundMessageType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public MessageBuf<INBOUND_IN> newInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||
|
@ -44,6 +44,12 @@ import io.netty.channel.ChannelInboundMessageHandlerAdapter;
|
||||
*/
|
||||
public abstract class MessageToMessageDecoder<I> extends ChannelInboundMessageHandlerAdapter<I> {
|
||||
|
||||
protected MessageToMessageDecoder() { }
|
||||
|
||||
protected MessageToMessageDecoder(Class<? extends I> inboundMessageType) {
|
||||
super(inboundMessageType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void messageReceived(ChannelHandlerContext ctx, I msg) throws Exception {
|
||||
ctx.nextInboundMessageBuffer().unfoldAndAdd(decode(ctx, msg));
|
||||
|
@ -42,6 +42,12 @@ import io.netty.channel.ChannelOutboundMessageHandlerAdapter;
|
||||
*/
|
||||
public abstract class MessageToMessageEncoder<I> extends ChannelOutboundMessageHandlerAdapter<I> {
|
||||
|
||||
protected MessageToMessageEncoder() { }
|
||||
|
||||
protected MessageToMessageEncoder(Class<? extends I> outboundMessageType) {
|
||||
super(outboundMessageType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void flush(ChannelHandlerContext ctx, I msg) throws Exception {
|
||||
try {
|
||||
|
@ -30,7 +30,45 @@ public abstract class TypeParameterMatcher {
|
||||
private static final TypeParameterMatcher NOOP = new NoOpTypeParameterMatcher();
|
||||
private static final Object TEST_OBJECT = new Object();
|
||||
|
||||
private static final ThreadLocal<Map<Class<?>, Map<String, TypeParameterMatcher>>> typeMap =
|
||||
private static final ThreadLocal<Map<Class<?>, TypeParameterMatcher>> getCache =
|
||||
new ThreadLocal<Map<Class<?>, TypeParameterMatcher>>() {
|
||||
@Override
|
||||
protected Map<Class<?>, TypeParameterMatcher> initialValue() {
|
||||
return new IdentityHashMap<Class<?>, TypeParameterMatcher>();
|
||||
}
|
||||
};
|
||||
|
||||
public static TypeParameterMatcher get(final Class<?> parameterType) {
|
||||
final Map<Class<?>, TypeParameterMatcher> getCache = TypeParameterMatcher.getCache.get();
|
||||
|
||||
TypeParameterMatcher matcher = getCache.get(parameterType);
|
||||
if (matcher == null) {
|
||||
if (parameterType == Object.class) {
|
||||
matcher = NOOP;
|
||||
} else if (PlatformDependent.hasJavassist()) {
|
||||
try {
|
||||
matcher = JavassistTypeParameterMatcherGenerator.generate(parameterType);
|
||||
matcher.match(TEST_OBJECT);
|
||||
} catch (IllegalAccessError e) {
|
||||
// Happens if parameterType is not public.
|
||||
matcher = null;
|
||||
} catch (Exception e) {
|
||||
// Will not usually happen, but just in case.
|
||||
matcher = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (matcher == null) {
|
||||
matcher = new ReflectiveMatcher(parameterType);
|
||||
}
|
||||
|
||||
getCache.put(parameterType, matcher);
|
||||
}
|
||||
|
||||
return matcher;
|
||||
}
|
||||
|
||||
private static final ThreadLocal<Map<Class<?>, Map<String, TypeParameterMatcher>>> findCache =
|
||||
new ThreadLocal<Map<Class<?>, Map<String, TypeParameterMatcher>>>() {
|
||||
@Override
|
||||
protected Map<Class<?>, Map<String, TypeParameterMatcher>> initialValue() {
|
||||
@ -41,37 +79,18 @@ public abstract class TypeParameterMatcher {
|
||||
public static TypeParameterMatcher find(
|
||||
final Object object, final Class<?> parameterizedSuperclass, final String typeParamName) {
|
||||
|
||||
final Map<Class<?>, Map<String, TypeParameterMatcher>> typeMap = TypeParameterMatcher.typeMap.get();
|
||||
final Map<Class<?>, Map<String, TypeParameterMatcher>> findCache = TypeParameterMatcher.findCache.get();
|
||||
final Class<?> thisClass = object.getClass();
|
||||
|
||||
Map<String, TypeParameterMatcher> map = typeMap.get(thisClass);
|
||||
Map<String, TypeParameterMatcher> map = findCache.get(thisClass);
|
||||
if (map == null) {
|
||||
map = new HashMap<String, TypeParameterMatcher>();
|
||||
typeMap.put(thisClass, map);
|
||||
findCache.put(thisClass, map);
|
||||
}
|
||||
|
||||
TypeParameterMatcher matcher = map.get(typeParamName);
|
||||
if (matcher == null) {
|
||||
Class<?> messageType = find0(object, parameterizedSuperclass, typeParamName);
|
||||
if (messageType == Object.class) {
|
||||
matcher = NOOP;
|
||||
} else if (PlatformDependent.hasJavassist()) {
|
||||
try {
|
||||
matcher = JavassistTypeParameterMatcherGenerator.generate(messageType);
|
||||
matcher.match(TEST_OBJECT);
|
||||
} catch (IllegalAccessError e) {
|
||||
// Happens if messageType is not public.
|
||||
matcher = null;
|
||||
} catch (Exception e) {
|
||||
// Will not usually happen, but just in case.
|
||||
matcher = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (matcher == null) {
|
||||
matcher = new ReflectiveMatcher(messageType);
|
||||
}
|
||||
|
||||
matcher = get(find0(object, parameterizedSuperclass, typeParamName));
|
||||
map.put(typeParamName, matcher);
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,10 @@ public abstract class ChannelInboundMessageHandlerAdapter<I>
|
||||
msgMatcher = TypeParameterMatcher.find(this, ChannelInboundMessageHandlerAdapter.class, "I");
|
||||
}
|
||||
|
||||
protected ChannelInboundMessageHandlerAdapter(Class<? extends I> inboundMessageType) {
|
||||
msgMatcher = TypeParameterMatcher.get(inboundMessageType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageBuf<I> newInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||
return Unpooled.messageBuffer();
|
||||
|
@ -47,6 +47,10 @@ public abstract class ChannelOutboundMessageHandlerAdapter<I>
|
||||
msgMatcher = TypeParameterMatcher.find(this, ChannelOutboundMessageHandlerAdapter.class, "I");
|
||||
}
|
||||
|
||||
protected ChannelOutboundMessageHandlerAdapter(Class<? extends I> outboundMessageType) {
|
||||
msgMatcher = TypeParameterMatcher.get(outboundMessageType);
|
||||
}
|
||||
|
||||
protected final boolean isCloseOnFailedFlush() {
|
||||
return closeOnFailedFlush;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user