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");
|
outboundMsgMatcher = TypeParameterMatcher.find(this, ByteToMessageCodec.class, "I");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ByteToMessageCodec(Class<? extends I> outboundMessageType) {
|
||||||
|
outboundMsgMatcher = TypeParameterMatcher.get(outboundMessageType);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeAdd(ChannelHandlerContext ctx) throws Exception {
|
public void beforeAdd(ChannelHandlerContext ctx) throws Exception {
|
||||||
decoder.beforeAdd(ctx);
|
decoder.beforeAdd(ctx);
|
||||||
|
|
|
@ -40,6 +40,12 @@ import io.netty.channel.ChannelOutboundMessageHandlerAdapter;
|
||||||
*/
|
*/
|
||||||
public abstract class MessageToByteEncoder<I> extends ChannelOutboundMessageHandlerAdapter<I> {
|
public abstract class MessageToByteEncoder<I> extends ChannelOutboundMessageHandlerAdapter<I> {
|
||||||
|
|
||||||
|
protected MessageToByteEncoder() { }
|
||||||
|
|
||||||
|
protected MessageToByteEncoder(Class<? extends I> outboundMessageType) {
|
||||||
|
super(outboundMessageType);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flush(ChannelHandlerContext ctx, I msg) throws Exception {
|
public void flush(ChannelHandlerContext ctx, I msg) throws Exception {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -90,6 +90,12 @@ public abstract class MessageToMessageCodec<INBOUND_IN, OUTBOUND_IN>
|
||||||
outboundMsgMatcher = TypeParameterMatcher.find(this, MessageToMessageCodec.class, "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
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public MessageBuf<INBOUND_IN> newInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
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> {
|
public abstract class MessageToMessageDecoder<I> extends ChannelInboundMessageHandlerAdapter<I> {
|
||||||
|
|
||||||
|
protected MessageToMessageDecoder() { }
|
||||||
|
|
||||||
|
protected MessageToMessageDecoder(Class<? extends I> inboundMessageType) {
|
||||||
|
super(inboundMessageType);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void messageReceived(ChannelHandlerContext ctx, I msg) throws Exception {
|
public final void messageReceived(ChannelHandlerContext ctx, I msg) throws Exception {
|
||||||
ctx.nextInboundMessageBuffer().unfoldAndAdd(decode(ctx, msg));
|
ctx.nextInboundMessageBuffer().unfoldAndAdd(decode(ctx, msg));
|
||||||
|
|
|
@ -42,6 +42,12 @@ import io.netty.channel.ChannelOutboundMessageHandlerAdapter;
|
||||||
*/
|
*/
|
||||||
public abstract class MessageToMessageEncoder<I> extends ChannelOutboundMessageHandlerAdapter<I> {
|
public abstract class MessageToMessageEncoder<I> extends ChannelOutboundMessageHandlerAdapter<I> {
|
||||||
|
|
||||||
|
protected MessageToMessageEncoder() { }
|
||||||
|
|
||||||
|
protected MessageToMessageEncoder(Class<? extends I> outboundMessageType) {
|
||||||
|
super(outboundMessageType);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void flush(ChannelHandlerContext ctx, I msg) throws Exception {
|
public final void flush(ChannelHandlerContext ctx, I msg) throws Exception {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -30,7 +30,45 @@ public abstract class TypeParameterMatcher {
|
||||||
private static final TypeParameterMatcher NOOP = new NoOpTypeParameterMatcher();
|
private static final TypeParameterMatcher NOOP = new NoOpTypeParameterMatcher();
|
||||||
private static final Object TEST_OBJECT = new Object();
|
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>>>() {
|
new ThreadLocal<Map<Class<?>, Map<String, TypeParameterMatcher>>>() {
|
||||||
@Override
|
@Override
|
||||||
protected Map<Class<?>, Map<String, TypeParameterMatcher>> initialValue() {
|
protected Map<Class<?>, Map<String, TypeParameterMatcher>> initialValue() {
|
||||||
|
@ -41,37 +79,18 @@ public abstract class TypeParameterMatcher {
|
||||||
public static TypeParameterMatcher find(
|
public static TypeParameterMatcher find(
|
||||||
final Object object, final Class<?> parameterizedSuperclass, final String typeParamName) {
|
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();
|
final Class<?> thisClass = object.getClass();
|
||||||
|
|
||||||
Map<String, TypeParameterMatcher> map = typeMap.get(thisClass);
|
Map<String, TypeParameterMatcher> map = findCache.get(thisClass);
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
map = new HashMap<String, TypeParameterMatcher>();
|
map = new HashMap<String, TypeParameterMatcher>();
|
||||||
typeMap.put(thisClass, map);
|
findCache.put(thisClass, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeParameterMatcher matcher = map.get(typeParamName);
|
TypeParameterMatcher matcher = map.get(typeParamName);
|
||||||
if (matcher == null) {
|
if (matcher == null) {
|
||||||
Class<?> messageType = find0(object, parameterizedSuperclass, typeParamName);
|
matcher = get(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
map.put(typeParamName, matcher);
|
map.put(typeParamName, matcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,10 @@ public abstract class ChannelInboundMessageHandlerAdapter<I>
|
||||||
msgMatcher = TypeParameterMatcher.find(this, ChannelInboundMessageHandlerAdapter.class, "I");
|
msgMatcher = TypeParameterMatcher.find(this, ChannelInboundMessageHandlerAdapter.class, "I");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ChannelInboundMessageHandlerAdapter(Class<? extends I> inboundMessageType) {
|
||||||
|
msgMatcher = TypeParameterMatcher.get(inboundMessageType);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MessageBuf<I> newInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
public MessageBuf<I> newInboundBuffer(ChannelHandlerContext ctx) throws Exception {
|
||||||
return Unpooled.messageBuffer();
|
return Unpooled.messageBuffer();
|
||||||
|
|
|
@ -47,6 +47,10 @@ public abstract class ChannelOutboundMessageHandlerAdapter<I>
|
||||||
msgMatcher = TypeParameterMatcher.find(this, ChannelOutboundMessageHandlerAdapter.class, "I");
|
msgMatcher = TypeParameterMatcher.find(this, ChannelOutboundMessageHandlerAdapter.class, "I");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected ChannelOutboundMessageHandlerAdapter(Class<? extends I> outboundMessageType) {
|
||||||
|
msgMatcher = TypeParameterMatcher.get(outboundMessageType);
|
||||||
|
}
|
||||||
|
|
||||||
protected final boolean isCloseOnFailedFlush() {
|
protected final boolean isCloseOnFailedFlush() {
|
||||||
return closeOnFailedFlush;
|
return closeOnFailedFlush;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user