/* * Copyright 2014 mango.jfaster.org * * The Mango Project licenses this file to you 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.jfaster.mango.descriptor; import org.jfaster.mango.util.reflect.Reflection; import org.jfaster.mango.util.reflect.TypeToken; import java.lang.annotation.Annotation; import java.lang.reflect.Array; import java.lang.reflect.GenericArrayType; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Arrays; import java.util.LinkedList; import java.util.List; /** * @author ash */ public class Methods { private static final TypeToken<?> genericTypeToken = TypeToken.of(Generic.class); public static MethodDescriptor getMethodDescriptor(Class<?> daoClass, Method method, boolean isUseActualParamName) { List<Annotation> mas = new LinkedList<Annotation>(); for (Annotation a : method.getAnnotations()) { mas.add(a); } for (Annotation a : Reflection.getAnnotations(daoClass)) { mas.add(a); } TypeToken<?> daoTypeToken = TypeToken.of(daoClass); Type returnType = fixAndResolveType(method.getGenericReturnType(), daoTypeToken); ReturnDescriptor rd = ReturnDescriptor.create(returnType, mas); List<ParameterDescriptor> pds = new LinkedList<ParameterDescriptor>(); Type[] genericParameterTypes = method.getGenericParameterTypes(); Annotation[][] parameterAnnotations = method.getParameterAnnotations(); String[] names = getParameterNames(method, isUseActualParamName); for (int i = 0; i < genericParameterTypes.length; i++) { Type type = fixAndResolveType(genericParameterTypes[i], daoTypeToken); Annotation[] pas = parameterAnnotations[i]; String name = names[i]; pds.add(ParameterDescriptor.create(i, type, Arrays.asList(pas), name)); } return MethodDescriptor.create(method.getName(), daoClass, rd, pds); } static Type fixAndResolveType(Type type, TypeToken<?> daoTypeToken) { type = fixTypeInJava6(type); return resolveType(type, daoTypeToken); } /** * java6中,利用反射获得int[],Integer[]等类型的genericType时,可能会得到泛型数组, * 下面的方法会将泛型数组转为class */ static Type fixTypeInJava6(Type type) { if (type instanceof GenericArrayType) { GenericArrayType gat = (GenericArrayType) type; Type componentType = gat.getGenericComponentType(); if (componentType instanceof Class) { return Array.newInstance((Class) componentType, 0).getClass(); } } return type; } static Type resolveType(Type type, TypeToken<?> daoTypeToken) { return genericTypeToken.isAssignableFrom(daoTypeToken) ? daoTypeToken.resolveType(type).getType() : type; } private static String[] getParameterNames(Method method, boolean isUseActualParamName) { String[] names = new String[method.getGenericParameterTypes().length]; for (int i = 0; i < names.length; i++) { String name = null; if (isUseActualParamName) { name = ParamNameResolver.getActualParamName(method, i); } if (name == null) { name = String.valueOf(i + 1); } names[i] = name; } return names; } }