[jboss-cvs] JBossAS SVN: r102626 - in projects/jboss-reflect/trunk/src: main/java/org/jboss/reflect/plugins/introspection and 3 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Fri Mar 19 11:02:43 EDT 2010
Author: kabir.khan at jboss.com
Date: 2010-03-19 11:02:41 -0400 (Fri, 19 Mar 2010)
New Revision: 102626
Added:
projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/SecurityActions.java
projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistTypeVariableSpy.java
projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/SecurityActions.java
projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoGenericSuperClassTypeVariable.java
projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoGenericSuperClassTypeVariableBounded.java
projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoGenericSuperInterfaceTypeVariable.java
projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoGenericSuperInterfaceTypeVariableBounded.java
projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoTypeVariable.java
projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoTypeVariableBounded.java
projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/ClassInfoGenericMembersTest.java
projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/IntrospectionClassInfoGenericMembersTestCase.java
projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/JavassistClassInfoGenericMembersTestCase.java
Modified:
projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/GenericsUtil.java
projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/IntrospectionTypeInfoFactoryImpl.java
projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistConstructorInfo.java
projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistFieldInfo.java
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/JavassistMethodInfo.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
projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/ClassInfoTestSuite.java
Log:
[JBREFLECT-5] Make JavassistMethodInfo/-FieldInfo/ConstructorInfo's getParameterTypes(), getReturnType() and getFieldType() etc. return Parameterized type infos if generics are used
Modified: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/GenericsUtil.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/GenericsUtil.java 2010-03-19 14:22:56 UTC (rev 102625)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/GenericsUtil.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -63,12 +63,10 @@
if (lower.length > 0)
{
- sb.append("? super ");
appendTypeGenericInfo(lower[0], sb);
}
else if (upper.length > 0)
{
- sb.append("? extends ");
appendTypeGenericInfo(upper[0], sb);
}
}
@@ -94,9 +92,8 @@
}
else if (type instanceof TypeVariable)
{
- //This is probably the wrong name, revisit when implementing type variables
TypeVariable typeVar = (TypeVariable)type;
- sb.append(typeVar.getName());
+ appendTypeGenericInfo(typeVar.getBounds()[0], sb);
}
else
{
Modified: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/IntrospectionTypeInfoFactoryImpl.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/IntrospectionTypeInfoFactoryImpl.java 2010-03-19 14:22:56 UTC (rev 102625)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/IntrospectionTypeInfoFactoryImpl.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -724,4 +724,33 @@
Type bound = type.getLowerBounds().length > 0 ? type.getLowerBounds()[0] : type.getUpperBounds()[0];
return getTypeInfo(bound);
}
+
+ @Override
+ protected TypeInfo peek(ParameterizedType type)
+ {
+ //FIXME improved version of what exists in WeakTypeCache. Should be put there
+ Class<?> rawType = (Class<?>) type.getRawType();
+ ClassLoader cl = SecurityActions.getClassLoader(rawType);
+ Map<String, TypeInfo> classLoaderCache = getClassLoaderCache(cl);
+
+ synchronized (classLoaderCache)
+ {
+ return classLoaderCache.get(GenericsUtil.getGenericName(type));
+ }
+ }
+
+ @Override
+ protected void put(ParameterizedType type, TypeInfo result)
+ {
+ //FIXME improved version of what exists in WeakTypeCache. Should be put there
+ Class<?> rawType = (Class<?>) type.getRawType();
+ ClassLoader cl = SecurityActions.getClassLoader(rawType);
+ Map<String, TypeInfo> classLoaderCache = getClassLoaderCache(cl);
+
+ synchronized (classLoaderCache)
+ {
+ classLoaderCache.put(GenericsUtil.getGenericName(type), result);
+ }
+ }
+
}
Added: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/SecurityActions.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/SecurityActions.java (rev 0)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/introspection/SecurityActions.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -0,0 +1,69 @@
+/*
+* 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.introspection;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ *
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+public 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/main/java/org/jboss/reflect/plugins/javassist/JavassistConstructorInfo.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistConstructorInfo.java 2010-03-19 14:22:56 UTC (rev 102625)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistConstructorInfo.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -28,6 +28,7 @@
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.NotFoundException;
+import javassist.bytecode.SignatureAttribute.MethodSignature;
import org.jboss.reflect.plugins.AnnotationHelper;
import org.jboss.reflect.spi.AnnotationValue;
@@ -189,12 +190,20 @@
{
try
{
- CtClass[] types = ctConstructor.getParameterTypes();
- parameterTypes = new TypeInfo[types.length];
- for (int i = 0; i < types.length; ++i)
- parameterTypes[i] = typeInfo.getFactory().getTypeInfo(types[i]);
- parameters = new ParameterInfo[types.length];
- for (int i = 0; i < types.length; ++i)
+ MethodSignature sig = JavassistHelper.getMethodSignature(ctConstructor);
+ if (sig != null && sig.getParameterTypes().length == ctConstructor.getParameterTypes().length)
+ {
+ parameterTypes = JavassistHelper.createParameterTypes(ctConstructor, sig, typeInfo);
+ }
+ else
+ {
+ CtClass[] types = ctConstructor.getParameterTypes();
+ parameterTypes = new TypeInfo[types.length];
+ for (int i = 0; i < types.length; ++i)
+ parameterTypes[i] = typeInfo.getFactory().getTypeInfo(types[i]);
+ }
+ parameters = new ParameterInfo[parameterTypes.length];
+ for (int i = 0; i < parameterTypes.length; ++i)
parameters[i] = new JavassistParameterInfo(annotationHelper, this, i, parameterTypes[i]);
}
catch (NotFoundException e)
Modified: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistFieldInfo.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistFieldInfo.java 2010-03-19 14:22:56 UTC (rev 102625)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistFieldInfo.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -35,6 +35,8 @@
import javassist.CtClass;
import javassist.CtField;
import javassist.NotFoundException;
+import javassist.bytecode.SignatureAttribute.ClassSignature;
+import javassist.bytecode.SignatureAttribute.ObjectType;
/**
* FieldInfo that relies on Javassist to answer reflective queries and to access
@@ -119,6 +121,13 @@
return fieldType;
try
{
+ ObjectType type = JavassistHelper.getFieldSignature(ctField);
+ if (type != null)
+ {
+ ClassSignature sig = JavassistHelper.getClassSignature(ctField.getDeclaringClass());
+ return typeInfo.getFactory().getTypeInfo(typeInfo.getClassLoader(), type, JavassistTypeVariableSpy.createForField(sig));
+ }
+
CtClass clazz = ctField.getType();
fieldType = typeInfo.getFactory().getTypeInfo(clazz);
return fieldType;
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-19 14:22:56 UTC (rev 102625)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistHelper.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -24,13 +24,18 @@
import java.util.Arrays;
import java.util.Stack;
+import javassist.CtBehavior;
import javassist.CtClass;
+import javassist.CtField;
import javassist.NotFoundException;
import javassist.bytecode.BadBytecode;
import javassist.bytecode.SignatureAttribute;
+import javassist.bytecode.SignatureAttribute.ArrayType;
import javassist.bytecode.SignatureAttribute.ClassSignature;
import javassist.bytecode.SignatureAttribute.ClassType;
+import javassist.bytecode.SignatureAttribute.MethodSignature;
import javassist.bytecode.SignatureAttribute.ObjectType;
+import javassist.bytecode.SignatureAttribute.Type;
import javassist.bytecode.SignatureAttribute.TypeArgument;
import javassist.bytecode.SignatureAttribute.TypeParameter;
import javassist.bytecode.SignatureAttribute.TypeVariable;
@@ -51,7 +56,7 @@
* @param clazz the sub class
* @param search the parent class or interface we are searching for
* @param parameter the index of the type parameter we are looking for
- * @return the type
+ * @return the generic type
*/
static ClassType determineType(CtClass clazz, CtClass search, int parameter)
{
@@ -67,7 +72,16 @@
return determineType(hierarchy, parameter);
}
- static int determineInfoIndex(TypeInfo[] actualTypeArguments, CtClass clazz, CtClass search, int parameter)
+ /**
+ * Looking at the classes between clazz and search, determine the type of the type parameter with the passed in index
+ *
+ * @param actualTypeArguments the actual type arguments
+ * @param clazz the sub class
+ * @param search the parent class or interface we are searching for
+ * @param parameter the index of the type parameter we are looking for
+ * @return the type
+ */
+ static TypeInfo determineInfoIndex(TypeInfo[] actualTypeArguments, CtClass clazz, CtClass search, int parameter)
{
Stack<CtClass> hierarchy = new Stack<CtClass>();
try
@@ -78,10 +92,81 @@
{
throw new RuntimeException(e);
}
- return determineInfoIndex(actualTypeArguments, hierarchy, parameter);
+ return actualTypeArguments[determineInfoIndex(actualTypeArguments, hierarchy, parameter)];
}
+
+ /**
+ * Get the full name of the generic javassist object type
+ *
+ * @param type the type
+ * @param spy used to determine actual types of type variables
+ * @return the generic type name
+ */
+ static String getGenericName(ObjectType type, JavassistTypeVariableSpy spy)
+ {
+ StringBuilder sb = new StringBuilder();
+ appendTypeGenericInfo(type, spy, sb);
+ return sb.toString();
+ }
/**
+ * Append the information of the type to the name builder
+ *
+ * @param type the type
+ * @param spy used to determine actual types of type variables
+ * @param sb the string builder receiving the name
+ * @return the generic type name
+ */
+ private static void appendTypeGenericInfo(ObjectType type, JavassistTypeVariableSpy spy, 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(", ");
+
+ if (arguments[i].getType() == null)
+ sb.append(Object.class.getName());
+ else
+ appendTypeGenericInfo(arguments[i].getType(), spy, sb);
+ }
+ sb.append(">");
+ }
+ }
+ else if (type instanceof SignatureAttribute.TypeVariable)
+ {
+ Type real = spy.getTypeBound((TypeVariable)type);
+ if (real instanceof ObjectType == false)
+ throw new IllegalStateException("Type is not an instance of ObjectType " + real);
+ appendTypeGenericInfo((ObjectType)real, spy, sb);
+ }
+ else if (type instanceof ArrayType)
+ {
+ ArrayType array = (ArrayType)type;
+
+ appendTypeGenericInfo((ObjectType)array.getComponentType(), spy, sb);
+ for (int i = 0 ; i < array.getDimension() ; i++)
+ sb.append("[]");
+ }
+ else
+ {
+ //TODO This might need implementing once we test wildcards
+ throw new IllegalArgumentException("Unhandled type " + type);
+ }
+ }
+
+ /**
* Determine the type of the parameter in the top-level class.
*
* @param hierarchy the hierarchy of classes as determined by {@link JavassistHelper#determineHierarchy(Stack, CtClass, CtClass)}
@@ -107,15 +192,16 @@
*
* @param clazz the CtClass
* @return the ClassSignature
+ * @throws IllegalArgumentException if clazz is null
*/
public static ClassSignature getClassSignature(CtClass clazz)
{
if (clazz == null)
throw new IllegalArgumentException("Null clazz");
- //Use getClassFile2 since in some cases the class has been frozen
if (clazz.isArray() || clazz.isPrimitive())
return null;
+ //Use getClassFile2 since in some cases the class has been frozen
SignatureAttribute signature = (SignatureAttribute)clazz.getClassFile2().getAttribute(SignatureAttribute.tag);
if (signature == null)
return null;
@@ -130,8 +216,79 @@
throw new IllegalStateException(e);
}
}
+
+ /**
+ * Creates the generic parameter types for a constructor or method
+ *
+ * @param behavior the method or constructor
+ * @param sig the method/constructor signature
+ * @param typeInfo the javassist type info
+ * @return the parameter types
+ */
+ public static TypeInfo[] createParameterTypes(CtBehavior behavior, MethodSignature sig, JavassistTypeInfo typeInfo)
+ {
+ SignatureAttribute.Type[] types = sig.getParameterTypes();
+ TypeInfo[] parameterTypes = new TypeInfo[types.length];
+ for (int i = 0 ; i < types.length ; i++)
+ parameterTypes[i] = typeInfo.getFactory().getTypeInfo(typeInfo.getClassLoader(), types[i], JavassistTypeVariableSpy.createForBehavior(behavior, sig));
+ return parameterTypes;
+ }
+
+ /**
+ * Gets the ClassSignature for a method/constructor
+ *
+ * @param behaviour the method/constructor
+ * @return the ClassSignature
+ * @throws IllegalArgumentException if clazz is null
+ */
+ public static MethodSignature getMethodSignature(CtBehavior behaviour)
+ {
+ if (behaviour == null)
+ throw new IllegalArgumentException("Null method/constructor");
+
+ //Use getMethodInfo2 since in some cases the class has been frozen
+ SignatureAttribute signature = (SignatureAttribute)behaviour.getMethodInfo2().getAttribute(SignatureAttribute.tag);
+ if (signature == null)
+ return null;
+ String sig = signature.getSignature();
+ try
+ {
+ return SignatureAttribute.toMethodSignature(sig);
+ }
+ catch (BadBytecode e)
+ {
+ throw new IllegalStateException(e);
+ }
+ }
/**
+ * Gets the FieldSignature for a field
+ *
+ * @param field the field
+ * @return the FieldSignature
+ * @throws IllegalArgumentException if clazz is null
+ */
+ public static ObjectType getFieldSignature(CtField field)
+ {
+ if (field == null)
+ throw new IllegalArgumentException("Null method/constructor");
+
+ //Use getMethodInfo2 since in some cases the class has been frozen
+ SignatureAttribute signature = (SignatureAttribute)field.getFieldInfo2().getAttribute(SignatureAttribute.tag);
+ if (signature == null)
+ return null;
+ String sig = signature.getSignature();
+ try
+ {
+ return SignatureAttribute.toFieldSignature(sig);
+ }
+ catch (BadBytecode e)
+ {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ /**
* Figures out the path between the passed in classes
*
* @param hierarchy receives the CtClasses that make up the hierarchy. This parameter may be null, in which
Modified: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistMethodInfo.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistMethodInfo.java 2010-03-19 14:22:56 UTC (rev 102625)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistMethodInfo.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -29,6 +29,8 @@
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;
+import javassist.bytecode.SignatureAttribute.BaseType;
+import javassist.bytecode.SignatureAttribute.MethodSignature;
import org.jboss.reflect.plugins.AnnotationHelper;
import org.jboss.reflect.spi.AnnotationValue;
@@ -142,9 +144,15 @@
return returnType;
try
{
+ MethodSignature sig = JavassistHelper.getMethodSignature(ctMethod);
+ if (sig != null)
+ {
+ if (sig.getReturnType() instanceof BaseType == false)
+ return typeInfo.getFactory().getTypeInfo(typeInfo.getClassLoader(), sig.getReturnType(), JavassistTypeVariableSpy.createForBehavior(ctMethod, sig));
+ }
+
CtClass clazz = ctMethod.getReturnType();
- returnType = typeInfo.getFactory().getTypeInfo(clazz);
- return returnType;
+ return typeInfo.getFactory().getTypeInfo(clazz);
}
catch (NotFoundException e)
{
@@ -218,12 +226,20 @@
{
try
{
- CtClass[] types = ctMethod.getParameterTypes();
- parameterTypes = new TypeInfo[types.length];
- for (int i = 0; i < types.length; ++i)
- parameterTypes[i] = typeInfo.getFactory().getTypeInfo(types[i]);
- parameters = new ParameterInfo[types.length];
- for (int i = 0; i < types.length; ++i)
+ MethodSignature sig = JavassistHelper.getMethodSignature(ctMethod);
+ if (sig != null && sig.getParameterTypes().length == ctMethod.getParameterTypes().length)
+ {
+ parameterTypes = JavassistHelper.createParameterTypes(ctMethod, sig, typeInfo);
+ }
+ else
+ {
+ CtClass[] types = ctMethod.getParameterTypes();
+ parameterTypes = new TypeInfo[types.length];
+ for (int i = 0; i < types.length; ++i)
+ parameterTypes[i] = typeInfo.getFactory().getTypeInfo(types[i]);
+ }
+ parameters = new ParameterInfo[parameterTypes.length];
+ for (int i = 0; i < parameterTypes.length; ++i)
parameters[i] = new JavassistParameterInfo(annotationHelper, this, i, parameterTypes[i]);
}
catch (NotFoundException e)
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-19 14:22:56 UTC (rev 102625)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistParameterizedClassInfo.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -36,6 +36,7 @@
import org.jboss.util.JBossStringBuilder;
/**
+ * Delegate class info to handle generic parameterized types in javassist
*
* @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
* @version $Revision: 1.1 $
@@ -49,20 +50,41 @@
/** The factory */
private final JavassistTypeInfoFactoryImpl factory;
+ /** The javassist generic type arguments */
private final TypeArgument[] typeArguments;
+ /** The generic type argument type infos */
private volatile TypeInfo[] typeArgumentInfos = ClassInfoImpl.UNKNOWN_TYPES;
- JavassistParameterizedClassInfo(JavassistTypeInfoFactoryImpl factory, ClassInfo delegate, TypeArgument[] typeArguments)
+ /** Utility to determine the actual bounds of generic type variables */
+ private final JavassistTypeVariableSpy spy;
+
+ /**
+ * Constructor
+ *
+ * @param factory the javassist type info factory
+ * @param delegate the class info containing the parameterized type's raw type
+ * @param typeArguments the javassist generic type arguments
+ * @param spy used to determine the actual bounds of generic type variables
+ */
+ JavassistParameterizedClassInfo(JavassistTypeInfoFactoryImpl factory, ClassInfo delegate, TypeArgument[] typeArguments, JavassistTypeVariableSpy spy)
{
super(delegate);
this.factory = factory;
this.typeArguments = typeArguments;
+ this.spy = spy;
}
+ /**
+ * Constructor
+ *
+ * @param factory the javassist type info factory
+ * @param delegate the class info containing the parameterized type's raw type
+ * @param typeArgumentInfos the type infos for the type arguments
+ */
public JavassistParameterizedClassInfo(JavassistTypeInfoFactoryImpl factory, ClassInfo delegate, TypeInfo[] typeArgumentInfos)
{
- this(factory, delegate, (TypeArgument[])null);
+ this(factory, delegate, (TypeArgument[])null, null);
this.typeArgumentInfos = typeArgumentInfos;
}
@@ -80,7 +102,7 @@
TypeInfo[] infos = new TypeInfo[typeArguments.length];
for (int i = 0 ; i < typeArguments.length ; i++)
{
- infos[i] = factory.createTypeInfoForTypeArgument(typeArguments[i], delegate.getClassLoader());
+ infos[i] = factory.createTypeInfoForTypeArgument(typeArguments[i], delegate.getClassLoader(), spy);
}
typeArgumentInfos = infos;
}
@@ -119,8 +141,7 @@
{
CtClass ctClass = ((JavassistTypeInfo)delegate).getCtClass();
CtClass collection = ctClass.getClassPool().get(target);
- int index = JavassistHelper.determineInfoIndex(getActualTypeArguments(), ((JavassistTypeInfo)delegate).getCtClass(), collection, parameter);
- return getActualTypeArguments()[index];
+ return JavassistHelper.determineInfoIndex(getActualTypeArguments(), ((JavassistTypeInfo)delegate).getCtClass(), collection, parameter);
}
catch (Exception e1)
{
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-19 14:22:56 UTC (rev 102625)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistTypeInfo.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -239,7 +239,7 @@
if (classSig != null)
{
ClassType type = classSig.getSuperClass();
- genericSuperClass = factory.getParameterizedClassInfo(getClassLoader(), type);
+ genericSuperClass = (ClassInfo)factory.getTypeInfo(getClassLoader(), type, JavassistTypeVariableSpy.createForClass(classSig));
}
else
{
@@ -281,7 +281,7 @@
ClassType[] types = classSig.getInterfaces();
for (int i = 0 ; i < types.length ; i++)
{
- ClassInfo info = factory.getParameterizedClassInfo(getClassLoader(), types[i]);
+ ClassInfo info = (ClassInfo)factory.getTypeInfo(getClassLoader(), types[i], JavassistTypeVariableSpy.createForClass(classSig));
if (info instanceof InterfaceInfo == false)
throw new IllegalStateException(info + " is not an InterfaceInfo");
infos[i] = (InterfaceInfo)info;
@@ -831,7 +831,8 @@
{
CtClass collection = ctClass.getClassPool().get(target);
ClassType type = JavassistHelper.determineType(ctClass, collection, parameter);
- return factory.getParameterizedClassInfo(getClassLoader(), type);
+ ClassSignature sig = JavassistHelper.getClassSignature(ctClass);
+ return factory.getTypeInfo(getClassLoader(), type, JavassistTypeVariableSpy.createForClass(sig));
}
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-19 14:22:56 UTC (rev 102625)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistTypeInfoFactoryImpl.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -36,6 +36,9 @@
import javassist.CtMethod;
import javassist.CtPrimitiveType;
import javassist.NotFoundException;
+import javassist.bytecode.SignatureAttribute;
+import javassist.bytecode.SignatureAttribute.ArrayType;
+import javassist.bytecode.SignatureAttribute.BaseType;
import javassist.bytecode.SignatureAttribute.ClassType;
import javassist.bytecode.SignatureAttribute.ObjectType;
import javassist.bytecode.SignatureAttribute.TypeArgument;
@@ -50,6 +53,7 @@
import org.jboss.reflect.plugins.javassist.classpool.DefaultClassPoolFactory;
import org.jboss.reflect.spi.AnnotationInfo;
import org.jboss.reflect.spi.AnnotationValue;
+import org.jboss.reflect.spi.ArrayInfo;
import org.jboss.reflect.spi.ClassInfo;
import org.jboss.reflect.spi.DelegateClassInfo;
import org.jboss.reflect.spi.MutableClassInfo;
@@ -299,7 +303,7 @@
{
ClassLoader cl = clazz.getClassLoader();
if(cl == null)
- cl = Thread.currentThread().getContextClassLoader();
+ cl = SecurityActions.getContextClassLoader();
return get(clazz.getName(), cl, clazz);
}
catch (ClassNotFoundException e)
@@ -346,7 +350,7 @@
{
throw new RuntimeException(e);
}
- number.setDelegate(get(clazz));
+ number.setDelegate(get(useClass));
}
return number;
}
@@ -369,6 +373,9 @@
return result;
}
+ /**
+ * Reads the type info from the cache
+ */
private TypeInfo getFromCache(String name, Map<String, WeakReference<TypeInfo>> classLoaderCache)
{
WeakReference<TypeInfo> weak = classLoaderCache.get(name);
@@ -377,22 +384,13 @@
TypeInfo result = weak.get();
if (result != null)
{
- if (result instanceof JavassistTypeInfo)
+ CtClass clazz = getCtClass(result, false);
+ if (clazz != null)
{
- if(compare(((JavassistTypeInfo)result).getCtClass(), (ClassInfo) result))
- return result;
- }
- else if (result instanceof DelegateClassInfo)
- {
- ClassInfo info = ((DelegateClassInfo)result).getDelegate();
- if (info instanceof JavassistTypeInfo)
- if(compare(((JavassistTypeInfo)info).getCtClass(), info))
+ if (compare(clazz, (ClassInfo)result))
return result;
}
- else
- {
- classLoaderCache.remove(name);
- }
+ classLoaderCache.remove(name);
}
}
return null;
@@ -504,12 +502,18 @@
}
+ /**
+ * Gets the type info for a class
+ *
+ * @param type the type
+ * @return the type info
+ */
public TypeInfo getTypeInfo(String name, ClassLoader cl) throws ClassNotFoundException
{
if (name == null)
throw new IllegalArgumentException("Null class name");
if (cl == null)
- cl = Thread.currentThread().getContextClassLoader();
+ cl = SecurityActions.getContextClassLoader();
TypeInfo primitive = PrimitiveInfo.valueOf(name);
if (primitive != null)
@@ -536,6 +540,12 @@
return getTypeInfo(clazz);
}
+ /**
+ * Gets the type info for a reflect type
+ *
+ * @param type the type
+ * @return the type info
+ */
public TypeInfo getTypeInfo(Type type)
{
if (type instanceof Class)
@@ -645,6 +655,12 @@
return new JavassistTypeInfo(this, clazz, null);
}
+ /**
+ * Creates a type info from a reflect generic paramemeterized type
+ *
+ * @param type the parameterized type
+ * @return the type info
+ */
protected TypeInfo getParameterizedType(ParameterizedType type)
{
@@ -681,15 +697,47 @@
return info;
}
- protected ClassInfo getParameterizedClassInfo(ClassLoader loader, ClassType type)
+ /**
+ * Gets the type info for a javassist type
+ *
+ * @param loader the class loader
+ * @param type the class type
+ * @param spy used to determine actual types of type variables
+ * @return the type info
+ */
+ protected TypeInfo getTypeInfo(ClassLoader loader, SignatureAttribute.Type type, JavassistTypeVariableSpy spy)
{
+ if (type instanceof ClassType)
+ return getTypeInfo(loader, (ClassType)type, spy);
+ else if (type instanceof ArrayType)
+ return getGenericArrayType(loader, (ArrayType)type, spy);
+ else if (type instanceof BaseType)
+ {
+ String s = String.valueOf(((BaseType)type).getDescriptor());
+ Class<?> clazz = PrimitiveInfo.getPrimativeArrayComponentType(s);
+ return PrimitiveInfo.valueOf(clazz.getName());
+ }
+
+ throw new IllegalArgumentException("Bad type " + type + " - " + type.getClass().getName());
+ }
+
+ /**
+ * Gets the type info for a javassist generic class type
+ *
+ * @param loader the class loader
+ * @param type the class type
+ * @param spy used to determine actual types of type variables
+ * @return the type info
+ */
+ protected TypeInfo getTypeInfo(ClassLoader loader, ClassType type, JavassistTypeVariableSpy spy)
+ {
//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);
+ return get(type.getName(), loader);
}
catch (ClassNotFoundException e)
{
@@ -698,14 +746,14 @@
}
//Look in the cache first
- String genericName = getGenericName(type);
+ String genericName = JavassistHelper.getGenericName(type, spy);
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;
+ return info;
}
//Create the parameterized type info
@@ -714,7 +762,7 @@
ClassInfo delegate = (ClassInfo)get(type.getName(), loader);
if (!isParameterized)
return delegate;
- info = new JavassistParameterizedClassInfo(this, delegate, type.getTypeArguments());
+ info = new JavassistParameterizedClassInfo(this, delegate, type.getTypeArguments(), spy);
}
catch (ClassNotFoundException e)
{
@@ -724,19 +772,48 @@
//Cache the parameterized type info
cache.put(genericName, new WeakReference<TypeInfo>(info));
- return (ClassInfo)info;
+ return info;
}
- protected TypeInfo createTypeInfoForTypeArgument(TypeArgument arg, ClassLoader loader)
+ /**
+ * Gets the type info for a javassist type argument
+ *
+ * @param arg the type argument
+ * @param loader the class loader
+ * @param spy used to determine actual types of type variables
+ * @return the type info
+ */
+ protected TypeInfo createTypeInfoForTypeArgument(TypeArgument arg, ClassLoader loader, JavassistTypeVariableSpy spy)
{
ObjectType type = arg.getType();
- if (type instanceof ClassType)
+ if (type == null)
{
- return getParameterizedClassInfo(loader, (ClassType) type);
+ try
+ {
+ return get(Object.class.getName(), loader, null);
+ }
+ catch(ClassNotFoundException e)
+ {
+ throw new RuntimeException(e);
+ }
}
+ else if (type instanceof ClassType)
+ {
+ return getTypeInfo(loader, (ClassType) type, spy);
+ }
+ else if (type instanceof javassist.bytecode.SignatureAttribute.TypeVariable)
+ {
+ return getTypeInfo(loader, spy.getTypeBound((javassist.bytecode.SignatureAttribute.TypeVariable)type), spy);
+ }
throw new IllegalStateException("Unhandled type " + type);
}
+ /**
+ * Gets the type info for a reflect wildcard type
+ *
+ * @param type the wildcard type
+ * @return the type info
+ */
protected TypeInfo getWildcardType(WildcardType type)
{
//Create the wildcard type info
@@ -744,52 +821,22 @@
return getTypeInfo(bound);
}
+ /**
+ * Gets the classloader cache for the passed in classloader.
+ *
+ * @param cl the classloader. If null is used, the Thread context classloader will be used instead
+ * @return the cache of type infos by name
+ */
@Override
protected Map<String, WeakReference<TypeInfo>> getClassLoaderCache(ClassLoader cl)
{
if (cl == null)
- cl = Thread.currentThread().getContextClassLoader();
+ cl = SecurityActions.getContextClassLoader();
return super.getClassLoaderCache(cl);
}
- 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());
- }
- }
-
/**
- * Get the information for an array type
+ * Get the type info for a reflect generic array type
*
* @param type the array type
* @return the info
@@ -808,7 +855,7 @@
Type compType = type.getGenericComponentType();
TypeInfo componentType = getTypeInfo(compType);
- String arrayName = getArrayCtClass(componentType);
+ String arrayName = getCtClass(componentType, true).getName();
CtClass clazz = getCtClass(arrayName + "[]", cl);
info = new JavassistArrayInfoImpl(this, clazz, null, componentType);
@@ -818,25 +865,109 @@
return info;
}
- private String getArrayCtClass(TypeInfo componentType)
+ /**
+ * Get the type info for a javassist array type
+ *
+ * @param cl the classloader
+ * @param type the array type
+ * @param spy used to determine actual types of type variables
+ * @return the type info
+ */
+ protected ArrayInfo getGenericArrayType(ClassLoader cl, ArrayType type, JavassistTypeVariableSpy spy)
{
- if (componentType instanceof JavassistTypeInfo)
- {
- if(compare(((JavassistTypeInfo)componentType).getCtClass(), (ClassInfo) componentType))
- return ((JavassistTypeInfo)componentType).getCtClass().getName();
- }
- else if (componentType instanceof DelegateClassInfo)
- {
- ClassInfo info = ((DelegateClassInfo)componentType).getDelegate();
- if (info instanceof JavassistTypeInfo)
- return ((JavassistTypeInfo)info).getCtClass().getName();
- }
+ ModifiableArrayType wrapped = new ModifiableArrayType(type);
+ return getGenericArrayType(cl, wrapped, spy);
+ }
+
+ /**
+ * Recursively get the type info for a javassist array type
+ *
+ * @param cl the classloader
+ * @param type the array type
+ * @param spy used to determine actual types of type variables
+ * @return the type info
+ */
+ protected ArrayInfo getGenericArrayType(ClassLoader cl, ModifiableArrayType type, JavassistTypeVariableSpy spy)
+ {
+ //Look in the cache first
+ String genericName = JavassistHelper.getGenericName(type, spy);
+ Map<String, WeakReference<TypeInfo>> cache = getClassLoaderCache(cl);
+ ArrayInfo info = (ArrayInfo)getFromCache(genericName, cache);
+ if (info != null)
+ return info;
+
+ type.decrement();
+ TypeInfo componentType = type.getDimension() > 0 ?
+ getGenericArrayType(cl, type, spy) : getTypeInfo(cl, type.getComponentType(), spy);
- throw new IllegalArgumentException(componentType + " is not a JavassistType info or a JavassistParameterizedType");
+ String arrayName = getCtClass(componentType, true).getName();
+ CtClass clazz = getCtClass(arrayName + "[]", cl);
+ info = new JavassistArrayInfoImpl(this, clazz, null, componentType);
+
+
+ //Cache the wildcard type info
+ cache.put(genericName, new WeakReference<TypeInfo>(info));
+
+ return info;
}
+ /**
+ * Gets the CtClass from a TypeInfo if it is a javassist one
+ *
+ * @param typeInfo the type info
+ * @param error if true and the type can not be determined, throw an error
+ * @return null if the type could not be determined and <code>error</code> is false
+ * @throws IllegalArgumentException if <code>error</code> is true and the type can not be determined
+ */
+ private CtClass getCtClass(TypeInfo typeInfo, boolean error)
+ {
+ if (typeInfo instanceof JavassistTypeInfo)
+ return ((JavassistTypeInfo)typeInfo).getCtClass();
+ else if (typeInfo instanceof DelegateClassInfo)
+ return getCtClass(((DelegateClassInfo) typeInfo).getDelegate(), error);
+
+ if (error)
+ throw new IllegalArgumentException(typeInfo + " is not a JavassistType info or a JavassistParameterizedType");
+
+ return null;
+ }
+
+ /**
+ * Get the type info for a reflect TypeVariable
+ *
+ * @param type the type variable
+ * @return the type info
+ *
+ */
protected TypeInfo getTypeVariable(TypeVariable<?> type)
{
return getTypeInfo(type.getBounds()[0]);
}
+
+ /**
+ * Wrapper around {@link ArrayType} to make it easier to
+ * create the name used to look up the array type infos
+ * in the cache
+ */
+ protected static class ModifiableArrayType extends ArrayType
+ {
+ int dims;
+
+ ModifiableArrayType(ArrayType original)
+ {
+ super(original.getDimension(), original.getComponentType());
+ dims = original.getDimension();
+ }
+
+ @Override
+ public int getDimension()
+ {
+ return dims;
+ }
+
+ void decrement()
+ {
+ dims--;
+ }
+ }
}
Added: projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistTypeVariableSpy.java
===================================================================
--- projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistTypeVariableSpy.java (rev 0)
+++ projects/jboss-reflect/trunk/src/main/java/org/jboss/reflect/plugins/javassist/JavassistTypeVariableSpy.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -0,0 +1,145 @@
+/*
+* 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 javassist.CtBehavior;
+import javassist.CtClass;
+import javassist.bytecode.SignatureAttribute.ClassSignature;
+import javassist.bytecode.SignatureAttribute.MethodSignature;
+import javassist.bytecode.SignatureAttribute.Type;
+import javassist.bytecode.SignatureAttribute.TypeParameter;
+import javassist.bytecode.SignatureAttribute.TypeVariable;
+
+/**
+ * When a type is of type {@link TypeVariable} this class helps determine what the actual type is
+ * from the signature of the member or the class
+ *
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+abstract class JavassistTypeVariableSpy
+{
+ /**
+ * Create a JavassistTypeVariableSpy for a method or constructor
+ *
+ * @param behavior the CtBehavior of the method or constructor
+ * @param sig the method signature
+ * @return the JavassistTypeVariableSpy
+ */
+ static JavassistTypeVariableSpy createForBehavior(CtBehavior behavior, MethodSignature sig)
+ {
+ return new MethodTypeVariable(behavior.getDeclaringClass(), sig);
+ }
+
+ /**
+ * Create a JavassistTypeVariableSpy for a class
+ *
+ * @param sig the class signature of the class
+ * @return the JavassistTypeVariableSpy
+ */
+ static JavassistTypeVariableSpy createForClass(ClassSignature sig)
+ {
+ return new ClassTypeVariable(sig);
+ }
+
+ /**
+ * Create a JavassistTypeVariableSpy for a field
+ *
+ * @param sig the class signature of the class containing the field
+ * @return the JavassistTypeVariableSpy
+ */
+ static JavassistTypeVariableSpy createForField(ClassSignature sig)
+ {
+ return new ClassTypeVariable(sig);
+ }
+
+ /**
+ * Get the actual bound of a type variable
+ *
+ * @param tv the type variable
+ * @throws IllegalStateException if the type can not be determined. This should only
+ * happen if the TypeVariable passed in does not belong to the signature used to
+ * create this JavassistTypeVariableSpy instance
+ */
+ abstract Type getTypeBound(TypeVariable tv);
+
+ private static Type getTypeFromTypeParameters(TypeVariable tv, TypeParameter[] parameters)
+ {
+ if (parameters == null)
+ return null;
+
+ for (int i = 0 ; i < parameters.length ; i++)
+ {
+ if (parameters[i].getName().equals(tv.getName()))
+ return parameters[i].getClassBound();
+ }
+
+ return null;
+ }
+
+ private static class MethodTypeVariable extends JavassistTypeVariableSpy
+ {
+ protected final CtClass clazz;
+ private final MethodSignature sig;
+
+ MethodTypeVariable(CtClass clazz, MethodSignature sig)
+ {
+ this.clazz = clazz;
+ this.sig = sig;
+ }
+
+ @Override
+ Type getTypeBound(TypeVariable tv)
+ {
+ Type type = getTypeFromTypeParameters(tv, sig.getTypeParameters());
+ if (type != null)
+ return type;
+
+ ClassSignature classSig = JavassistHelper.getClassSignature(clazz);
+ type = getTypeFromTypeParameters(tv, classSig.getParameters());
+ if (type != null)
+ return type;
+
+ throw new IllegalStateException("No type parameter found called " + tv.getName() + " in " + sig + " or in " + classSig);
+ }
+ }
+
+ private static class ClassTypeVariable extends JavassistTypeVariableSpy
+ {
+ private final ClassSignature sig;
+
+ public ClassTypeVariable(ClassSignature sig)
+ {
+ this.sig = sig;
+ }
+
+ @Override
+ Type getTypeBound(TypeVariable tv)
+ {
+ Type type = getTypeFromTypeParameters(tv, sig.getParameters());
+ if (type != null)
+ return type;
+
+ throw new IllegalStateException("No type parameter found called " + tv.getName() + " in " + sig);
+ }
+ }
+}
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-19 15:02:41 UTC (rev 102626)
@@ -0,0 +1,52 @@
+/*
+* 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
+{
+ static ClassLoader getContextClassLoader()
+ {
+ if (System.getSecurityManager() == null)
+ return Thread.currentThread().getContextClassLoader();
+ else
+ return AccessController.doPrivileged(GetContextClassLoaderAction.INSTANCE);
+ }
+
+ static class GetContextClassLoaderAction implements PrivilegedAction<ClassLoader>
+ {
+ final static GetContextClassLoaderAction INSTANCE = new GetContextClassLoaderAction();
+
+ public ClassLoader run()
+ {
+ return Thread.currentThread().getContextClassLoader();
+ }
+
+ }
+}
Added: projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoGenericSuperClassTypeVariable.java
===================================================================
--- projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoGenericSuperClassTypeVariable.java (rev 0)
+++ projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoGenericSuperClassTypeVariable.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -0,0 +1,32 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt 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.test.classinfo.support;
+
+/**
+ * ClassInfoSuperClass
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassInfoGenericSuperClassTypeVariable<T> extends ClassInfoGenericClass<T>
+{
+}
Added: projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoGenericSuperClassTypeVariableBounded.java
===================================================================
--- projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoGenericSuperClassTypeVariableBounded.java (rev 0)
+++ projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoGenericSuperClassTypeVariableBounded.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -0,0 +1,32 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt 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.test.classinfo.support;
+
+/**
+ * ClassInfoSuperClass
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassInfoGenericSuperClassTypeVariableBounded<T extends String> extends ClassInfoGenericClass<T>
+{
+}
Added: projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoGenericSuperInterfaceTypeVariable.java
===================================================================
--- projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoGenericSuperInterfaceTypeVariable.java (rev 0)
+++ projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoGenericSuperInterfaceTypeVariable.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -0,0 +1,32 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt 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.test.classinfo.support;
+
+/**
+ * ClassInfoGenericSuperInterfaceEmptyClass.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassInfoGenericSuperInterfaceTypeVariable<T> implements ClassInfoGenericInterface<T>
+{
+}
Added: projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoGenericSuperInterfaceTypeVariableBounded.java
===================================================================
--- projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoGenericSuperInterfaceTypeVariableBounded.java (rev 0)
+++ projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoGenericSuperInterfaceTypeVariableBounded.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -0,0 +1,32 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt 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.test.classinfo.support;
+
+/**
+ * ClassInfoGenericSuperInterfaceEmptyClass.
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassInfoGenericSuperInterfaceTypeVariableBounded<T extends String> implements ClassInfoGenericInterface<T>
+{
+}
Added: projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoTypeVariable.java
===================================================================
--- projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoTypeVariable.java (rev 0)
+++ projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoTypeVariable.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -0,0 +1,43 @@
+/*
+* 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.test.classinfo.support;
+
+import java.util.Collection;
+
+/**
+ *
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassInfoTypeVariable<E>
+{
+ public Collection<E> genericTypeVariable;
+
+ public <E> ClassInfoTypeVariable(Integer id, Collection<E> collA, Collection<E> collB, Collection<Long> collC)
+ {
+ }
+
+ public Collection<E> genericTypeVariable(Collection<E> collA, Collection<Long> collB)
+ {
+ return null;
+ }
+}
Added: projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoTypeVariableBounded.java
===================================================================
--- projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoTypeVariableBounded.java (rev 0)
+++ projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/support/ClassInfoTypeVariableBounded.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -0,0 +1,43 @@
+/*
+* 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.test.classinfo.support;
+
+import java.util.Collection;
+
+/**
+ *
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+public class ClassInfoTypeVariableBounded<E extends Number>
+{
+ public Collection<E> genericTypeVariableBounded;
+
+ public <E> ClassInfoTypeVariableBounded(Integer id, Collection<E> collA, Collection<E> collB, Collection<Long> collC)
+ {
+ }
+
+ public Collection<E> genericTypeVariableBounded(Collection<E> collA, Collection<Long> collB)
+ {
+ return null;
+ }
+}
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-19 14:22:56 UTC (rev 102625)
+++ projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/ClassInfoGenericClassTest.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -24,6 +24,7 @@
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
@@ -68,11 +69,15 @@
import org.jboss.test.classinfo.support.ClassInfoGenericSuperClassEmptyClass;
import org.jboss.test.classinfo.support.ClassInfoGenericSuperClassNotGeneric;
import org.jboss.test.classinfo.support.ClassInfoGenericSuperClassString;
+import org.jboss.test.classinfo.support.ClassInfoGenericSuperClassTypeVariable;
+import org.jboss.test.classinfo.support.ClassInfoGenericSuperClassTypeVariableBounded;
import org.jboss.test.classinfo.support.ClassInfoGenericSuperInterfaceCollection;
import org.jboss.test.classinfo.support.ClassInfoGenericSuperInterfaceComplicated;
import org.jboss.test.classinfo.support.ClassInfoGenericSuperInterfaceEmptyClass;
import org.jboss.test.classinfo.support.ClassInfoGenericSuperInterfaceNotGeneric;
import org.jboss.test.classinfo.support.ClassInfoGenericSuperInterfaceString;
+import org.jboss.test.classinfo.support.ClassInfoGenericSuperInterfaceTypeVariable;
+import org.jboss.test.classinfo.support.ClassInfoGenericSuperInterfaceTypeVariableBounded;
@@ -109,6 +114,16 @@
testGenericSuperClass(ClassInfoGenericSuperClassNotGeneric.class, ClassInfoGenericClass.class, new Class[0]);
}
+ public void testGenericSuperClassTypeVariable()
+ {
+ testGenericSuperClass(ClassInfoGenericSuperClassTypeVariable.class, ClassInfoGenericClass.class, new Class[] {Object.class});
+ }
+
+ public void testGenericSuperClassTypeVariableBounded()
+ {
+ testGenericSuperClass(ClassInfoGenericSuperClassTypeVariableBounded.class, ClassInfoGenericClass.class, new Class[] {String.class});
+ }
+
public void testGenericSuperClassCollection()
{
ParameterizedType type = assertInstanceOf(ClassInfoGenericSuperClassCollection.class.getGenericSuperclass(), ParameterizedType.class);
@@ -140,6 +155,16 @@
testGenericSuperInterface(ClassInfoGenericSuperInterfaceNotGeneric.class, ClassInfoGenericInterface.class, new Class[0]);
}
+ public void testGenericSuperInterfaceEmptyClassTypeVariable()
+ {
+ testGenericSuperInterface(ClassInfoGenericSuperInterfaceTypeVariable.class, ClassInfoGenericInterface.class, new Class[] { Object.class });
+ }
+
+ public void testGenericSuperInterfaceEmptyClassTypeVariableBounded()
+ {
+ testGenericSuperInterface(ClassInfoGenericSuperInterfaceTypeVariableBounded.class, ClassInfoGenericInterface.class, new Class[] { String.class });
+ }
+
public void testGenericSuperInterfaceCollection()
{
Type[] infos = ClassInfoGenericSuperInterfaceCollection.class.getGenericInterfaces();
@@ -759,7 +784,12 @@
Type[] reflectTypes = superClass.getActualTypeArguments();
assertEquals(genericTypes.length, reflectTypes.length);
for (int i = 0 ; i < genericTypes.length ; i++)
- assertEquals(genericTypes[i], reflectTypes[i]);
+ {
+ if (reflectTypes[i] instanceof TypeVariable)
+ assertEquals(genericTypes[i], ((TypeVariable)reflectTypes[i]).getBounds()[0]);
+ else
+ assertEquals(genericTypes[i], reflectTypes[i]);
+ }
//Compare the classinfo stuff vs raw reflect
TypeInfoFactory factory = getTypeInfoFactory();
@@ -791,7 +821,12 @@
Type[] reflectTypes = iface.getActualTypeArguments();
assertEquals(genericTypes.length, reflectTypes.length);
for (int i = 0 ; i < genericTypes.length ; i++)
- assertEquals(genericTypes[i], reflectTypes[i]);
+ {
+ if (reflectTypes[i] instanceof TypeVariable)
+ assertEquals(genericTypes[i], ((TypeVariable)reflectTypes[i]).getBounds()[0]);
+ else
+ assertEquals(genericTypes[i], reflectTypes[i]);
+ }
//Compare the classinfo stuff vs raw reflect
TypeInfoFactory factory = getTypeInfoFactory();
@@ -832,9 +867,12 @@
Class<?> typeClass = (Class<?>)reflectType;
assertEquals(typeClass.getName(), actualType.getName());
}
+ else if (reflectType instanceof TypeVariable)
+ {
+ assertTypeAgainstRawReflect(((TypeVariable)reflectType).getBounds()[0], actualType);
+ }
else
{
- //We might need to handle wildcards in which case we need to do something here
fail("Not yet implemented");
}
}
Added: projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/ClassInfoGenericMembersTest.java
===================================================================
--- projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/ClassInfoGenericMembersTest.java (rev 0)
+++ projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/ClassInfoGenericMembersTest.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -0,0 +1,532 @@
+/*
+* 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.test.classinfo.test;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.Collection;
+
+import org.jboss.reflect.spi.ArrayInfo;
+import org.jboss.reflect.spi.ClassInfo;
+import org.jboss.reflect.spi.ConstructorInfo;
+import org.jboss.reflect.spi.FieldInfo;
+import org.jboss.reflect.spi.MethodInfo;
+import org.jboss.reflect.spi.TypeInfo;
+import org.jboss.test.classinfo.support.ClassInfoTypeVariable;
+import org.jboss.test.classinfo.support.ClassInfoTypeVariableBounded;
+
+/**
+ *
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+public abstract class ClassInfoGenericMembersTest extends AbstractClassInfoTest
+{
+ @SuppressWarnings("unchecked")
+ public Collection notGeneric;
+
+ public Collection<String> generic;
+
+ public Collection<?> genericWildcard;
+
+ public Collection<? extends String> genericWildcardUpperBounded;
+
+ public Collection<? super String> genericWildcardLowerBounded;
+
+ public Collection<String>[] genericArray;
+
+ public ClassInfoGenericMembersTest(String name)
+ {
+ super(name);
+ }
+
+ //Todo
+ //mix primitives and generics, e.g. int someMethod(int, Class<String>)
+ //Test complex things
+
+ @SuppressWarnings("unchecked")
+ public ClassInfoGenericMembersTest(Long id, Collection collA, Collection collB, Collection collC)
+ {
+ super(id.toString());
+ }
+
+ public ClassInfoGenericMembersTest(Short id, Collection<String> collA, Collection<String> collB, Collection<Long> collC)
+ {
+ super(id.toString());
+ }
+
+ public ClassInfoGenericMembersTest(Boolean id, Collection<?> collA, Collection<?> collB, Collection<Long> collC)
+ {
+ super(id.toString());
+ }
+
+ public ClassInfoGenericMembersTest(Double id, Collection<? extends String> collA, Collection<? extends String> collB, Collection<Long> collC)
+ {
+ super(id.toString());
+ }
+
+ public ClassInfoGenericMembersTest(Float id, Collection<? super String> collA, Collection<? super String> collB, Collection<Long> collC)
+ {
+ super(id.toString());
+ }
+
+ public <E> ClassInfoGenericMembersTest(Integer id, Collection<E> collA, Collection<E> collB, Collection<Long> collC)
+ {
+ super(id.toString());
+ }
+
+ public <E extends String> ClassInfoGenericMembersTest(Number id, Collection<E> collA, Collection<E> collB, Collection<Long> collC)
+ {
+ super(id.toString());
+ }
+
+ public ClassInfoGenericMembersTest(System id, Collection<String>[][] collA, Collection<String>[][] collB, Collection<Long>[][] collC)
+ {
+ super(id.toString());
+ }
+
+ @SuppressWarnings("unchecked")
+ public ClassInfoGenericMembersTest(Runtime id, Collection<String> collA, Collection<String> collB, Collection collC)
+ {
+ super(id.toString());
+ }
+
+ public ClassInfoGenericMembersTest(Package id, Collection<String> collA, Collection<String> collB, long lng)
+ {
+ super(id.toString());
+ }
+
+ public void testNotGenericConstructor() throws Throwable
+ {
+ testConstructor(false, Long.class);
+ }
+
+ public void testGenericConstructor() throws Throwable
+ {
+ testConstructor(true, Short.class);
+ }
+
+ public void testGenericWildcardConstructor() throws Throwable
+ {
+ testConstructor(true, Boolean.class);
+ }
+
+ public void testGenericWildcardUpperBoundedConstructor() throws Throwable
+ {
+ testConstructor(true, Double.class);
+ }
+
+ public void testGenericWildcardLowerBoundedConstructor() throws Throwable
+ {
+ testConstructor(true, Float.class);
+ }
+
+ public void testGenericTypeVariableUpperBoundedConstructor() throws Throwable
+ {
+ testConstructor(true, Integer.class);
+ }
+
+ public void testGenericTypeVariableLowerBoundedConstructor() throws Throwable
+ {
+ testConstructor(true, Number.class);
+ }
+
+ public void testGenericTypeVariableUpperBoundedConstructorTypeFromClass() throws Throwable
+ {
+ testConstructor(true, ClassInfoTypeVariable.class, Integer.class);
+ }
+
+ public void testGenericTypeVariableLowerBoundedConstructorTypeFromClass() throws Throwable
+ {
+ testConstructor(true, ClassInfoTypeVariableBounded.class, Integer.class);
+ }
+
+ public void testGenericArrayConstructor() throws Throwable
+ {
+ testConstructor(true, System.class);
+ }
+
+ public void testMixGenericAndNonGenericConstructor() throws Throwable
+ {
+ testConstructor(true, Runtime.class);
+ }
+
+ public void testMixGenericAndPrimitivesConstructor() throws Throwable
+ {
+ testConstructor(true, Package.class);
+ }
+
+ @SuppressWarnings("unchecked")
+ public Collection notGeneric(Collection collA, Collection collB)
+ {
+ return null;
+ }
+
+ public Collection<String> generic(Collection<String> collA, Collection<Long> collB)
+ {
+ return null;
+ }
+
+ public Collection<?> genericWildcard(Collection<?> collA, Collection<Long> collB)
+ {
+ return null;
+ }
+
+ public Collection<? extends String> genericWildcardUpperBounded(Collection<? extends String> collA, Collection<Long> collB)
+ {
+ return null;
+ }
+
+ public Collection<? super String> genericWildcardLowerBounded(Collection<? super String> collA, Collection<Long> collB)
+ {
+ return null;
+ }
+
+ public <E> Collection<E> genericTypeVariable(Collection<E> collA, Collection<Long> collB)
+ {
+ return null;
+ }
+
+ public <E extends String> Collection<E> genericTypeVariableBounded(Collection<E> collA, Collection<Long> collB)
+ {
+ return null;
+ }
+
+ public Collection<String>[] genericArrayMethod(Collection<String>[] collA, Collection<Long>[] collB)
+ {
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Collection<String> mixGenericsAndNonGenerics(Collection<String> collA, Collection collB)
+ {
+ return null;
+ }
+
+ public Collection<String> mixGenericsAndPrimitives(Collection<String> collA, long l)
+ {
+ return null;
+ }
+
+ public void testNotGenericMethod() throws Throwable
+ {
+ testMethod(false, "notGeneric");
+ }
+
+ public void testGenericMethod() throws Throwable
+ {
+ testMethod(true, "generic");
+ }
+
+ public void testGenericWildcardMethod() throws Throwable
+ {
+ testMethod(true, "genericWildcard");
+ }
+
+ public void testGenericWildcardUpperBoundedMethod() throws Throwable
+ {
+ testMethod(true, "genericWildcardUpperBounded");
+ }
+
+ public void testGenericWildcardLowerBoundedMethod() throws Throwable
+ {
+ testMethod(true, "genericWildcardLowerBounded");
+ }
+
+ public void testGenericTypeVariableMethod() throws Throwable
+ {
+ testMethod(true, "genericTypeVariable");
+ }
+
+ public void testGenericArrayMethod() throws Throwable
+ {
+ testMethod(true, "genericArrayMethod");
+ }
+
+ public void testGenericTypeVariableMethodTypeFromClass() throws Throwable
+ {
+ testMethod(true, ClassInfoTypeVariable.class, "genericTypeVariable");
+ }
+
+ public void testGenericTypeVariableBoundedMethodTypeFromClass() throws Throwable
+ {
+ testMethod(true, ClassInfoTypeVariableBounded.class, "genericTypeVariableBounded");
+ }
+
+ public void testGenericTypeVariableBoundedMethod() throws Throwable
+ {
+ testMethod(true, "genericTypeVariableBounded");
+ }
+
+ public void testMixGenericsAndNonGenericsMethod() throws Throwable
+ {
+ testMethod(true, "mixGenericsAndNonGenerics");
+ }
+
+ public void testMixGenericsAndPrimitivesMethod() throws Throwable
+ {
+ testMethod(true, "mixGenericsAndPrimitives");
+ }
+
+ public void testNotGenericField() throws Throwable
+ {
+ testField("notGeneric");
+ }
+
+ public void testGenericField() throws Throwable
+ {
+ testField("generic");
+ }
+
+ public void testGenericWildcardField() throws Throwable
+ {
+ testField("genericWildcard");
+ }
+
+ public void testGenericWildcardUpperBoundedField() throws Throwable
+ {
+ testField("genericWildcardUpperBounded");
+ }
+
+ public void testGenericWildcardLowerBoundedField() throws Throwable
+ {
+ testField("genericWildcardLowerBounded");
+ }
+
+ public void testGenericTypeVariableFieldTypeFromClass() throws Throwable
+ {
+ testField(ClassInfoTypeVariable.class, "genericTypeVariable");
+ }
+
+ public void testGenericTypeVariableBoundedFieldTypeFromClass() throws Throwable
+ {
+ testField(ClassInfoTypeVariableBounded.class, "genericTypeVariableBounded");
+ }
+
+ public void testGenericArrayField() throws Throwable
+ {
+ testField("genericArray");
+ }
+
+ private void testMethod(boolean generic, String name) throws Throwable
+ {
+ testMethod(generic, ClassInfoGenericMembersTest.class, name);
+ }
+
+ private void testMethod(boolean generic, Class<?> clazz, String name) throws Throwable
+ {
+ ClassInfo info = getClassInfo(clazz);
+ Method m = getMethod(clazz, name);
+ MethodInfo minfo = getMethodInfo(info, name);
+
+ assertTypeAgainstRawReflect(m.getGenericReturnType(), minfo.getReturnType());
+
+ Type[] parameterTypes = m.getGenericParameterTypes();
+ TypeInfo[] parameterInfos = minfo.getParameterTypes();
+ assertEquals(parameterTypes.length, parameterInfos.length);
+ for (int i = 0 ; i < parameterTypes.length ; i++)
+ {
+ assertTypeAgainstRawReflect(parameterTypes[i], parameterInfos[i]);
+ }
+
+ assertEquals(m.getGenericReturnType(), parameterTypes[0]);
+ assertSame(minfo.getReturnType(), parameterInfos[0]);
+
+ if (!generic)
+ {
+ assertEquals(parameterTypes[0], parameterTypes[1]);
+ assertSame(parameterInfos[0], parameterInfos[1]);
+ }
+ else
+ {
+ assertNotSame(parameterInfos[0], parameterInfos[1]);
+ }
+ }
+
+ private void testConstructor(boolean generic, Class<?> id) throws Throwable
+ {
+ testConstructor(generic, ClassInfoGenericMembersTest.class, id);
+ }
+
+ private void testConstructor(boolean generic, Class<?> clazz, Class<?> id) throws Throwable
+ {
+ ClassInfo info = getClassInfo(clazz);
+ Constructor<?> c = getConstructor(clazz, id);
+ ConstructorInfo cinfo = getConstructorInfo(info, id);
+
+ Type[] parameterTypes = c.getGenericParameterTypes();
+ TypeInfo[] parameterInfos = cinfo.getParameterTypes();
+ assertEquals(parameterTypes.length, parameterInfos.length);
+ for (int i = 1 ; i < parameterTypes.length ; i++)
+ {
+ assertTypeAgainstRawReflect(parameterTypes[i], parameterInfos[i]);
+ }
+
+ assertEquals(parameterTypes[1], parameterTypes[2]);
+ assertSame(parameterInfos[1], parameterInfos[2]);
+
+ if (!generic)
+ {
+ assertEquals(parameterTypes[2], parameterTypes[3]);
+ assertSame(parameterInfos[2], parameterInfos[3]);
+ }
+ else
+ {
+ assertNotSame(parameterInfos[2], parameterInfos[3]);
+ }
+ }
+
+ private void testField(String name) throws Throwable
+ {
+ testField(ClassInfoGenericMembersTest.class, name);
+ }
+
+ private void testField(Class<?> clazz, String name) throws Throwable
+ {
+ ClassInfo info = getClassInfo(clazz);
+ Field f = getField(clazz, name);
+ FieldInfo finfo = getFieldInfo(info, name);
+
+ assertTypeAgainstRawReflect(f.getGenericType(), finfo.getType());
+ }
+
+ protected void assertTypeArgumentsAgainstRawReflect(Type[] reflectTypes, TypeInfo[] actualTypeArguments)
+ {
+ assertEquals(reflectTypes.length, actualTypeArguments.length);
+ for (int i = 0 ; i < reflectTypes.length ; i++)
+ {
+ assertTypeAgainstRawReflect(reflectTypes[i], actualTypeArguments[i]);
+ }
+ }
+
+ protected void assertTypeAgainstRawReflect(Type reflectType, TypeInfo actualType)
+ {
+ if (reflectType instanceof ParameterizedType)
+ {
+ ParameterizedType type = (ParameterizedType)reflectType;
+ Type rawType = type.getRawType();
+ assertTypeAgainstRawReflect(rawType, actualType);
+
+ assertTypeArgumentsAgainstRawReflect(type.getActualTypeArguments(), ((ClassInfo)actualType).getActualTypeArguments());
+ }
+ else if (reflectType instanceof Class)
+ {
+ Class<?> typeClass = (Class<?>)reflectType;
+ assertEquals(typeClass.getName(), actualType.getName());
+ }
+ else if (reflectType instanceof WildcardType)
+ {
+ WildcardType wtype = (WildcardType)reflectType;
+ if (wtype.getLowerBounds().length > 0)
+ assertTypeAgainstRawReflect(wtype.getLowerBounds()[0], actualType);
+ else
+ assertTypeAgainstRawReflect(wtype.getUpperBounds()[0], actualType);
+ }
+ else if (reflectType instanceof TypeVariable)
+ {
+ assertTypeAgainstRawReflect(((TypeVariable)reflectType).getBounds()[0], actualType);
+ }
+ else if (reflectType instanceof GenericArrayType)
+ {
+ ArrayInfo array = assertInstanceOf(actualType, ArrayInfo.class);
+ assertTypeAgainstRawReflect(((GenericArrayType)reflectType).getGenericComponentType(), array.getComponentType());
+ }
+ else
+ {
+ //We might need to handle wildcards in which case we need to do something here
+ fail("Not yet implemented " + reflectType);
+ }
+ }
+
+ private ClassInfo getClassInfo(Class<?> clazz)
+ {
+ TypeInfo info = getTypeInfoFactory().getTypeInfo(clazz);
+ return assertInstanceOf(info, ClassInfo.class);
+ }
+
+ private Method getMethod(Class<?> clazz, String name) throws Exception
+ {
+ for (Method m : clazz.getMethods())
+ {
+ if (m.getName().equals(name))
+ return m;
+ }
+ throw new IllegalArgumentException("No method called " + name);
+ }
+
+ private Constructor<?> getConstructor(Class<?> clazz, Class<?> id) throws Exception
+ {
+ for (Constructor<?> c : clazz.getConstructors())
+ {
+ if (c.getParameterTypes()[0].equals(id))
+ return c;
+ }
+ throw new IllegalArgumentException("No constructor");
+ }
+
+ private Field getField(Class<?> clazz, String name) throws Exception
+ {
+ for (Field f : clazz.getFields())
+ {
+ if (f.getName().equals(name))
+ return f;
+ }
+ throw new IllegalArgumentException("No field called " + name);
+ }
+
+ private MethodInfo getMethodInfo(ClassInfo classInfo, String name) throws Exception
+ {
+ for (MethodInfo m : classInfo.getDeclaredMethods())
+ {
+ if (m.getName().equals(name))
+ return m;
+ }
+ throw new IllegalArgumentException("No method called " + name);
+ }
+
+ private ConstructorInfo getConstructorInfo(ClassInfo classInfo, Class<?> clazz) throws Exception
+ {
+ for (ConstructorInfo c : classInfo.getDeclaredConstructors())
+ {
+ if (c.getParameterTypes()[0].getName().equals(clazz.getName()))
+ return c;
+ }
+ throw new IllegalArgumentException("No constructor");
+ }
+
+ private FieldInfo getFieldInfo(ClassInfo classInfo, String name) throws Exception
+ {
+ for (FieldInfo f : classInfo.getDeclaredFields())
+ {
+ if (f.getName().equals(name))
+ return f;
+ }
+ throw new IllegalArgumentException("No field called " + name);
+ }
+
+}
Modified: projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/ClassInfoTestSuite.java
===================================================================
--- projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/ClassInfoTestSuite.java 2010-03-19 14:22:56 UTC (rev 102625)
+++ projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/ClassInfoTestSuite.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -64,6 +64,8 @@
suite.addTest(JavassistGenericClassUnitTestCase.suite());
suite.addTest(FieldAccessRestrictionTestCase.suite());
suite.addTest(MethodAccessRestrictionTestCase.suite());
+ suite.addTest(IntrospectionClassInfoGenericMembersTestCase.suite());
+ suite.addTest(JavassistClassInfoGenericMembersTestCase.suite());
return suite;
}
Added: projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/IntrospectionClassInfoGenericMembersTestCase.java
===================================================================
--- projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/IntrospectionClassInfoGenericMembersTestCase.java (rev 0)
+++ projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/IntrospectionClassInfoGenericMembersTestCase.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -0,0 +1,52 @@
+/*
+* 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.test.classinfo.test;
+
+import junit.framework.Test;
+
+import org.jboss.reflect.plugins.introspection.IntrospectionTypeInfoFactory;
+import org.jboss.reflect.spi.TypeInfoFactory;
+
+/**
+ *
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+public class IntrospectionClassInfoGenericMembersTestCase extends ClassInfoGenericMembersTest
+{
+ public IntrospectionClassInfoGenericMembersTestCase(String name)
+ {
+ super(name);
+ }
+
+ public static Test suite()
+ {
+ return suite(IntrospectionClassInfoGenericMembersTestCase.class);
+ }
+
+ @Override
+ protected TypeInfoFactory getTypeInfoFactory()
+ {
+ return new IntrospectionTypeInfoFactory();
+ }
+
+}
Added: projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/JavassistClassInfoGenericMembersTestCase.java
===================================================================
--- projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/JavassistClassInfoGenericMembersTestCase.java (rev 0)
+++ projects/jboss-reflect/trunk/src/test/java/org/jboss/test/classinfo/test/JavassistClassInfoGenericMembersTestCase.java 2010-03-19 15:02:41 UTC (rev 102626)
@@ -0,0 +1,51 @@
+/*
+* 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.test.classinfo.test;
+
+import junit.framework.Test;
+
+import org.jboss.reflect.plugins.javassist.JavassistTypeInfoFactory;
+import org.jboss.reflect.spi.TypeInfoFactory;
+
+/**
+ *
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 1.1 $
+ */
+public class JavassistClassInfoGenericMembersTestCase extends ClassInfoGenericMembersTest
+{
+ public JavassistClassInfoGenericMembersTestCase(String name)
+ {
+ super(name);
+ }
+
+ public static Test suite()
+ {
+ return suite(JavassistClassInfoGenericMembersTestCase.class);
+ }
+
+ @Override
+ protected TypeInfoFactory getTypeInfoFactory()
+ {
+ return new JavassistTypeInfoFactory();
+ }
+}
More information about the jboss-cvs-commits
mailing list