net.gdface.codegen.Method Maven / Gradle / Ivy
/**
* @Title: Method.java
* @Package net.gdface.codegen.wsdl
* @Description:
* @author guyadong
* @date 2015年7月14日 上午9:34:17
* @version V1.0
*/
package net.gdface.codegen;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import net.gdface.annotation.DeriveMethod;
import net.gdface.reflection.generics.EnhancedTypeResolver;
import net.gdface.utils.Assert;
import net.gdface.utils.TypeNameUtils;
/**
* @author guyadong
*
*/
public class Method {
public class Parameter {
public final Class> type;
public final String name;
public final Type genericType;
private final Map, Annotation> annotation;
private Parameter(String name, Class> type, Type genericType,
Map, Annotation> annotation) {
this.name = name;
this.type = type;
this.genericType = genericType;
this.annotation = annotation;
}
/**
* @param annotationClass
* @see java.util.Map#get(java.lang.Object)
*/
@SuppressWarnings("unchecked")
public T getAnnotation(Class annotationClass) {
Assert.notNull(annotationClass, "annotationClass");
return (T) annotation.get(annotationClass);
}
@SuppressWarnings("unchecked")
public T getAnnotation(String annotationClassName) {
Assert.notNull(annotationClassName, "annotationClass");
for(Annotation ann:annotation.values()){
if(ann.annotationType().getName().endsWith(annotationClassName)){
return (T) ann;
}
}
return null;
}
/**
* @see java.util.Map#values()
*/
public Collection getAnnotations() {
return annotation.values();
}
/**
* @return type
*/
public Class> getType() {
return type;
}
/**
* @return name
*/
public String getName() {
return name;
}
/**
* @return genericType
*/
public Type getGenericType() {
return genericType;
}
}
private final java.lang.reflect.Method method;
private final String[] parameterNames;
private final Map paramMap;
private final Parameter[] parameters;
private final String docSignature;
private final Set catalogs ;
private static final Predicate EMPTY_PREDICATE = new Predicate(){
@Override
public boolean apply(String input) {
return !Strings.isNullOrEmpty(input);
}};
private static final Function TRIM_FUNCTION = new Function(){
@Override
public String apply(String input) {
return input.trim();
}};
/**
* @param method
* @param parameterNames
*/
public Method(java.lang.reflect.Method method, String[] parameterNames) {
Assert.notNull(method, "method");
Class>[] types = method.getParameterTypes();
if (null != parameterNames && parameterNames.length != types.length){
throw new IllegalArgumentException("parameterNames length not equals actually parameter number");
}
this.method = method;
if (null == parameterNames) {
parameterNames = new String[types.length];
for (int i = 0; i < parameterNames.length; i++)
parameterNames[i] = String.format("arg%d", i);
}
this.parameterNames = parameterNames;
this.parameters = createParameters();
paramMap = createParamMap(parameters);
docSignature = getDocSignature(true);
DeriveMethod deriveMethod = this.method.getAnnotation(DeriveMethod.class);
if(deriveMethod != null){
Iterable iterable = Iterables.filter(Lists.newArrayList(deriveMethod.catalogs()), Predicates.compose(EMPTY_PREDICATE, TRIM_FUNCTION));
this.catalogs = ImmutableSet.copyOf(iterable);
}else{
this.catalogs = Collections.emptySet();
}
}
private Parameter[] createParameters() {
Parameter[] parameters = new Parameter[this.parameterNames.length];
Annotation[][] parameterAnnotations = this.getParameterAnnotations();
Class>[] parameterTypes = this.getParameterTypes();
Type[] genericParameterTypes = this.getGenericParameterTypes();
for (int i = 0; i < parameters.length; i++) {
parameters[i] = new Parameter(parameterNames[i], parameterTypes[i], genericParameterTypes[i],
getParameterAnnotationMap(parameterAnnotations[i]));
}
return parameters;
}
private final Map createParamMap(Parameter[] parameters) {
HashMap map = new HashMap(parameters.length);
for (Parameter p : parameters)
map.put(p.name, p);
return map;
}
private Map, Annotation> getParameterAnnotationMap(Annotation[] parameterAnnotations) {
Map, Annotation> map = new HashMap, Annotation>(
parameterAnnotations.length);
for (Annotation annotation : parameterAnnotations)
map.put(annotation.annotationType(), annotation);
return map;
}
/**
* @param flag
* @throws SecurityException
* @see java.lang.reflect.AccessibleObject#setAccessible(boolean)
*/
public void setAccessible(boolean flag) throws SecurityException {
method.setAccessible(flag);
}
/**
* @see java.lang.reflect.AccessibleObject#isAccessible()
*/
public boolean isAccessible() {
return method.isAccessible();
}
/**
* @see java.lang.reflect.Method#getDeclaringClass()
*/
public Class> getDeclaringClass() {
return method.getDeclaringClass();
}
/**
* @see java.lang.reflect.Method#getName()
*/
public String getName() {
return method.getName();
}
/**
* @see java.lang.reflect.Method#getModifiers()
*/
public int getModifiers() {
return method.getModifiers();
}
/**
* @param annotationClass
* @see java.lang.reflect.AccessibleObject#isAnnotationPresent(java.lang.Class)
*/
public boolean isAnnotationPresent(Class extends Annotation> annotationClass) {
return method.isAnnotationPresent(annotationClass);
}
/**
* @see java.lang.reflect.Method#getTypeParameters()
*/
public TypeVariable[] getTypeParameters() {
return method.getTypeParameters();
}
/**
* @see java.lang.reflect.AccessibleObject#getAnnotations()
*/
public Annotation[] getAnnotations() {
return method.getAnnotations();
}
/**
* @see java.lang.reflect.Method#getReturnType()
*/
public Class> getReturnType() {
return method.getReturnType();
}
/**
* @see java.lang.reflect.Method#getGenericReturnType()
*/
public Type getGenericReturnType() {
return method.getGenericReturnType();
}
/**
* @see java.lang.reflect.Method#getParameterTypes()
*/
public Class>[] getParameterTypes() {
return method.getParameterTypes();
}
/**
* @see java.lang.reflect.Method#getGenericParameterTypes()
*/
public Type[] getGenericParameterTypes() {
return method.getGenericParameterTypes();
}
/**
* @see java.lang.reflect.Method#getExceptionTypes()
*/
public Class>[] getExceptionTypes() {
return method.getExceptionTypes();
}
/**
* @see java.lang.reflect.Method#getGenericExceptionTypes()
*/
public Type[] getGenericExceptionTypes() {
return method.getGenericExceptionTypes();
}
/**
* @param obj
* @see java.lang.reflect.Method#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
return method.equals(obj);
}
/**
* @see java.lang.reflect.Method#hashCode()
*/
public int hashCode() {
return method.hashCode();
}
/**
* @param obj
* @param args
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @see java.lang.reflect.Method#invoke(java.lang.Object, java.lang.Object[])
*/
public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException {
return method.invoke(obj, args);
}
/**
* @see java.lang.reflect.Method#isBridge()
*/
public boolean isBridge() {
return method.isBridge();
}
/**
* @see java.lang.reflect.Method#isVarArgs()
*/
public boolean isVarArgs() {
return method.isVarArgs();
}
/**
* @see java.lang.reflect.Method#isSynthetic()
*/
public boolean isSynthetic() {
return method.isSynthetic();
}
/**
* @param annotationClass
* @see java.lang.reflect.Method#getAnnotation(java.lang.Class)
*/
public T getAnnotation(Class annotationClass) {
return method.getAnnotation(annotationClass);
}
/**
* @see java.lang.reflect.Method#getDeclaredAnnotations()
*/
public Annotation[] getDeclaredAnnotations() {
return method.getDeclaredAnnotations();
}
/**
* @see java.lang.reflect.Method#getDefaultValue()
*/
public Object getDefaultValue() {
return method.getDefaultValue();
}
/**
* @see java.lang.reflect.Method#getParameterAnnotations()
*/
public Annotation[][] getParameterAnnotations() {
return method.getParameterAnnotations();
}
/**
* @param name
* @see java.util.Map#get(java.lang.Object)
*/
public Parameter getParameter(String name) {
return paramMap.get(name);
}
/**
* @return parameterNames
*/
public String[] getParameterNames() {
return parameterNames;
}
private static final int LANGUAGE_MODIFIERS = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE
| Modifier.ABSTRACT | Modifier.STATIC | Modifier.FINAL | Modifier.SYNCHRONIZED | Modifier.NATIVE;
/**
*
* @see java.lang.reflect.Method#toGenericString()
*/
public String toGenericString() {
return toGenericString(false);
}
/**
* 输出类名简写的(泛型)方法描述字符串
*
* @param resolver
* @param fullClassName
* 是否显示类的全名
* @see java.lang.reflect.Method#toGenericString()
* @since 2.2.9
*/
public String toGenericString(EnhancedTypeResolver resolver, boolean fullClassName) {
try {
StringBuilder sb = new StringBuilder();
int mod = getModifiers() & LANGUAGE_MODIFIERS;
if (mod != 0) {
sb.append(Modifier.toString(mod) + " ");
}
Type[] typeparms = getTypeParameters();
if (typeparms.length > 0) {
boolean first = true;
sb.append("<");
for (Type typeparm : typeparms) {
if (!first)
sb.append(",");
sb.append(TypeNameUtils.getTypeName(typeparm, fullClassName));
/*
* if (typeparm instanceof Class) sb.append(((Class>) typeparm).getName()); else
* sb.append(typeparm.toString());
*/
first = false;
}
sb.append("> ");
}
Type genRetType = resolver.resolveType(getGenericReturnType());
sb.append(TypeNameUtils.getTypeName(genRetType, fullClassName) + " ");
if (fullClassName)
sb.append(TypeNameUtils.getTypeName(getDeclaringClass(), fullClassName) + ".");
sb.append(getName() + "(");
Type[] params = resolver.resolveTypes(getGenericParameterTypes());
for (int j = 0; j < parameterNames.length; j++) {
sb.append(TypeNameUtils.getTypeName(params[j], fullClassName) + " ");
sb.append(parameterNames[j]);
if (j < (parameterNames.length - 1))
sb.append(",");
}
sb.append(")");
Type[] exceptions = getGenericExceptionTypes();
if (exceptions.length > 0) {
sb.append(" throws ");
for (int k = 0; k < exceptions.length; k++) {
sb.append(TypeNameUtils.getTypeName(exceptions[k], fullClassName));
if (k < (exceptions.length - 1))
sb.append(",");
}
}
return sb.toString();
} catch (Exception e) {
return "<" + e + ">";
}
}
/**
* 输出类名简写的(泛型)方法描述字符串
*
* @param fullClassName
* 是否显示类的全名
* @see java.lang.reflect.Method#toGenericString()
*/
public String toGenericString(boolean fullClassName) {
return toGenericString(new EnhancedTypeResolver(), fullClassName);
}
/**
* 输出类名简写的方法描述字符串
*
* @see #toString(boolean)
* @see java.lang.reflect.Method#toString()
*/
@Override
public String toString() {
return toString(false);
}
/**
* 是否显示类的全名
*
* @param fullClassName
* @see java.lang.reflect.Method#toString()
*/
public String toString(boolean fullClassName) {
try {
StringBuffer sb = new StringBuffer();
int mod = getModifiers() & LANGUAGE_MODIFIERS;
if (mod != 0) {
sb.append(Modifier.toString(mod) + " ");
}
sb.append(TypeNameUtils.getTypeName(getReturnType(), fullClassName) + " ");
if (fullClassName)
sb.append(TypeNameUtils.getTypeName(getDeclaringClass(), fullClassName) + ".");
sb.append(getName() + "(");
Class>[] params = getParameterTypes(); // avoid clone
for (int j = 0; j < params.length; j++) {
sb.append(TypeNameUtils.getTypeName(params[j], fullClassName) + " ");
sb.append(parameterNames[j]);
if (j < (parameterNames.length - 1))
sb.append(",");
}
sb.append(")");
Class>[] exceptions = (Class[]) getGenericExceptionTypes(); // avoid clone
if (exceptions.length > 0) {
sb.append(" throws ");
for (int k = 0; k < exceptions.length; k++) {
sb.append(exceptions[k].getName());
if (k < (exceptions.length - 1))
sb.append(",");
}
}
return sb.toString();
} catch (Exception e) {
return "<" + e + ">";
}
}
/**
* @return parameters
*/
public Parameter[] getParameters() {
return parameters;
}
public final String getDocSignature(boolean fn) {
return getDocSignature(method, fn);
}
public static final String getDocSignature(java.lang.reflect.Method method, boolean fn) {
return getDocSignature(method, TypeNameUtils.toFullName(fn));
}
public String getDocSignature(Map> importedList) {
return getDocSignature(method,importedList,"");
}
public String getDocSignature(Map> importedList,String pkg) {
return getDocSignature(method, importedList,pkg);
}
public final static String getDocSignature(java.lang.reflect.Method method, final Map> importedList,String pkg) {
TypeNameUtils.FullName fn;
if (null != importedList) {
fn = new FullNameByImporList(importedList,pkg);
} else
fn = TypeNameUtils.FULLNAME_INSTANCE_TRUE;
return getDocSignature(method, fn);
}
private static String getDocSignature(java.lang.reflect.Method method, TypeNameUtils.FullName fn) {
StringBuilder builder = new StringBuilder()
.append(TypeNameUtils.getTypeName(method.getDeclaringClass(), fn.isFullName(method.getDeclaringClass()))).append("#")
.append(method.getName()).append("(");
int c = 0;
for (Class> type : method.getParameterTypes()) {
if (c++ > 0)
builder.append(",");
builder.append(TypeNameUtils.getTypeName(type, fn.isFullName(type)));
}
builder.append(")");
return builder.toString();
}
public Set getGenericExceptionTypeSet() {
return new HashSet(Arrays.asList(getGenericExceptionTypes()));
}
/**
* @return docSignature
*/
public final String getDocSignature() {
return docSignature;
}
/**
* @return docSignature
*/
public final String getSignature() {
return getSignature(method);
}
/**
* 根据方法是否定义{@link Deprecated} 注解判断方法是否为废弃的
* @since 2.1.18
*/
public final boolean isDeprecated() {
return null != method.getAnnotation(Deprecated.class);
}
public static final String getSignature(java.lang.reflect.Method method) {
return getDocSignature(method, true).replaceFirst("\\S*#", "");
}
public java.lang.reflect.Method delegate() {
return method;
}
/**
* 判断当前方法是否匹配指定的分类标签
* @param required 指定的分类标签,为{@code null}或空时返回true
*/
public boolean tagsMatched(Set required) {
if(required == null || required.isEmpty()){
return true;
}
return !Sets.intersection(catalogs, required).isEmpty();
}
public static final Function TO_REFLECT_METHOD = new Function() {
@Override
public java.lang.reflect.Method apply(Method input) {
return input == null ? null : input.delegate();
}
};
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy