[jboss-cvs] JBossAS SVN: r102294 - in projects/jboss-reflect/trunk/src: test/java/org/jboss/test/classinfo/test and 1 other directory.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Thu Mar 11 11:05:17 EST 2010


Author: kabir.khan at jboss.com
Date: 2010-03-11 11:05:16 -0500 (Thu, 11 Mar 2010)
New Revision: 102294

Added:
   projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/SecurityActions.java
Modified:
   projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistHelper.java
   projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistParameterizedClassInfo.java
   projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistTypeInfo.java
   projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistTypeInfoFactoryImpl.java
   projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/ClassInfoGenericClassTest.java
Log:
[JBREFLECT-5] Cache lookups of parameterized types in javassist

Modified: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistHelper.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistHelper.java	2010-03-11 15:18:56 UTC (rev 102293)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistHelper.java	2010-03-11 16:05:16 UTC (rev 102294)
@@ -21,11 +21,11 @@
 */ 
 package org.jboss.reflect.plugins.javassist;
 
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
 import java.util.Arrays;
 import java.util.Stack;
 
-import org.jboss.reflect.spi.TypeInfo;
-
 import javassist.CtClass;
 import javassist.NotFoundException;
 import javassist.bytecode.BadBytecode;
@@ -37,10 +37,12 @@
 import javassist.bytecode.SignatureAttribute.TypeParameter;
 import javassist.bytecode.SignatureAttribute.TypeVariable;
 
+import org.jboss.reflect.spi.ClassInfo;
+import org.jboss.reflect.spi.TypeInfo;
+
 /**
- * TODO This is prototype code! Once there are some tests for things like nested generics etc., it is very likely that we will need
- * to change signatures of methods in this class as needed.
- * 
+ * Utilities to figure out generic information 
+ *  
  * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
  * @version $Revision: 1.1 $
  */
@@ -219,12 +221,10 @@
    {
       int lastIndex;
       CtClass last = null;
-//      String name;
       ClassType classType;
       
       private void determineType(Stack<CtClass> hierarchy, int parameter)
       {
-         //TODO This should maybe return the full ObjectType instead
          CtClass clazz = null;
          
          TypeParameter targetType = null;

Modified: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistParameterizedClassInfo.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistParameterizedClassInfo.java	2010-03-11 15:18:56 UTC (rev 102293)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistParameterizedClassInfo.java	2010-03-11 16:05:16 UTC (rev 102294)
@@ -26,8 +26,6 @@
 
 import javassist.CtClass;
 import javassist.bytecode.SignatureAttribute.ClassSignature;
-import javassist.bytecode.SignatureAttribute.ClassType;
-import javassist.bytecode.SignatureAttribute.ObjectType;
 import javassist.bytecode.SignatureAttribute.TypeArgument;
 
 import org.jboss.reflect.plugins.ClassInfoImpl;
@@ -68,6 +66,11 @@
       this.typeArgumentInfos = typeArgumentInfos;
    }
    
+   public ClassInfo getDelegate()
+   {
+      return delegate;
+   }
+   
    @Override
    public TypeInfoFactory getTypeInfoFactory()
    {
@@ -82,7 +85,7 @@
          TypeInfo[] infos = new TypeInfo[typeArguments.length];
          for (int i = 0 ; i < typeArguments.length ; i++)
          {
-            infos[i] = createTypeInfo(typeArguments[i], delegate.getClassLoader());
+            infos[i] = factory.createTypeInfoForTypeArgument(typeArguments[i], delegate.getClassLoader());
          }
          typeArgumentInfos = infos;
       }
@@ -90,30 +93,6 @@
       return typeArgumentInfos;
    }
    
-   private TypeInfo createTypeInfo(TypeArgument arg, ClassLoader loader)
-   {
-      try
-      {
-         ObjectType type = arg.getType();
-         if (type instanceof ClassType)
-         {
-            ClassInfo info = (ClassInfo)factory.get(((ClassType)type).getName(), delegate.getClassLoader());
-            TypeArgument[] args = ((ClassType)type).getTypeArguments();
-            if (args != null && args.length > 0)
-            {
-               info = new JavassistParameterizedClassInfo(factory, info, args);
-            }
-            return info;
-         }
-         throw new IllegalStateException("Unhandled type " + type);
-      }
-      catch (ClassNotFoundException e)
-      {
-         // AutoGenerated
-         throw new RuntimeException(e);
-      }
-   }
-
    @Override
    public TypeInfo getComponentType()
    {

Modified: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistTypeInfo.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistTypeInfo.java	2010-03-11 15:18:56 UTC (rev 102293)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistTypeInfo.java	2010-03-11 16:05:16 UTC (rev 102294)
@@ -239,7 +239,7 @@
          if (classSig != null)
          {
             ClassType type = classSig.getSuperClass();
-            genericSuperClass = getParameterizedClassInfo(type);
+            genericSuperClass = factory.getParameterizedClassInfo(getClassLoader(), type);
          }
          else
          {
@@ -250,24 +250,6 @@
       return genericSuperClass;   
    }
 
-   private ClassInfo getParameterizedClassInfo(ClassType type)
-   {
-      String name = type.getName();
-      
-      ClassInfo delegate;
-      try
-      {
-         delegate = (ClassInfo)factory.get(name, getClassLoader());
-         if (type.getTypeArguments() == null || type.getTypeArguments().length == 0)
-            return delegate;
-         return new JavassistParameterizedClassInfo(factory, delegate, type.getTypeArguments());
-      }
-      catch (ClassNotFoundException e)
-      {
-         throw new IllegalStateException(e);
-      }
-   }
-   
    public InterfaceInfo[] getInterfaces()
    {
       try
@@ -299,7 +281,7 @@
             ClassType[] types = classSig.getInterfaces();
             for (int i = 0 ; i < types.length ; i++)
             {
-               ClassInfo info = getParameterizedClassInfo(types[i]);
+               ClassInfo info = factory.getParameterizedClassInfo(getClassLoader(), types[i]);
                if (info instanceof InterfaceInfo == false)
                   throw new IllegalStateException(info + " is not an InterfaceInfo");
                infos[i] = (InterfaceInfo)info; 
@@ -849,7 +831,7 @@
       {
          CtClass collection = ctClass.getClassPool().get(target);
          ClassType type = JavassistHelper.determineType(ctClass, collection, parameter);
-         return getParameterizedClassInfo(type);
+         return factory.getParameterizedClassInfo(getClassLoader(), type);
       }
       catch (Exception e1)
       {

Modified: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistTypeInfoFactoryImpl.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistTypeInfoFactoryImpl.java	2010-03-11 15:18:56 UTC (rev 102293)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistTypeInfoFactoryImpl.java	2010-03-11 16:05:16 UTC (rev 102294)
@@ -21,6 +21,22 @@
 */
 package org.jboss.reflect.plugins.javassist;
 
+import java.lang.annotation.Annotation;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Map;
+
+import javassist.CtClass;
+import javassist.CtField;
+import javassist.CtMember;
+import javassist.CtMethod;
+import javassist.CtPrimitiveType;
+import javassist.NotFoundException;
+import javassist.bytecode.SignatureAttribute.ClassType;
+import javassist.bytecode.SignatureAttribute.ObjectType;
+import javassist.bytecode.SignatureAttribute.TypeArgument;
+
 import org.jboss.reflect.plugins.AnnotationAttributeImpl;
 import org.jboss.reflect.plugins.AnnotationHelper;
 import org.jboss.reflect.plugins.AnnotationValueFactory;
@@ -39,19 +55,6 @@
 import org.jboss.util.JBossStringBuilder;
 import org.jboss.util.collection.WeakClassCache;
 
-import java.lang.annotation.Annotation;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.Map;
-
-import javassist.CtClass;
-import javassist.CtField;
-import javassist.CtMember;
-import javassist.CtMethod;
-import javassist.CtPrimitiveType;
-import javassist.NotFoundException;
-
 /**
  * A javassist type factory.
  * TODO: need to fix the cl stuff
@@ -346,31 +349,48 @@
       }
       
       Map<String, WeakReference<TypeInfo>> classLoaderCache = getClassLoaderCache(ctClass.getClassPool().getClassLoader());
-
-      WeakReference<TypeInfo> weak = classLoaderCache.get(ctClass.getName());
+      TypeInfo result = getFromCache(ctClass.getName(), classLoaderCache);
+      if (result != null)
+         return result;
+      
+      result = instantiate(ctClass, clazz);
+      
+      WeakReference<TypeInfo>weak = new WeakReference<TypeInfo>(result);
+      classLoaderCache.put(ctClass.getName(), weak);
+      
+//      we just ignore generate(..) since it doesnt do anything atm
+//      generate(clazz, result);
+      
+      return result;
+   }
+   
+   private TypeInfo getFromCache(String name, Map<String, WeakReference<TypeInfo>> classLoaderCache)
+   {
+      WeakReference<TypeInfo> weak = classLoaderCache.get(name);
       if (weak != null)
       {
          TypeInfo result = weak.get();
          if (result != null)
          {
-            if(compare(ctClass, (ClassInfo) result))
-               return result;
+            if (result instanceof JavassistTypeInfo)
+            {
+               if(compare(((JavassistTypeInfo)result).getCtClass(), (ClassInfo) result))
+                  return result;
+            }
+            else if (result instanceof JavassistParameterizedClassInfo)
+            {
+               ClassInfo info = ((JavassistParameterizedClassInfo)result).getDelegate();
+               if (info instanceof JavassistTypeInfo)
+                  if(compare(((JavassistTypeInfo)info).getCtClass(),  info))
+                     return result;
+            }
             else
             {
-               classLoaderCache.remove(ctClass.getName());
+               classLoaderCache.remove(name);
             }
          }
       }
-
-      TypeInfo result = instantiate(ctClass, clazz);
-      
-      weak = new WeakReference<TypeInfo>(result);
-      classLoaderCache.put(ctClass.getName(), weak);
-      
-//      we just ignore generate(..) since it doesnt do anything atm
-//      generate(clazz, result);
-      
-      return result;
+      return null;
    }
    
    /**
@@ -621,7 +641,19 @@
 
    protected TypeInfo getParameterizedType(ParameterizedType type)
    {
-      Class<?> rawType = (Class<?>)type.getRawType();
+      
+      //Look in the cache first
+      String genericName = getGenericName(type);
+      Class<?> rawType = (Class<?>) type.getRawType();
+      ClassLoader cl = SecurityActions.getClassLoader(rawType);
+      if (cl == null)
+         cl = Thread.currentThread().getContextClassLoader();
+      Map<String, WeakReference<TypeInfo>> cache = getClassLoaderCache(cl);
+      TypeInfo info = getFromCache(genericName, cache);
+      if (info != null)
+         return info;
+      
+      //Create the parameterized type info
       ClassInfo raw = (ClassInfo)getTypeInfo(rawType);
       Type[] types = type.getActualTypeArguments();
       TypeInfo[] typeInfos = new TypeInfo[types.length];
@@ -637,7 +669,140 @@
             throw new IllegalStateException(e);
          }
       }
-      return new JavassistParameterizedClassInfo(this, raw, typeInfos);
+      info = new JavassistParameterizedClassInfo(this, raw, typeInfos);
+      
+      //Cache the parameterized type info
+      cache.put(genericName, new WeakReference<TypeInfo>(info));
+      
+      return info;
    }
+
+   protected ClassInfo getParameterizedClassInfo(ClassLoader loader, ClassType type)
+   {
+      //If it is not a parameterized type, just return the type
+      boolean isParameterized = type.getTypeArguments() != null && type.getTypeArguments().length > 0;
+      if (!isParameterized)
+      {
+         try
+         {
+            return (ClassInfo)get(type.getName(), loader);
+         }
+         catch (ClassNotFoundException e)
+         {
+            throw new IllegalStateException(e);
+         }
+      }
+      
+      //Look in the cache first
+      String genericName = getGenericName(type);
+      Map<String, WeakReference<TypeInfo>> cache = getClassLoaderCache(loader);
+      TypeInfo info = getFromCache(genericName, cache);
+      if (info != null)
+      {
+         if (info instanceof ClassInfo == false)
+            throw new IllegalStateException("Not a ClassInfo " + info);
+         return (ClassInfo)info;
+      }
+      
+      //Create the parameterized type info
+      try
+      {
+         ClassInfo delegate = (ClassInfo)get(type.getName(), loader);
+         if (!isParameterized)
+            return delegate;
+         info = new JavassistParameterizedClassInfo(this, delegate, type.getTypeArguments());
+      }
+      catch (ClassNotFoundException e)
+      {
+         throw new IllegalStateException(e);
+      }
+
+      //Cache the parameterized type info
+      cache.put(genericName, new WeakReference<TypeInfo>(info));
+      
+      return (ClassInfo)info;
+   }
    
+   protected TypeInfo createTypeInfoForTypeArgument(TypeArgument arg, ClassLoader loader)
+   {
+      ObjectType type = arg.getType();
+      if (type instanceof ClassType)
+      {
+         return getParameterizedClassInfo(loader, (ClassType) type);
+      }
+      throw new IllegalStateException("Unhandled type " + type);
+   }
+
+   
+   
+   protected String getGenericName(ParameterizedType type)
+   {
+      StringBuilder sb = new StringBuilder();
+      appendTypeGenericInfo(type, sb);
+      return sb.toString();
+   }
+
+   protected void appendTypeGenericInfo(Type type, StringBuilder sb)
+   {
+      if (type instanceof Class)
+      {
+         sb.append(((Class<?>)type).getName());
+      }
+      else if (type instanceof ParameterizedType)
+      {
+         ParameterizedType ptype = (ParameterizedType)type;
+         appendTypeGenericInfo(ptype.getRawType(), sb);
+         sb.append("<");
+         Type[] types = ptype.getActualTypeArguments();
+         for (int i = 0 ; i < types.length ; i++)
+         {
+            if (i > 0)
+               sb.append(", ");
+            appendTypeGenericInfo(types[i], sb);
+         }
+         sb.append(">");
+      }
+      else
+      {
+         //TODO This might need implementing once we test wildcards
+         throw new IllegalArgumentException("Unhandled type " + type.getClass().getName());
+      }
+   }
+
+   protected String getGenericName(ObjectType type)
+   {
+      StringBuilder sb = new StringBuilder();
+      appendTypeGenericInfo(type, sb);
+      return sb.toString();
+   }
+   
+   protected void appendTypeGenericInfo(ObjectType type, StringBuilder sb)
+   {
+      if (type instanceof ClassType)
+      {
+         ClassType ctype = (ClassType)type;
+         sb.append(ctype.getName());
+
+         TypeArgument[] arguments = ctype.getTypeArguments();
+         
+         if (arguments != null && arguments.length > 0)
+         {
+            sb.append("<");
+            
+            for (int i = 0 ; i < arguments.length ; i++)
+            {
+               if (i > 0)
+                  sb.append(", ");
+               appendTypeGenericInfo(arguments[i].getType(), sb);
+            }
+            sb.append(">");
+         }
+      }
+      else
+      {
+         //TODO This might need implementing once we test wildcards
+         throw new IllegalArgumentException("Unhandled type " + type.getClass().getName());
+      }
+   }
+
 }

Added: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/SecurityActions.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/SecurityActions.java	                        (rev 0)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/SecurityActions.java	2010-03-11 16:05:16 UTC (rev 102294)
@@ -0,0 +1,70 @@
+/*
+* JBoss, Home of Professional Open Source.
+* Copyright 2006, Red Hat Middleware LLC, and individual contributors
+* as indicated by the @author tags. See the copyright.txt file in the
+* distribution for a full listing of individual contributors. 
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/ 
+package org.jboss.reflect.plugins.javassist;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * 
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+class SecurityActions
+{
+   
+   interface GetClassLoaderAction 
+   {
+      ClassLoader getClassLoader(Class<?> clazz);
+      
+      GetClassLoaderAction NON_PRIVILEGED = new GetClassLoaderAction() {
+
+         public ClassLoader getClassLoader(Class<?> clazz)
+         {
+            return clazz.getClassLoader();
+         }};
+
+     GetClassLoaderAction PRIVILEGED = new GetClassLoaderAction() {
+
+         public ClassLoader getClassLoader(final Class<?> clazz)
+         {
+            return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+
+               public ClassLoader run()
+               {
+                  return clazz.getClassLoader();
+               }});
+         }};
+   }
+   
+   static ClassLoader getClassLoader(Class<?> clazz)
+   {
+      if (System.getSecurityManager() == null)
+      {
+         return GetClassLoaderAction.NON_PRIVILEGED.getClassLoader(clazz);
+      }
+      else
+      {
+         return GetClassLoaderAction.PRIVILEGED.getClassLoader(clazz);
+      }
+   }
+}

Modified: projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/ClassInfoGenericClassTest.java
===================================================================
--- projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/ClassInfoGenericClassTest.java	2010-03-11 15:18:56 UTC (rev 102293)
+++ projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/ClassInfoGenericClassTest.java	2010-03-11 16:05:16 UTC (rev 102294)
@@ -352,7 +352,7 @@
       assertKeyValueType(ClassInfoGenericExtendsMap.class, Short.class, Double.class);
    }
    
-   public static Map<List<Class<String>>, Map<String, Class<String>>> signatureMapComplex()
+   public static Map<List<Class<String>>, Map<Class<String>, List<Long>>> signatureMapComplex()
    {
       return null;
    }
@@ -449,6 +449,72 @@
       assertKeyValueType(ClassInfoGenericExtendsSwappedMapInComplicatedWayWIthSpecificType.class, Short.class, Double.class);
    }
 
+   public void testCachedParameterizedClassInfoSame() throws Throwable
+   {
+      TypeInfo typeInfo1 = getTypeInfoFactory().getTypeInfo(getGenericReturnType("signatureCollectionBoolean"));
+      TypeInfo typeInfo2 = getTypeInfoFactory().getTypeInfo(getGenericReturnType("signatureCollectionBoolean"));
+      assertEquals(typeInfo1, typeInfo2);
+      assertSame(typeInfo1, typeInfo2);
+   }
+   
+   public static Collection<Long> signatureCollectionLong() 
+   {
+      return null;
+   }
+   
+   public void testCachedParameterizedClassInfoNotSame() throws Throwable
+   {
+      TypeInfo typeInfo1 = getTypeInfoFactory().getTypeInfo(getGenericReturnType("signatureCollectionBoolean"));
+      TypeInfo typeInfo2 = getTypeInfoFactory().getTypeInfo(getGenericReturnType("signatureCollectionLong"));
+      assertEquals(typeInfo1.getName(), typeInfo2.getName());
+      assertNotSame(typeInfo1, typeInfo2);
+   }
+
+   public void testCachedParameterizedClassInfoGenericInterfaces() throws Throwable
+   {
+      TypeInfo typeInfo = getTypeInfoFactory().getTypeInfo(getGenericReturnType("signatureCollectionComplex"));
+      InterfaceInfo[] interfaceInfos = ((ClassInfo)getTypeInfoFactory().getTypeInfo(ClassInfoGenericImplementsCollectionComplex.class)).getGenericInterfaces();
+      assertEquals(1, interfaceInfos.length);
+      assertEquals(typeInfo, interfaceInfos[0]);
+      assertSame(typeInfo, interfaceInfos[0]);
+   }
+   
+   public void testCachedParameterizedClassInfoGenericSuperclass() throws Throwable
+   {
+      ClassInfo classInfo1 = (ClassInfo)getTypeInfoFactory().getTypeInfo(getGenericReturnType("signatureCollectionComplex"));
+      ClassInfo classInfo2 = ((ClassInfo)getTypeInfoFactory().getTypeInfo(ClassInfoGenericExtendsCollectionComplex.class)).getGenericSuperclass();
+      
+      assertEquals(1, classInfo1.getActualTypeArguments().length);
+      assertEquals(1, classInfo2.getActualTypeArguments().length);
+      
+      assertEquals(classInfo1.getActualTypeArguments()[0], classInfo2.getActualTypeArguments()[0]);
+      assertSame(classInfo1.getActualTypeArguments()[0], classInfo2.getActualTypeArguments()[0]);
+   }
+
+   public void testCachedParameterizedClassInfoComponentType() throws Throwable
+   {
+      ClassInfo classInfo = (ClassInfo)getTypeInfoFactory().getTypeInfo(getGenericReturnType("signatureCollectionComplex"));
+      ClassInfo componentType = (ClassInfo)((ClassInfo)getTypeInfoFactory().getTypeInfo(ClassInfoGenericExtendsCollectionComplex.class)).getComponentType();
+      
+      assertEquals(1, classInfo.getActualTypeArguments().length);
+      assertEquals(classInfo.getActualTypeArguments()[0], componentType);
+      assertSame(classInfo.getActualTypeArguments()[0], componentType);
+   }
+
+   public void testCachedParameterizedClassInfoKeyValueType() throws Throwable
+   {
+      ClassInfo classInfo = (ClassInfo)getTypeInfoFactory().getTypeInfo(getGenericReturnType("signatureMapComplex"));
+      ClassInfo keyType = (ClassInfo)((ClassInfo)getTypeInfoFactory().getTypeInfo(ClassInfoGenericImplementsMapComplex.class)).getKeyType();
+      ClassInfo valueType = (ClassInfo)((ClassInfo)getTypeInfoFactory().getTypeInfo(ClassInfoGenericImplementsMapComplex.class)).getValueType();
+      
+//      Map<List<Class<String>>, Map<String, Class<String>>>
+      assertEquals(2, classInfo.getActualTypeArguments().length);
+      assertEquals(classInfo.getActualTypeArguments()[0], keyType);
+      assertSame(classInfo.getActualTypeArguments()[0], keyType);
+      assertEquals(classInfo.getActualTypeArguments()[1], valueType);
+      assertSame(classInfo.getActualTypeArguments()[1], valueType);
+   }
+
    private Type getGenericReturnType(String methodName) throws Exception
    {
       Method method = ClassInfoGenericClassTest.class.getMethod(methodName, (Class[]) null);




More information about the jboss-cvs-commits mailing list