All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.gdface.codegen.Method Maven / Gradle / Ivy

There is a newer version: 3.5.0
Show newest version
/**   
 * @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 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