public ArrayElement(Type arrayType) { Class<?> arrayClass = ReflectionHelper.getClassFromType( arrayType ); if ( arrayClass.getComponentType().isPrimitive() ) { this.containerClass = arrayClass; } else { this.containerClass = Object[].class; } }
private static String toShortString(ParameterizedType parameterizedType) { Class<?> rawType = ReflectionHelper.getClassFromType( parameterizedType ); if ( rawType.getPackage() == null ) { return parameterizedType.toString(); } String typeArgumentsString = Arrays.stream( parameterizedType.getActualTypeArguments() ) .map( t -> toShortString( t ) ) .collect( Collectors.joining( ", ", "<", ">" ) ); return toShortString( rawType ) + typeArgumentsString; }
/** * Converts the given <code>Type</code> to a <code>Class</code>. * * @param type the type to convert * @return the class corresponding to the type */ public static Class<?> getClassFromType(Type type) { if ( type instanceof Class ) { return (Class<?>) type; } if ( type instanceof ParameterizedType ) { return getClassFromType( ( (ParameterizedType) type ).getRawType() ); } throw log.getUnableToConvertTypeToClassException( type ); }
/** * Converts the given {@code Type} to a {@code Class}. * * @param type the type to convert * @return the class corresponding to the type */ public static Class<?> getClassFromType(Type type) { if ( type instanceof Class ) { return (Class<?>) type; } if ( type instanceof ParameterizedType ) { return getClassFromType( ( (ParameterizedType) type ).getRawType() ); } if ( type instanceof GenericArrayType ) { return Object[].class; } throw LOG.getUnableToConvertTypeToClassException( type ); }
/** * Used to determine the possible value extractors that can be applied to a declared type. * <p> * Used when building cascading metadata in {@link CascadingMetaDataBuilder} to decide if it should be promoted to * {@link ContainerCascadingMetaData} with cascaded constrained type arguments. * <p> * An example could be when we need to upgrade BV 1.1 style {@code @Valid private List<SomeBean> list;} * to {@code private List<@Valid SomeBean> list;} * <p> * Searches only for maximally specific value extractors based on a type. * <p> * Types that are assignable to {@link Map} are handled as a special case - key value extractor is ignored for them. */ public Set<ValueExtractorDescriptor> getValueExtractorCandidatesForContainerDetectionOfGlobalCascadedValidation(Type enclosingType) { // if it's a Map assignable type, it gets a special treatment to conform to the Bean Validation specification boolean mapAssignable = TypeHelper.isAssignable( Map.class, enclosingType ); Class<?> enclosingClass = ReflectionHelper.getClassFromType( enclosingType ); return getRuntimeCompliantValueExtractors( enclosingClass, registeredValueExtractors ) .stream() .filter( ved -> !mapAssignable || !ved.equals( MapKeyExtractor.DESCRIPTOR ) ) .collect( Collectors.collectingAndThen( Collectors.toSet(), CollectionHelper::toImmutableSet ) ); }
private Map<TypeVariable<?>, CascadingMetaDataBuilder> getTypeParametersCascadingMetaDataForAnnotatedType(AnnotatedType annotatedType) { if ( annotatedType instanceof AnnotatedArrayType ) { return getTypeParametersCascadingMetaDataForArrayType( (AnnotatedArrayType) annotatedType ); } else if ( annotatedType instanceof AnnotatedParameterizedType ) { return getTypeParametersCascadingMetaDataForParameterizedType( (AnnotatedParameterizedType) annotatedType, ReflectionHelper.getClassFromType( annotatedType.getType() ).getTypeParameters() ); } else { return Collections.emptyMap(); } }
private static void determineValueExtractorDefinitions(List<AnnotatedType> valueExtractorDefinitions, Class<?> extractorImplementationType) { if ( !ValueExtractor.class.isAssignableFrom( extractorImplementationType ) ) { return; } Class<?> superClass = extractorImplementationType.getSuperclass(); if ( superClass != null && !Object.class.equals( superClass ) ) { determineValueExtractorDefinitions( valueExtractorDefinitions, superClass ); } for ( Class<?> implementedInterface : extractorImplementationType.getInterfaces() ) { if ( !ValueExtractor.class.equals( implementedInterface ) ) { determineValueExtractorDefinitions( valueExtractorDefinitions, implementedInterface ); } } for ( AnnotatedType annotatedInterface : extractorImplementationType.getAnnotatedInterfaces() ) { if ( ValueExtractor.class.equals( ReflectionHelper.getClassFromType( annotatedInterface.getType() ) ) ) { valueExtractorDefinitions.add( annotatedInterface ); } } }
private static Map<TypeVariable<?>, CascadingMetaDataBuilder> addCascadingMetaDataBasedOnContainerDetection(Type cascadableType, Map<TypeVariable<?>, CascadingMetaDataBuilder> containerElementTypesCascadingMetaData, Map<Class<?>, Class<?>> groupConversions, ValueExtractorDescriptor possibleValueExtractor) { Class<?> cascadableClass = ReflectionHelper.getClassFromType( cascadableType ); if ( cascadableClass.isArray() ) { // for arrays, we need to add an ArrayElement cascading metadata: it's the only way arrays support cascading at the moment. return addArrayElementCascadingMetaData( cascadableClass, containerElementTypesCascadingMetaData, groupConversions ); } else { Map<TypeVariable<?>, CascadingMetaDataBuilder> cascadingMetaData = containerElementTypesCascadingMetaData; cascadingMetaData = addCascadingMetaData( cascadableClass, possibleValueExtractor.getContainerType(), possibleValueExtractor.getExtractedTypeParameter(), cascadingMetaData, groupConversions ); return cascadingMetaData; } }
ContainerElementConstraintMappingContextImpl(TypeConstraintMappingContextImpl<?> typeContext, ContainerElementTarget parentContainerElementTarget, ConstraintLocation parentLocation, int index) { super( typeContext.getConstraintMapping(), parentLocation.getTypeForValidatorResolution() ); this.typeContext = typeContext; this.parentContainerElementTarget = parentContainerElementTarget; this.parentLocation = parentLocation; this.configuredType = parentLocation.getTypeForValidatorResolution(); // HV-1428 Container element support is disabled for arrays if ( TypeHelper.isArray( configuredType ) ) { throw LOG.getContainerElementConstraintsAndCascadedValidationNotSupportedOnArraysException( configuredType ); } if ( configuredType instanceof ParameterizedType ) { TypeVariable<?>[] typeParameters = ReflectionHelper.getClassFromType( configuredType ).getTypeParameters(); if ( index > typeParameters.length - 1 ) { throw LOG.getInvalidTypeArgumentIndexException( configuredType, index ); } else { this.typeParameter = typeParameters[index]; } } else { typeParameter = new ArrayElement( configuredType ); } this.index = index; this.constraints = new HashSet<>(); this.nestedContainerElementContexts = new HashMap<>(); }
for ( TypeVariable<?> typeVariable : ReflectionHelper.getClassFromType( annotatedType.getType() ).getTypeParameters() ) { AnnotatedType annotatedTypeParameter = annotatedParameterizedType.getAnnotatedActualTypeArguments()[i];
propertyPathNode = (NodeImpl) propertyPathIter.next(); clazz = ReflectionHelper.getClassFromType( ReflectionHelper.getCollectionElementType( propertyMetaData.getType() ) ); propertyMetaData = getBeanPropertyMetaData( clazz, propertyPathNode ); clazz = ReflectionHelper.getClassFromType( propertyMetaData.getType() );
TypeVariable<?>[] typeParameters = isArray ? new TypeVariable[0] : ReflectionHelper.getClassFromType( enclosingType ).getTypeParameters();
propertyPathNode = (NodeImpl) propertyPathIter.next(); clazz = ReflectionHelper.getClassFromType( ReflectionHelper.getCollectionElementType( propertyMetaData.getType() ) ); beanMetaData = beanMetaDataManager.getBeanMetaData( clazz ); propertyMetaData = getBeanPropertyMetaData( beanMetaData, propertyPathNode ); clazz = ReflectionHelper.getClassFromType( propertyMetaData.getType() );
if ( containerDetectionValueExtractorCandidates.size() > 1 ) { throw LOG.getUnableToGetMostSpecificValueExtractorDueToSeveralMaximallySpecificValueExtractorsDeclaredException( ReflectionHelper.getClassFromType( enclosingType ), ValueExtractorHelper.toValueExtractorClasses( containerDetectionValueExtractorCandidates ) );