package org.theonefx.wcframework.ioc.val;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.HashMap;
import java.util.Map;
import org.theonefx.wcframework.utils.Assert;
/**
* 参数说明.Helper类,它封装了方法参数规格, 即方法或构造函数加一个参数索引和嵌套类型声明的泛型类型索引。 作为规范对象传递.
*/
public class MethodParameter {
private Method method;
private Constructor<?> constructor;
private final int parameterIndex;
private Class<?> parameterType;
private Type genericParameterType;
private Annotation[] parameterAnnotations;
/** 嵌套级别 */
private int nestingLevel = 1;
/** level => index 的MAP */
private Map<Integer, Integer> typeIndexesPerLevel;
Map<TypeVariable<?>, Type> typeVariableMap;
/**
* 根据给定的Method创建一个新的MethodParameter对象,其嵌套级别(nestingLevel)为1
*
* @param method
* 指定的参数所在的方法
* @param parameterIndex
* 参数索引
*/
public MethodParameter(Method method, int parameterIndex) {
this(method, parameterIndex, 1);
}
/**
* 根据给定的Method创建新的MethodParameter对象。
*
* @param method
* 指定的参数所在的方法
* @param parameterIndex
* 参数索引 (-1代表方法返回类型;0代表第一个参数;1代表第二个参数,后面以此类推)
* @param nestingLevel
* 目标类型的嵌套级别 (通常为 1; 例如:在二维列表的情况下, 1 代表外层封装List, 而2代表内层元素List)
*/
public MethodParameter(Method method, int parameterIndex, int nestingLevel) {
Assert.notNull(method, "Method must not be null");
this.method = method;
this.parameterIndex = parameterIndex;
this.nestingLevel = nestingLevel;
}
/**
* 根据给定的Constructor创建一个新的MethodParameter对象,其嵌套级别(nestingLevel)为1
*
* @param constructor
* 指定的参数所在的构造函数
* @param parameterIndex
* 参数索引
*/
public MethodParameter(Constructor<?> constructor, int parameterIndex) {
this(constructor, parameterIndex, 1);
}
/**
* 根据给定的Constructor创建一个新的MethodParameter对象.
*
* @param constructor
* 指定的参数所在的构造函数
* @param parameterIndex
* 参数索引
* @param nestingLevel
* 目标类型的嵌套级别 (通常为 1; 例如:在二维列表的情况下, 1 代表外层封装List, 而2代表内层元素List)
*/
public MethodParameter(Constructor<?> constructor, int parameterIndex, int nestingLevel) {
Assert.notNull(constructor, "Constructor must not be null");
this.constructor = constructor;
this.parameterIndex = parameterIndex;
this.nestingLevel = nestingLevel;
}
/**
* 通过复制原始MethodParameter来创建新的对象。
* 创建出一个和原始对象基于相同的元数据和缓存状态的新的独立的对象.
*
* @param original 复制的的原始MethodParameter对象
*/
public MethodParameter(MethodParameter original) {
Assert.notNull(original, "Original 不能为空");
this.method = original.method;
this.constructor = original.constructor;
this.parameterIndex = original.parameterIndex;
this.parameterType = original.parameterType;
this.parameterAnnotations = original.parameterAnnotations;
this.typeVariableMap = original.typeVariableMap;
}
public Method getMethod() {
return this.method;
}
public Constructor<?> getConstructor() {
return this.constructor;
}
public Class<?> getDeclaringClass() {
return (this.method != null ? this.method.getDeclaringClass() : this.constructor.getDeclaringClass());
}
/**
* 返回method/constructor的参数d索引号.
*
* @return 参数索引 (不可能为负值)
*/
public int getParameterIndex() {
return this.parameterIndex;
}
/**
* 设置一个解析过的(泛型)参数类型
*/
void setParameterType(Class<?> parameterType) {
this.parameterType = parameterType;
}
/**
* 返回method/constructor的参数的类型
*
* @return 参数类型(永远不可能为<code>null</code>)
*/
public Class<?> getParameterType() {
if (this.parameterType == null) {
if (this.parameterIndex < 0) {
this.parameterType = (this.method != null ? this.method.getReturnType() : null);
} else {
this.parameterType = (this.method != null ? this.method.getParameterTypes()[this.parameterIndex]
: this.constructor.getParameterTypes()[this.parameterIndex]);
}
}
return this.parameterType;
}
/**
* 返回method/constructor参数的泛型类型
*
* @return 参数类型(永远不可能为<code>null</code>)
*/
public Type getGenericParameterType() {
if (this.genericParameterType == null) {
if (this.parameterIndex < 0) {
this.genericParameterType = (this.method != null ? this.method.getGenericReturnType() : null);
} else {
this.genericParameterType = (this.method != null ? this.method.getGenericParameterTypes()[this.parameterIndex] : this.constructor
.getGenericParameterTypes()[this.parameterIndex]);
}
}
return this.genericParameterType;
}
/**
* 返回与method/constructor其本身关联的注解数组
*/
public Annotation[] getMethodAnnotations() {
return (this.method != null ? this.method.getAnnotations() : this.constructor.getAnnotations());
}
/**
* 返回与method/constructor本身关联的指定类型的注解
*
* @param annotationType 需要寻找的注解类型
* @return 注解对象, 或者<code>null</code>
*/
public <T extends Annotation> T getMethodAnnotation(Class<T> annotationType) {
return (this.method != null ? this.method.getAnnotation(annotationType) : (T) this.constructor.getAnnotation(annotationType));
}
/**
* 返回与method/constructor的参数关联的注解数组
*/
public Annotation[] getParameterAnnotations() {
if (this.parameterAnnotations == null) {
Annotation[][] annotationArray = (this.method != null ? this.method.getParameterAnnotations() : this.constructor.getParameterAnnotations());
if (this.parameterIndex >= 0 && this.parameterIndex < annotationArray.length) {
this.parameterAnnotations = annotationArray[this.parameterIndex];
} else {
this.parameterAnnotations = new Annotation[0];
}
}
return this.parameterAnnotations;
}
/**
* 返回参数指定类型的注解
*
* @param annotationType 需要寻找的注解类型
* @return 注解对象,找不到的话就返回<code>null</code>
*/
@SuppressWarnings("unchecked")
public <T extends Annotation> T getParameterAnnotation(Class<T> annotationType) {
Annotation[] anns = getParameterAnnotations();
for (Annotation ann : anns) {
if (annotationType.isInstance(ann)) {
return (T) ann;
}
}
return null;
}
/**
* 增加参数的嵌套级别
* @see #getNestingLevel()
*/
public void increaseNestingLevel() {
this.nestingLevel++;
}
/**
* 减少参数的嵌套级别
* @see #getNestingLevel()
*/
public void decreaseNestingLevel() {
getTypeIndexesPerLevel().remove(this.nestingLevel);
this.nestingLevel--;
}
/**
* 返回参数的嵌套级别 (通常情况下是1; 例如在一个列表的列表中,有1人表示嵌套列表,而2表示嵌套列表的元素).
*/
public int getNestingLevel() {
return this.nestingLevel;
}
/**
* 设置当前嵌套级别 的类型索引
*
* @param typeIndex 对应的类型索引, 如果为<code>null</code>代表默认的类型索引
* @see #getNestingLevel()
*/
public void setTypeIndexForCurrentLevel(int typeIndex) {
getTypeIndexesPerLevel().put(this.nestingLevel, typeIndex);
}
/**
* 返回当前嵌套级别 的类型索引
* @return 对应的类型索引, 如果为<code>null</code>代表没有指定(这代表这默认的类型索引)
* @see #getNestingLevel()
*/
public Integer getTypeIndexForCurrentLevel() {
return getTypeIndexForLevel(this.nestingLevel);
}
/**
* 返回指定嵌套级别 的类型索引
* @param nestingLevel 需要检查的嵌套级别
* @return 对应的类型索引, 如果为<code>null</code>代表没有指定(这代表这默认的类型索引)
*/
public Integer getTypeIndexForLevel(int nestingLevel) {
return getTypeIndexesPerLevel().get(nestingLevel);
}
/**
* 以延迟创建的方式获得typeIndexesPerLevel
*/
private Map<Integer, Integer> getTypeIndexesPerLevel() {
if (this.typeIndexesPerLevel == null) {
this.typeIndexesPerLevel = new HashMap<Integer, Integer>(4);
}
return this.typeIndexesPerLevel;
}
/**
* 根据给定的方法或者是构造函数创建一个新的MethodParameter对象
* <p>
* 这是一个便利的MethodParameter创建方式应用于如下情景:以通用的方式对待Method和Constructor
*
* @param methodOrConstructor 指定的参数所在的方法/构造函数
* @param parameterIndex 参数索引
* @return 对应的MethodParameter实例
*/
public static MethodParameter forMethodOrConstructor(Object methodOrConstructor, int parameterIndex) {
if (methodOrConstructor instanceof Method) {
return new MethodParameter((Method) methodOrConstructor, parameterIndex);
} else if (methodOrConstructor instanceof Constructor) {
return new MethodParameter((Constructor<?>) methodOrConstructor, parameterIndex);
} else {
throw new IllegalArgumentException("给定的对象[" + methodOrConstructor + "]既不是一个Method也不是一个Constructor");
}
}
}