org.frameworkset.util.MethodParameter Maven / Gradle / Ivy
Show all versions of bboss-util Show documentation
/*
* Copyright 2008 biaoping.yin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.frameworkset.util;
import com.frameworkset.util.EditorInf;
import org.frameworkset.util.ClassUtil.Var;
import org.frameworkset.util.annotations.MapKey;
import org.frameworkset.util.annotations.Scope;
import org.frameworkset.util.annotations.wraper.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* Title: MethodParameter.java
*
*
* Description:
*
*
* bboss workgroup
*
*
* Copyright (c) 2007
*
*
* @Date 2010-10-13 下午08:58:46
* @author biaoping.yin
* @version 1.0
*/
public class MethodParameter {
private static final Method methodParameterAnnotationsMethod = ClassUtils
.getMethodIfAvailable(Method.class, "getParameterAnnotations",
new Class[0]);
private static final Method constructorParameterAnnotationsMethod = ClassUtils
.getMethodIfAvailable(Constructor.class, "getParameterAnnotations",
new Class[0]);
private Method method;
private EditorInf editor;
private Constructor constructor;
private final int parameterIndex;
private Class parameterType;
private Object[] parameterAnnotations;
private ParameterNameDiscoverer parameterNameDiscoverer;
private boolean isrequestbody;
/**
* 请求参数名称
*/
private String parameterName;
private String origineRequestParamName;
public void setOrigineRequestParamName(String origineRequestParamName) {
this.origineRequestParamName = origineRequestParamName;
}
private boolean namevariabled = false;
public void setNamevariabled(boolean namevariabled) {
this.namevariabled = namevariabled;
}
public boolean isNamevariabled() {
return namevariabled;
}
public String getOrigineRequestParamName() {
return origineRequestParamName;
}
/**
* 参数名称由常量和变量部分组成,变量var中包含了变量对应的request参数名称和变量在整个参数名称中所处的位置
*/
private List requestParamNameToken;
public List getRequestParamNameToken() {
return requestParamNameToken;
}
public void setRequestParamNameToken(List requestParamNameToken) {
this.requestParamNameToken = requestParamNameToken;
}
private boolean dataBeanBind;
private Scope requestScope = null;
private int nestingLevel = 1;
/** Map from Integer level to Integer type index */
private Map typeIndexesPerLevel;
private Map typeVariableMap;
private String paramNamePrefix;
private RequestParamWraper requestParam;
private RequestHeaderWraper requestHeader;
private AttributeWraper attribute;
private PagerParamWraper pagerParam;
private RequestBodyWraper requestBody;
private MapKey mapKey;
private boolean primaryType;
/**
* 标识参数是否被多个不同类型的注解所注解
*/
private boolean multiAnnotations = false;
private List multiAnnotationParams;
/**
* Create a new MethodParameter for the given method, with nesting level 1.
*
* @param method
* the Method to specify a parameter for
* @param parameterIndex
* the index of the parameter
*/
public MethodParameter(Method method, int parameterIndex) {
this(method, parameterIndex, 1);
}
/**
* Create a new MethodParameter for the given method.
*
* @param method
* the Method to specify a parameter for
* @param parameterIndex
* the index of the parameter (-1 for the method return type; 0
* for the first method parameter, 1 for the second method
* parameter, etc)
* @param nestingLevel
* the nesting level of the target type (typically 1; e.g. in
* case of a List of Lists, 1 would indicate the nested List,
* whereas 2 would indicate the element of the nested 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;
}
/**
* Create a new MethodParameter for the given constructor, with nesting
* level 1.
*
* @param constructor
* the Constructor to specify a parameter for
* @param parameterIndex
* the index of the parameter
*/
public MethodParameter(Constructor constructor, int parameterIndex) {
this(constructor, parameterIndex, 1);
}
/**
* Create a new MethodParameter for the given constructor.
*
* @param constructor
* the Constructor to specify a parameter for
* @param parameterIndex
* the index of the parameter
* @param nestingLevel
* the nesting level of the target type (typically 1; e.g. in
* case of a List of Lists, 1 would indicate the nested List,
* whereas 2 would indicate the element of the nested 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;
}
/**
* Copy constructor, resulting in an independent MethodParameter object
* based on the same metadata and cache state that the original object was
* in.
*
* @param original
* the original MethodParameter object to copy from
*/
public MethodParameter(MethodParameter original) {
Assert.notNull(original, "Original must not be null");
this.method = original.method;
this.constructor = original.constructor;
this.parameterIndex = original.parameterIndex;
this.parameterType = original.parameterType;
this.parameterAnnotations = original.parameterAnnotations;
this.typeVariableMap = original.typeVariableMap;
}
/**
* Return the wrapped Method, if any.
*
* Note: Either Method or Constructor is available.
*
* @return the Method, or null
if none
*/
public Method getMethod() {
return this.method;
}
/**
* Return the wrapped Constructor, if any.
*
* Note: Either Method or Constructor is available.
*
* @return the Constructor, or null
if none
*/
public Constructor getConstructor() {
return this.constructor;
}
/**
* Return the index of the method/constructor parameter.
*
* @return the parameter index (never negative)
*/
public int getParameterIndex() {
return this.parameterIndex;
}
/**
* Set a resolved (generic) parameter type.
*/
void setParameterType(Class parameterType) {
this.parameterType = parameterType;
}
/**
* Return the type of the method/constructor parameter.
*
* @return the parameter type (never null
)
*/
public Class getParameterType() {
if (this.parameterType == null) {
this.parameterType = (this.method != null ? this.method
.getParameterTypes()[this.parameterIndex]
: this.constructor.getParameterTypes()[this.parameterIndex]);
}
return this.parameterType;
}
/**
* Return the annotations associated with the method/constructor parameter.
*
* @return the parameter annotations, or null
if there is no
* annotation support (on JDK < 1.5). The return value is an Object
* array instead of an Annotation array simply for compatibility
* with older JDKs; feel free to cast it to
* Annotation[]
on JDK 1.5 or higher.
*/
public Object[] getParameterAnnotations() {
if (this.parameterAnnotations != null) {
return this.parameterAnnotations;
}
if (methodParameterAnnotationsMethod == null) {
return null;
}
Object[][] annotationArray = (this.method != null ? ((Object[][]) ReflectionUtils
.invokeMethod(methodParameterAnnotationsMethod, this.method))
: ((Object[][]) ReflectionUtils
.invokeMethod(constructorParameterAnnotationsMethod,
this.constructor)));
this.parameterAnnotations = annotationArray[this.parameterIndex];
return this.parameterAnnotations;
}
/**
* Initialize parameter name discovery for this method parameter.
*
* This method does not actually try to retrieve the parameter name at this
* point; it just allows discovery to happen when the application calls
*/
public void initParameterNameDiscovery(
ParameterNameDiscoverer parameterNameDiscoverer) {
this.parameterNameDiscoverer = parameterNameDiscoverer;
}
/**
* Return the name of the method/constructor parameter.
*
* @return the parameter name (may be null
if no parameter name
* metadata is contained in the class file or no
* {@link #initParameterNameDiscovery ParameterNameDiscoverer} has
* been set to begin with)
*/
public String getMethodParameterName() {
String parameterName = null;
if (parameterName == null && this.parameterNameDiscoverer != null) {
String[] parameterNames = (this.method != null ? this.parameterNameDiscoverer
.getParameterNames(this.method)
: this.parameterNameDiscoverer
.getParameterNames(this.constructor));
if (parameterNames != null) {
parameterName = parameterNames[this.parameterIndex];
}
this.parameterNameDiscoverer = null;
}
return parameterName;
}
public String getRequestParameterName() {
return this.parameterName;
}
/**
* Increase this parameter's nesting level.
*
* @see #getNestingLevel()
*/
public void increaseNestingLevel() {
this.nestingLevel++;
}
/**
* Decrease this parameter's nesting level.
*
* @see #getNestingLevel()
*/
public void decreaseNestingLevel() {
getTypeIndexesPerLevel().remove(new Integer(this.nestingLevel));
this.nestingLevel--;
}
/**
* Return the nesting level of the target type (typically 1; e.g. in case of
* a List of Lists, 1 would indicate the nested List, whereas 2 would
* indicate the element of the nested List).
*/
public int getNestingLevel() {
return this.nestingLevel;
}
/**
* Set the type index for the current nesting level.
*
* @param typeIndex
* the corresponding type index (or null
for the
* default type index)
* @see #getNestingLevel()
*/
public void setTypeIndexForCurrentLevel(int typeIndex) {
getTypeIndexesPerLevel().put(new Integer(this.nestingLevel),
new Integer(typeIndex));
}
/**
* Return the type index for the current nesting level.
*
* @return the corresponding type index, or null
if none
* specified (indicating the default type index)
* @see #getNestingLevel()
*/
public Integer getTypeIndexForCurrentLevel() {
return getTypeIndexForLevel(this.nestingLevel);
}
/**
* Return the type index for the specified nesting level.
*
* @param nestingLevel
* the nesting level to check
* @return the corresponding type index, or null
if none
* specified (indicating the default type index)
*/
public Integer getTypeIndexForLevel(int nestingLevel) {
return (Integer) getTypeIndexesPerLevel()
.get(new Integer(nestingLevel));
}
/**
* Obtain the (lazily constructed) type-indexes-per-level Map.
*/
private Map getTypeIndexesPerLevel() {
if (this.typeIndexesPerLevel == null) {
this.typeIndexesPerLevel = new HashMap(4);
}
return this.typeIndexesPerLevel;
}
/**
* Create a new MethodParameter for the given method or constructor.
*
* This is a convenience constructor for scenarios where a Method or
* Constructor reference is treated in a generic fashion.
*
* @param methodOrConstructor
* the Method or Constructor to specify a parameter for
* @param parameterIndex
* the index of the parameter
* @return the corresponding MethodParameter instance
*/
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("Given object ["
+ methodOrConstructor
+ "] is neither a Method nor a Constructor");
}
}
public EditorInf getEditor() {
return editor;
}
public void setEditor(EditorInf editor) {
this.editor = editor;
}
public void setParameterName(String parameterName) {
this.parameterName = parameterName;
}
public void setDataBeanBind(boolean dataBeanBind) {
this.dataBeanBind = dataBeanBind;
}
public boolean isDataBeanBind()
{
return this.dataBeanBind;
}
public void setDataBindScope(Scope requestScope) {
this.requestScope = requestScope;
}
public Scope getDataBindScope() {
return requestScope;
}
private boolean required = false;
public void setRequired(boolean required) {
this.required = required;
}
public boolean isRequired()
{
return this.required;
}
private Object defaultValue;
public Object getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(Object defaultValue) {
this.defaultValue = defaultValue;
}
public boolean isMultiAnnotations() {
return multiAnnotations;
}
public void setMultiAnnotations(boolean multiAnnotations) {
this.multiAnnotations = multiAnnotations;
}
public List getMultiAnnotationParams() {
return multiAnnotationParams;
}
public void setMultiAnnotationParams(
List multiAnnotationParams) {
if(multiAnnotationParams != null && multiAnnotationParams.size() > 0)
this.setMultiAnnotations(true);
this.multiAnnotationParams = multiAnnotationParams;
}
public Map getTypeVariableMap() {
return typeVariableMap;
}
protected void setTypeVariableMap(Map typeVariableMap) {
this.typeVariableMap = typeVariableMap;
}
/**
* @return the paramNamePrefix
*/
public String getParamNamePrefix() {
return paramNamePrefix;
}
/**
* @param paramNamePrefix the paramNamePrefix to set
*/
public void setParamNamePrefix(String paramNamePrefix) {
this.paramNamePrefix = paramNamePrefix;
}
/**
* @return the requestParam
*/
public RequestParamWraper getRequestParam() {
return requestParam;
}
/**
* @param requestParam the requestParam to set
*/
public void setRequestParam(RequestParamWraper requestParam) {
this.requestParam = requestParam;
}
private PathVariableWraper pathVariable;
public void setPathVariable(PathVariableWraper param) {
pathVariable = param;
}
private CookieValueWraper cookieValue;
/**
* @return the pathVariable
*/
public PathVariableWraper getPathVariable() {
return pathVariable;
}
/**
* @return the cookieValue
*/
public CookieValueWraper getCookieValue() {
return cookieValue;
}
/**
* @param cookieValue the cookieValue to set
*/
public void setCookieValue(CookieValueWraper cookieValue) {
this.cookieValue = cookieValue;
}
// private AttributeWraper attribute;
/**
* @return the attribute
*/
public AttributeWraper getAttribute() {
return attribute;
}
/**
* @param attribute the attribute to set
*/
public void setAttribute(AttributeWraper attribute) {
this.attribute = attribute;
}
/**
* @return the requestHeader
*/
public RequestHeaderWraper getRequestHeader() {
return requestHeader;
}
/**
* @param requestHeader the requestHeader to set
*/
public void setRequestHeader(RequestHeaderWraper requestHeader) {
this.requestHeader = requestHeader;
}
public void setMapKey(MapKey mapKey)
{
this.mapKey = mapKey;
}
public MapKey getMapKey()
{
return mapKey;
}
public boolean isPrimaryType() {
return primaryType;
}
public void setPrimaryType(boolean isPrimaryType) {
this.primaryType = isPrimaryType;
}
public PagerParamWraper getPagerParam() {
return pagerParam;
}
public void setPagerParam(PagerParamWraper pagerParam) {
this.pagerParam = pagerParam;
}
public boolean isIsrequestbody() {
return isrequestbody;
}
public void setIsrequestbody(boolean isrequestbody) {
this.isrequestbody = isrequestbody;
}
public RequestBodyWraper getRequestBody() {
return requestBody;
}
public void setRequestBody(RequestBodyWraper requestBody) {
this.requestBody = requestBody;
}
private boolean innerRequestBody(){
if(this.multiAnnotationParams == null || this.multiAnnotationParams.size() == 0){
return false;
}
for(MethodParameter p:multiAnnotationParams){
if(p.getRequestBody() != null)
{
return true;
}
}
return false;
}
/**
* 判断参数是否带requestbody注解
* @return
*/
public boolean requestbody() {
return isrequestbody || innerRequestBody();
}
}