public static Type extractConstraintValidatorTypeArgumentType(Class<? extends ConstraintValidator<?, ?>> validator, int typeArgumentIndex) { Map<Type, Type> resolvedTypes = new HashMap<>(); Type constraintValidatorType = resolveTypes( resolvedTypes, validator ); //we now have all bind from a type to its resolution at one level Type type = ( (ParameterizedType) constraintValidatorType ).getActualTypeArguments()[typeArgumentIndex]; if ( type == null ) { throw LOG.getNullIsAnInvalidTypeForAConstraintValidatorException(); } else if ( type instanceof GenericArrayType ) { type = TypeHelper.getArrayType( TypeHelper.getComponentType( type ) ); } while ( resolvedTypes.containsKey( type ) ) { type = resolvedTypes.get( type ); } //FIXME raise an exception if validatorType is not a class return type; }
private static Type extractType(Class<? extends ConstraintValidator<?, ?>> validator) { Map<Type, Type> resolvedTypes = newHashMap(); Type constraintValidatorType = resolveTypes( resolvedTypes, validator ); //we now have all bind from a type to its resolution at one level Type validatorType = ( (ParameterizedType) constraintValidatorType ).getActualTypeArguments()[VALIDATOR_TYPE_INDEX]; if ( validatorType == null ) { throw log.getNullIsAnInvalidTypeForAConstraintValidatorException(); } else if ( validatorType instanceof GenericArrayType ) { validatorType = TypeHelper.getArrayType( TypeHelper.getComponentType( validatorType ) ); } while ( resolvedTypes.containsKey( validatorType ) ) { validatorType = resolvedTypes.get( validatorType ); } //FIXME raise an exception if validatorType is not a class return validatorType; }
/** * Gets the erased type of the specified type. * * @param type the type to perform erasure on * * @return the erased type, never a parameterized type nor a type variable * * @see <a href="http://docs.oracle.com/javase/specs/jls/se6/html/typesValues.html#4.6">4.6 Type Erasure</a> */ public static Type getErasedType(Type type) { // the erasure of a parameterized type G<T1, ... ,Tn> is |G| if ( type instanceof ParameterizedType ) { Type rawType = ( (ParameterizedType) type ).getRawType(); return getErasedType( rawType ); } // TODO: the erasure of a nested type T.C is |T|.C // the erasure of an array type T[] is |T|[] if ( isArray( type ) ) { Type componentType = getComponentType( type ); Type erasedComponentType = getErasedType( componentType ); return getArrayType( erasedComponentType ); } // the erasure of a type variable is the erasure of its leftmost bound if ( type instanceof TypeVariable<?> ) { Type[] bounds = ( (TypeVariable<?>) type ).getBounds(); return getErasedType( bounds[0] ); } // the erasure of every other type is the type itself return type; }
Type erasedComponentType = getErasedType( componentType ); return getArrayType( erasedComponentType );