/** * Create a type descriptor for a nested type declared within the method parameter. * <p>For example, if the methodParameter is a {@code List<String>} and the * nesting level is 1, the nested type descriptor will be String.class. * <p>If the methodParameter is a {@code List<List<String>>} and the nesting * level is 2, the nested type descriptor will also be a String.class. * <p>If the methodParameter is a {@code Map<Integer, String>} and the nesting * level is 1, the nested type descriptor will be String, derived from the map value. * <p>If the methodParameter is a {@code List<Map<Integer, String>>} and the * nesting level is 2, the nested type descriptor will be String, derived from the map value. * <p>Returns {@code null} if a nested type cannot be obtained because it was not declared. * For example, if the method parameter is a {@code List<?>}, the nested type * descriptor returned will be {@code null}. * @param methodParameter the method parameter with a nestingLevel of 1 * @param nestingLevel the nesting level of the collection/array element or * map key/value declaration within the method parameter * @return the nested type descriptor at the specified nesting level, * or {@code null} if it could not be obtained * @throws IllegalArgumentException if the nesting level of the input * {@link MethodParameter} argument is not 1, or if the types up to the * specified nesting level are not of collection, array, or map types */ @Nullable public static TypeDescriptor nested(MethodParameter methodParameter, int nestingLevel) { if (methodParameter.getNestingLevel() != 1) { throw new IllegalArgumentException("MethodParameter nesting level must be 1: " + "use the nestingLevel parameter to specify the desired nestingLevel for nested type traversal"); } return nested(new TypeDescriptor(methodParameter), nestingLevel); }
/** * Create a type descriptor for a nested type declared within the method parameter. * <p>For example, if the methodParameter is a {@code List<String>} and the * nesting level is 1, the nested type descriptor will be String.class. * <p>If the methodParameter is a {@code List<List<String>>} and the nesting * level is 2, the nested type descriptor will also be a String.class. * <p>If the methodParameter is a {@code Map<Integer, String>} and the nesting * level is 1, the nested type descriptor will be String, derived from the map value. * <p>If the methodParameter is a {@code List<Map<Integer, String>>} and the * nesting level is 2, the nested type descriptor will be String, derived from the map value. * <p>Returns {@code null} if a nested type cannot be obtained because it was not declared. * For example, if the method parameter is a {@code List<?>}, the nested type * descriptor returned will be {@code null}. * @param methodParameter the method parameter with a nestingLevel of 1 * @param nestingLevel the nesting level of the collection/array element or * map key/value declaration within the method parameter * @return the nested type descriptor at the specified nesting level, * or {@code null} if it could not be obtained * @throws IllegalArgumentException if the nesting level of the input * {@link MethodParameter} argument is not 1, or if the types up to the * specified nesting level are not of collection, array, or map types */ @Nullable public static TypeDescriptor nested(MethodParameter methodParameter, int nestingLevel) { if (methodParameter.getNestingLevel() != 1) { throw new IllegalArgumentException("MethodParameter nesting level must be 1: " + "use the nestingLevel parameter to specify the desired nestingLevel for nested type traversal"); } return nested(new TypeDescriptor(methodParameter), nestingLevel); }
/** * Return a {@link ResolvableType} for the specified {@link MethodParameter}, * overriding the target type to resolve with a specific given type. * @param methodParameter the source method parameter (must not be {@code null}) * @param targetType the type to resolve (a part of the method parameter's type) * @return a {@link ResolvableType} for the specified method parameter * @see #forMethodParameter(Method, int) */ public static ResolvableType forMethodParameter(MethodParameter methodParameter, @Nullable Type targetType) { Assert.notNull(methodParameter, "MethodParameter must not be null"); ResolvableType owner = forType(methodParameter.getContainingClass()).as(methodParameter.getDeclaringClass()); return forType(targetType, new MethodParameterTypeProvider(methodParameter), owner.asVariableResolver()). getNested(methodParameter.getNestingLevel(), methodParameter.typeIndexesPerLevel); }
/** * Return a {@link ResolvableType} for the specified {@link MethodParameter} with a * given implementation type. Use this variant when the class that declares the method * includes generic parameter variables that are satisfied by the implementation type. * @param methodParameter the source method parameter (must not be {@code null}) * @param implementationType the implementation type * @return a {@link ResolvableType} for the specified method parameter * @see #forMethodParameter(MethodParameter) */ public static ResolvableType forMethodParameter(MethodParameter methodParameter, @Nullable ResolvableType implementationType) { Assert.notNull(methodParameter, "MethodParameter must not be null"); implementationType = (implementationType != null ? implementationType : forType(methodParameter.getContainingClass())); ResolvableType owner = implementationType.as(methodParameter.getDeclaringClass()); return forType(null, new MethodParameterTypeProvider(methodParameter), owner.asVariableResolver()). getNested(methodParameter.getNestingLevel(), methodParameter.typeIndexesPerLevel); }
/** * Return a {@link ResolvableType} for the specified {@link MethodParameter}, * overriding the target type to resolve with a specific given type. * @param methodParameter the source method parameter (must not be {@code null}) * @param targetType the type to resolve (a part of the method parameter's type) * @return a {@link ResolvableType} for the specified method parameter * @see #forMethodParameter(Method, int) */ public static ResolvableType forMethodParameter(MethodParameter methodParameter, @Nullable Type targetType) { Assert.notNull(methodParameter, "MethodParameter must not be null"); ResolvableType owner = forType(methodParameter.getContainingClass()).as(methodParameter.getDeclaringClass()); return forType(targetType, new MethodParameterTypeProvider(methodParameter), owner.asVariableResolver()). getNested(methodParameter.getNestingLevel(), methodParameter.typeIndexesPerLevel); }
/** * Return a {@link ResolvableType} for the specified {@link MethodParameter} with a * given implementation type. Use this variant when the class that declares the method * includes generic parameter variables that are satisfied by the implementation type. * @param methodParameter the source method parameter (must not be {@code null}) * @param implementationType the implementation type * @return a {@link ResolvableType} for the specified method parameter * @see #forMethodParameter(MethodParameter) */ public static ResolvableType forMethodParameter(MethodParameter methodParameter, @Nullable ResolvableType implementationType) { Assert.notNull(methodParameter, "MethodParameter must not be null"); implementationType = (implementationType != null ? implementationType : forType(methodParameter.getContainingClass())); ResolvableType owner = implementationType.as(methodParameter.getDeclaringClass()); return forType(null, new MethodParameterTypeProvider(methodParameter), owner.asVariableResolver()). getNested(methodParameter.getNestingLevel(), methodParameter.typeIndexesPerLevel); }
public ParameterDescriptor(MethodParameter methodParameter) { super(methodParameter.getParameterType()); if (methodParameter.getNestingLevel() != 1) { throw new IllegalArgumentException("MethodParameter argument must have its nestingLevel set to 1"); } this.methodParameter = methodParameter; }
/** * Extract the generic parameter type from the given method or constructor. * @param methodParam the method parameter specification * @param source the source class/interface defining the generic parameter types * @param typeIndex the index of the type (e.g. 0 for Collections, * 0 for Map keys, 1 for Map values) * @return the generic type, or <code>null</code> if none */ private static Class<?> getGenericParameterType(MethodParameter methodParam, Class<?> source, int typeIndex) { return extractType(GenericTypeResolver.getTargetType(methodParam), source, typeIndex, methodParam.typeVariableMap, methodParam.typeIndexesPerLevel, methodParam.getNestingLevel(), 1); }
/** * Creates a type descriptor for a nested type declared within the method parameter. * For example, if the methodParameter is a List<String> and the nestingLevel is 1, the nested type descriptor will be String.class. * If the methodParameter is a List<List<String>> and the nestingLevel is 2, the nested type descriptor will also be a String.class. * If the methodParameter is a Map<Integer, String> and the nesting level is 1, the nested type descriptor will be String, derived from the map value. * If the methodParameter is a List<Map<Integer, String>> and the nesting level is 2, the nested type descriptor will be String, derived from the map value. * Returns null if a nested type cannot be obtained because it was not declared. * For example, if the method parameter is a List<?>, the nested type descriptor returned will be null. * @param methodParameter the method parameter with a nestingLevel of 1 * @param nestingLevel the nesting level of the collection/array element or map key/value declaration within the method parameter. * @return the nested type descriptor at the specified nesting level, or null if it could not be obtained. * @throws IllegalArgumentException if the nesting level of the input {@link MethodParameter} argument is not 1. * @throws IllegalArgumentException if the types up to the specified nesting level are not of collection, array, or map types. */ public static TypeDescriptor nested(MethodParameter methodParameter, int nestingLevel) { if (methodParameter.getNestingLevel() != 1) { throw new IllegalArgumentException("methodParameter nesting level must be 1: use the nestingLevel parameter to specify the desired nestingLevel for nested type traversal"); } return nested(new ParameterDescriptor(methodParameter), nestingLevel); }
/** * Extract the generic parameter type from the given method or constructor. * @param methodParam the method parameter specification * @param source the source class/interface defining the generic parameter types * @param typeIndex the index of the type (e.g. 0 for Collections, * 0 for Map keys, 1 for Map values) * @return the generic type, or <code>null</code> if none */ private static Class<?> getGenericParameterType(MethodParameter methodParam, Class<?> source, int typeIndex) { return extractType(GenericTypeResolver.getTargetType(methodParam), source, typeIndex, methodParam.typeVariableMap, methodParam.typeIndexesPerLevel, methodParam.getNestingLevel(), 1); }
/** * Creates a type descriptor for a nested type declared within the method parameter. * <p>For example, if the methodParameter is a {@code List<String>} and the * nesting level is 1, the nested type descriptor will be String.class. * <p>If the methodParameter is a {@code List<List<String>>} and the nesting * level is 2, the nested type descriptor will also be a String.class. * <p>If the methodParameter is a {@code Map<Integer, String>} and the nesting * level is 1, the nested type descriptor will be String, derived from the map value. * <p>If the methodParameter is a {@code List<Map<Integer, String>>} and the * nesting level is 2, the nested type descriptor will be String, derived from the map value. * <p>Returns {@code null} if a nested type cannot be obtained because it was not declared. * For example, if the method parameter is a {@code List<?>}, the nested type * descriptor returned will be {@code null}. * @param methodParameter the method parameter with a nestingLevel of 1 * @param nestingLevel the nesting level of the collection/array element or * map key/value declaration within the method parameter * @return the nested type descriptor at the specified nesting level, * or {@code null} if it could not be obtained * @throws IllegalArgumentException if the nesting level of the input * {@link MethodParameter} argument is not 1, or if the types up to the * specified nesting level are not of collection, array, or map types */ @Nullable public static TypeDescriptor nested(MethodParameter methodParameter, int nestingLevel) { if (methodParameter.getNestingLevel() != 1) { throw new IllegalArgumentException("MethodParameter nesting level must be 1: " + "use the nestingLevel parameter to specify the desired nestingLevel for nested type traversal"); } return nested(new TypeDescriptor(methodParameter), nestingLevel); }
/** * Return a {@link ResolvableType} for the specified {@link MethodParameter}, * overriding the target type to resolve with a specific given type. * @param methodParameter the source method parameter (must not be {@code null}) * @param targetType the type to resolve (a part of the method parameter's type) * @return a {@link ResolvableType} for the specified method parameter * @see #forMethodParameter(Method, int) */ public static ResolvableType forMethodParameter(MethodParameter methodParameter, @Nullable Type targetType) { Assert.notNull(methodParameter, "MethodParameter must not be null"); ResolvableType owner = forType(methodParameter.getContainingClass()).as(methodParameter.getDeclaringClass()); return forType(targetType, new MethodParameterTypeProvider(methodParameter), owner.asVariableResolver()). getNested(methodParameter.getNestingLevel(), methodParameter.typeIndexesPerLevel); }
if (methodParameter.getNestingLevel() != 1) { throw new IllegalArgumentException("MethodParameter nesting level must be 1: " + "use the nestingLevel parameter to specify the desired nestingLevel for nested type traversal");
/** * Return a {@link ResolvableType} for the specified {@link MethodParameter}, overriding the * target type to resolve with a specific given type. * * @param methodParameter the source method parameter (must not be {@code null}) * @param targetType the type to resolve (a part of the method parameter's type) * @return a {@link ResolvableType} for the specified method parameter * @see #forMethodParameter(Method, int) */ public static ResolvableType forMethodParameter(MethodParameter methodParameter, @Nullable Type targetType) { Assert.notNull(methodParameter, "MethodParameter must not be null"); ResolvableType owner = forType(methodParameter.getContainingClass()).as(methodParameter.getDeclaringClass()); return forType(targetType, new MethodParameterTypeProvider(methodParameter), owner.asVariableResolver()) .getNested(methodParameter.getNestingLevel(), methodParameter.typeIndexesPerLevel); }
/** * Return a {@link ResolvableType} for the specified {@link MethodParameter} with a * given implementation type. Use this variant when the class that declares the method * includes generic parameter variables that are satisfied by the implementation type. * @param methodParameter the source method parameter (must not be {@code null}) * @param implementationType the implementation type * @return a {@link ResolvableType} for the specified method parameter * @see #forMethodParameter(MethodParameter) */ public static ResolvableType forMethodParameter(MethodParameter methodParameter, @Nullable ResolvableType implementationType) { Assert.notNull(methodParameter, "MethodParameter must not be null"); implementationType = (implementationType != null ? implementationType : forType(methodParameter.getContainingClass())); ResolvableType owner = implementationType.as(methodParameter.getDeclaringClass()); return forType(null, new MethodParameterTypeProvider(methodParameter), owner.asVariableResolver()). getNested(methodParameter.getNestingLevel(), methodParameter.typeIndexesPerLevel); }