Author: pete.muir(a)jboss.org
Date: 2009-03-24 17:17:22 -0400 (Tue, 24 Mar 2009)
New Revision: 2194
Added:
ri/trunk/impl/src/main/java/org/jboss/webbeans/util/reflection/
ri/trunk/impl/src/main/java/org/jboss/webbeans/util/reflection/ParameterizedTypeImpl.java
Modified:
ri/trunk/impl/src/main/java/org/jboss/webbeans/event/EventManager.java
ri/trunk/impl/src/main/java/org/jboss/webbeans/util/Reflections.java
Log:
WBRI-194
Modified: ri/trunk/impl/src/main/java/org/jboss/webbeans/event/EventManager.java
===================================================================
--- ri/trunk/impl/src/main/java/org/jboss/webbeans/event/EventManager.java 2009-03-24
19:02:07 UTC (rev 2193)
+++ ri/trunk/impl/src/main/java/org/jboss/webbeans/event/EventManager.java 2009-03-24
21:17:22 UTC (rev 2194)
@@ -18,6 +18,7 @@
package org.jboss.webbeans.event;
import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -30,8 +31,8 @@
import org.jboss.webbeans.context.DependentContext;
import org.jboss.webbeans.log.Log;
import org.jboss.webbeans.log.Logging;
-import org.jboss.webbeans.util.Reflections;
import org.jboss.webbeans.util.Strings;
+import org.jboss.webbeans.util.Reflections.HierarchyDiscovery;
import org.jboss.webbeans.util.collections.ForwardingMap;
/**
@@ -47,18 +48,18 @@
/**
* An event type -> observer list map
*/
- private class RegisteredObserversMap extends ForwardingMap<Class<?>,
List<EventObserver<?>>>
+ private class RegisteredObserversMap extends ForwardingMap<Type,
List<EventObserver<?>>>
{
// The map delegate
- private ConcurrentHashMap<Class<?>, List<EventObserver<?>>>
delegate;
+ private ConcurrentHashMap<Type, List<EventObserver<?>>>
delegate;
/**
* Constructor. Initializes the delegate
*/
public RegisteredObserversMap()
{
- delegate = new ConcurrentHashMap<Class<?>,
List<EventObserver<?>>>();
+ delegate = new ConcurrentHashMap<Type,
List<EventObserver<?>>>();
}
/**
@@ -67,7 +68,7 @@
* @return The delegate
*/
@Override
- protected Map<Class<?>, List<EventObserver<?>>> delegate()
+ protected Map<Type, List<EventObserver<?>>> delegate()
{
return delegate;
}
@@ -160,9 +161,10 @@
public <T> Set<Observer<T>> getObservers(T event, Annotation...
bindings)
{
Set<Observer<T>> interestedObservers = new
HashSet<Observer<T>>();
- for (Class<?> clazz : Reflections.getTypeHierachy(event.getClass()))
+ Set<Type> types = new
HierarchyDiscovery<Type>(event.getClass()).getFlattenedTypes();
+ for (Type type : types)
{
- for (EventObserver<?> observer : registeredObservers.get(clazz))
+ for (EventObserver<?> observer : registeredObservers.get(type))
{
log.debug("Checking observer " + observer + " to see if it is
interested in event [" + event + "]");
if (observer.isObserverInterested(bindings))
Modified: ri/trunk/impl/src/main/java/org/jboss/webbeans/util/Reflections.java
===================================================================
--- ri/trunk/impl/src/main/java/org/jboss/webbeans/util/Reflections.java 2009-03-24
19:02:07 UTC (rev 2193)
+++ ri/trunk/impl/src/main/java/org/jboss/webbeans/util/Reflections.java 2009-03-24
21:17:22 UTC (rev 2194)
@@ -28,6 +28,7 @@
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
@@ -35,7 +36,9 @@
import javax.inject.BindingType;
import javax.inject.ExecutionException;
+import org.jboss.webbeans.util.reflection.ParameterizedTypeImpl;
+
/**
* Utility class for static reflection-type operations
*
@@ -96,13 +99,100 @@
@SuppressWarnings("unchecked")
private void discoverFromClass(Class<?> clazz)
{
- discoverTypes((T) clazz.getSuperclass());
- for (Class<?> c : clazz.getInterfaces())
+ discoverTypes((T) resolveType(type, clazz.getGenericSuperclass()));
+ for (Type c : clazz.getGenericInterfaces())
{
- discoverTypes((T) c);
+ discoverTypes((T) resolveType(type, c));
}
}
+ /**
+ * Gets the actual types by resolving TypeParameters.
+ *
+ * @param beanType
+ * @param type
+ * @return actual type
+ */
+ private Type resolveType(Type beanType, Type type)
+ {
+ if (type instanceof ParameterizedType)
+ {
+ if (beanType instanceof ParameterizedType)
+ {
+ return resolveParameterizedType((ParameterizedType) beanType,
(ParameterizedType) type);
+ }
+ if (beanType instanceof Class)
+ {
+ return resolveType(((Class<?>) beanType).getGenericSuperclass(),
(ParameterizedType) type);
+ }
+ }
+
+ if (type instanceof TypeVariable)
+ {
+ if (beanType instanceof ParameterizedType)
+ {
+ return resolveTypeParameter((ParameterizedType) beanType,
(TypeVariable<?>) type);
+ }
+ if (beanType instanceof Class)
+ {
+ return resolveType(((Class<?>) beanType).getGenericSuperclass(),
(TypeVariable<?>) type);
+ }
+ }
+ return type;
+ }
+
+ private Type resolveParameterizedType(ParameterizedType beanType, ParameterizedType
parameterizedType)
+ {
+ Type rawType = parameterizedType.getRawType();
+ Type[] actualTypes = parameterizedType.getActualTypeArguments();
+
+ Type resolvedRawType = resolveType(beanType, rawType);
+ Type[] resolvedActualTypes = new Type[actualTypes.length];
+
+ for (int i = 0; i < actualTypes.length; i++)
+ {
+ resolvedActualTypes[i] = resolveType(beanType, actualTypes[i]);
+ }
+ // reconstruct ParameterizedType by types resolved TypeVariable.
+ return new ParameterizedTypeImpl(resolvedRawType, resolvedActualTypes,
parameterizedType.getOwnerType());
+ }
+
+ private Type resolveTypeParameter(ParameterizedType beanType, TypeVariable<?>
typeVariable)
+ {
+ // step1. raw type
+ Class<?> actualType = (Class<?>) beanType.getRawType();
+ TypeVariable<?>[] typeVariables = actualType.getTypeParameters();
+ Type[] actualTypes = beanType.getActualTypeArguments();
+ for (int i = 0; i < typeVariables.length; i++)
+ {
+ if (typeVariables[i].equals(typeVariable))
+ {
+ return resolveType(type, actualTypes[i]);
+ }
+ }
+
+ // step2. generic super class
+ Type genericSuperType = actualType.getGenericSuperclass();
+ Type type = resolveType(genericSuperType, typeVariable);
+ if (!(type instanceof TypeVariable<?>))
+ {
+ return type;
+ }
+
+ // step3. generic interfaces
+ for (Type interfaceType : actualType.getGenericInterfaces())
+ {
+ Type resolvedType = resolveType(interfaceType, typeVariable);
+ if (!(resolvedType instanceof TypeVariable<?>))
+ {
+ return resolvedType;
+ }
+ }
+
+ // don't resolve type variable
+ return typeVariable;
+ }
+
}
/**
Added:
ri/trunk/impl/src/main/java/org/jboss/webbeans/util/reflection/ParameterizedTypeImpl.java
===================================================================
---
ri/trunk/impl/src/main/java/org/jboss/webbeans/util/reflection/ParameterizedTypeImpl.java
(rev 0)
+++
ri/trunk/impl/src/main/java/org/jboss/webbeans/util/reflection/ParameterizedTypeImpl.java 2009-03-24
21:17:22 UTC (rev 2194)
@@ -0,0 +1,93 @@
+package org.jboss.webbeans.util.reflection;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+
+public class ParameterizedTypeImpl implements ParameterizedType
+{
+ private final Type[] actualTypeArguments;
+ private final Type rawType;
+ private final Type ownerType;
+
+ public ParameterizedTypeImpl(Type rawType, Type[] actualTypeArguments, Type
ownerType)
+ {
+ this.actualTypeArguments = actualTypeArguments;
+ this.rawType = rawType;
+ this.ownerType = ownerType;
+ }
+
+ public Type[] getActualTypeArguments()
+ {
+ return actualTypeArguments;
+ }
+
+ public Type getOwnerType()
+ {
+ return ownerType;
+ }
+
+ public Type getRawType()
+ {
+ return rawType;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + Arrays.hashCode(actualTypeArguments);
+ result = prime * result + ((ownerType == null) ? 0 : ownerType.hashCode());
+ result = prime * result + ((rawType == null) ? 0 : rawType.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof ParameterizedType))
+ return false;
+
+ final ParameterizedType other = (ParameterizedType) obj;
+ if (!Arrays.equals(actualTypeArguments, other.getActualTypeArguments()))
+ return false;
+ if (ownerType == null)
+ {
+ if (other.getOwnerType() != null)
+ return false;
+ }
+ else if (!ownerType.equals(other.getOwnerType()))
+ return false;
+ if (rawType == null)
+ {
+ if (other.getRawType() != null)
+ return false;
+ }
+ else if (!rawType.equals(other.getRawType()))
+ return false;
+ return true;
+ }
+
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.append(rawType);
+ if (actualTypeArguments.length > 0)
+ {
+ sb.append("<");
+ for (Type actualType : actualTypeArguments)
+ {
+ sb.append(actualType);
+ sb.append(",");
+ }
+ sb.delete(sb.length() - 1, sb.length());
+ sb.append(">");
+ }
+ return sb.toString();
+ }
+}
Property changes on:
ri/trunk/impl/src/main/java/org/jboss/webbeans/util/reflection/ParameterizedTypeImpl.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain