diff --git a/src/main/java/org/hibernate/annotations/common/reflection/ReflectionManager.java b/src/main/java/org/hibernate/annotations/common/reflection/ReflectionManager.java
index 8f2eb72..045dbca 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/ReflectionManager.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/ReflectionManager.java
@@ -8,6 +8,7 @@
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
+import java.lang.reflect.Type;
import java.util.Map;
/**
@@ -23,6 +24,8 @@ public interface ReflectionManager {
public Class toClass(XClass xClazz);
+ public Type toType(XClass xClazz);
+
public Method toMethod(XMethod method);
public XPackage toXPackage(Package pkg);
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaReflectionManager.java b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaReflectionManager.java
index d0b6858..39e62ee 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/JavaReflectionManager.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/JavaReflectionManager.java
@@ -175,6 +175,37 @@ public JavaXType toXType(TypeEnvironment context, Type propType) {
throw new IllegalArgumentException( "No PropertyTypeExtractor available for type void " );
}
+ @Override
+ public Type toType(XClass xClazz) {
+ if ( ! ( xClazz instanceof JavaXClass ) ) {
+ throw new IllegalArgumentException( "XClass not coming from this ReflectionManager implementation" );
+ }
+ final JavaXClass javaXClazz = (JavaXClass) xClazz;
+ final Class> clazz = javaXClazz.toClass();
+ final Type[] typeArguments = clazz.getTypeParameters();
+ if ( typeArguments.length == 0 ) {
+ return clazz;
+ }
+ return javaXClazz.getTypeEnvironment().bind(
+ new ParameterizedType() {
+ @Override
+ public Type[] getActualTypeArguments() {
+ return typeArguments;
+ }
+
+ @Override
+ public Type getRawType() {
+ return clazz;
+ }
+
+ @Override
+ public Type getOwnerType() {
+ return null;
+ }
+ }
+ );
+ }
+
public boolean equals(XClass class1, Class class2) {
if ( class1 == null ) {
return class2 == null;
diff --git a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeFactory.java b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeFactory.java
index 07795e5..2a79ec5 100644
--- a/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeFactory.java
+++ b/src/main/java/org/hibernate/annotations/common/reflection/java/generics/TypeFactory.java
@@ -11,6 +11,7 @@
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
+import java.util.StringJoiner;
/**
* This class instances our own ParameterizedTypes
and GenericArrayTypes
.
@@ -57,6 +58,42 @@ public int hashCode() {
getOwnerType()
);
}
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ if ( ownerType != null ) {
+ sb.append( ownerType.getTypeName() );
+
+ sb.append( "$" );
+
+ if ( ownerType instanceof ParameterizedType ) {
+ // Find simple name of nested type by removing the
+ // shared prefix with owner.
+ sb.append(
+ rawType.getTypeName().replace(
+ ( (ParameterizedType) ownerType ).getRawType().getTypeName() + "$",
+ ""
+ )
+ );
+ } else if ( rawType instanceof Class> ) {
+ sb.append( ( (Class>) rawType ).getSimpleName() );
+ } else
+ sb.append( rawType.getTypeName() );
+ } else
+ sb.append( rawType.getTypeName() );
+
+ if ( substTypeArgs != null ) {
+ final StringJoiner sj = new StringJoiner( ", ", "<", ">" );
+ sj.setEmptyValue( "" );
+ for ( Type t : substTypeArgs ) {
+ sj.add( t.getTypeName() );
+ }
+ sb.append( sj );
+ }
+
+ return sb.toString();
+ }
};
}
diff --git a/src/test/java/org/hibernate/annotations/common/test/reflection/java/JavaXClassTest.java b/src/test/java/org/hibernate/annotations/common/test/reflection/java/JavaXClassTest.java
index 71777d3..d7a6f1e 100644
--- a/src/test/java/org/hibernate/annotations/common/test/reflection/java/JavaXClassTest.java
+++ b/src/test/java/org/hibernate/annotations/common/test/reflection/java/JavaXClassTest.java
@@ -7,6 +7,8 @@
package org.hibernate.annotations.common.test.reflection.java;
import java.io.Serializable;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
import java.util.List;
import org.hibernate.annotations.common.reflection.ReflectionManager;
@@ -88,6 +90,19 @@ public void testCanBeAnEnum() {
assertTrue( factory.toXClass( Sex.class ).isEnum() );
}
+ public void testParameterizedType() {
+ Type type = factory.toType(
+ fatherAsSeenFromSon.getDeclaredProperties( "property" )
+ .stream()
+ .filter( p -> p.getName().equals( "genericCollectionProperty" ) )
+ .findFirst()
+ .get()
+ .getType()
+ );
+ assertTrue( type instanceof ParameterizedType );
+ assertEquals( String.class, ((ParameterizedType) type).getActualTypeArguments()[0] );
+ }
+
@Override
protected XAnnotatedElement getConcreteInstance() {
return factory.toXClass( Dad.class );