From 71136390f1dfde13eea8d3f2e1b70ffc672a1dd8 Mon Sep 17 00:00:00 2001 From: Trustin Lee Date: Fri, 8 Feb 2013 15:56:48 +0900 Subject: [PATCH] Extract type parameter finder code to a utility class --- .../util/internal/TypeParameterFinder.java | 57 +++++++++++++++++++ .../java/io/netty/handler/ssl/SslHandler.java | 2 +- .../ChannelInboundMessageHandlerAdapter.java | 37 +----------- 3 files changed, 61 insertions(+), 35 deletions(-) create mode 100644 common/src/main/java/io/netty/util/internal/TypeParameterFinder.java diff --git a/common/src/main/java/io/netty/util/internal/TypeParameterFinder.java b/common/src/main/java/io/netty/util/internal/TypeParameterFinder.java new file mode 100644 index 0000000000..3e5574e158 --- /dev/null +++ b/common/src/main/java/io/netty/util/internal/TypeParameterFinder.java @@ -0,0 +1,57 @@ +/* + * 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 java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +public final class TypeParameterFinder { + + // TODO: Use a weak key map + private static final ConcurrentMap, Class> typeMap = new ConcurrentHashMap, Class>(); + + public static Class findActualTypeParameter( + final Object object, final Class parameterizedSuperClass, final int typeParamIndex) { + final Class thisClass = object.getClass(); + Class messageType = typeMap.get(thisClass); + if (messageType == null) { + Class currentClass = thisClass; + for (;;) { + if (currentClass.getSuperclass() == parameterizedSuperClass) { + Type[] types = ((ParameterizedType) currentClass.getGenericSuperclass()).getActualTypeArguments(); + if (types.length - 1 < typeParamIndex || !(types[0] instanceof Class)) { + throw new IllegalStateException( + "cannot determine the inbound message type of " + thisClass.getSimpleName()); + } + + messageType = (Class) types[0]; + break; + } + currentClass = currentClass.getSuperclass(); + } + + typeMap.put(thisClass, messageType); + } + + return messageType; + } + + + private TypeParameterFinder() { } +} diff --git a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java index 797444d9a9..ddd3fb1f4e 100644 --- a/handler/src/main/java/io/netty/handler/ssl/SslHandler.java +++ b/handler/src/main/java/io/netty/handler/ssl/SslHandler.java @@ -1,4 +1,4 @@ -io.netty.channel.DefaultChannelPromise.setFailure/* +/* * Copyright 2012 The Netty Project * * The Netty Project licenses this file to you under the Apache License, diff --git a/transport/src/main/java/io/netty/channel/ChannelInboundMessageHandlerAdapter.java b/transport/src/main/java/io/netty/channel/ChannelInboundMessageHandlerAdapter.java index 6f5f1f9cb9..8ad0732357 100644 --- a/transport/src/main/java/io/netty/channel/ChannelInboundMessageHandlerAdapter.java +++ b/transport/src/main/java/io/netty/channel/ChannelInboundMessageHandlerAdapter.java @@ -17,11 +17,7 @@ package io.netty.channel; import io.netty.buffer.MessageBuf; import io.netty.buffer.Unpooled; - -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; +import io.netty.util.internal.TypeParameterFinder; /** * {@link ChannelHandler} which handles inbound messages of a specific type. @@ -48,9 +44,6 @@ import java.util.concurrent.ConcurrentMap; public abstract class ChannelInboundMessageHandlerAdapter extends ChannelStateHandlerAdapter implements ChannelInboundMessageHandler { - private static final ConcurrentMap, Class> messageTypeMap = - new ConcurrentHashMap, Class>(); - private final Class acceptedMsgType; protected ChannelInboundMessageHandlerAdapter() { @@ -61,32 +54,8 @@ public abstract class ChannelInboundMessageHandlerAdapter @SuppressWarnings("rawtypes") Class parameterizedHandlerType, int messageTypeParamIndex) { - acceptedMsgType = findMessageType(parameterizedHandlerType, messageTypeParamIndex); - } - - private Class findMessageType(Class parameterizedHandlerType, int messageTypeParamIndex) { - final Class thisClass = getClass(); - Class messageType = messageTypeMap.get(thisClass); - if (messageType == null) { - Class currentClass = thisClass; - for (;;) { - if (currentClass.getSuperclass() == parameterizedHandlerType) { - Type[] types = ((ParameterizedType) currentClass.getGenericSuperclass()).getActualTypeArguments(); - if (types.length - 1 < messageTypeParamIndex || !(types[0] instanceof Class)) { - throw new IllegalStateException( - "cannot determine the inbound message type of " + thisClass.getSimpleName()); - } - - messageType = (Class) types[0]; - break; - } - currentClass = currentClass.getSuperclass(); - } - - messageTypeMap.put(thisClass, messageType); - } - - return messageType; + acceptedMsgType = TypeParameterFinder.findActualTypeParameter( + this, parameterizedHandlerType, messageTypeParamIndex); } @Override