1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
|
/*
* Created on 25 janv. 07
*/
import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;
/**
* @author CyberChouan
* @version 2007.01.25
*/
public class MethodUtils {
/**
* Lors de l'invocation d'une {@link Method} via la methode 'invoke',
* si le parametre attendu est une primitive, l'invocation avec en
* parametre l'objet associe fonctionne
* @param expected
* @param given
* @return
*/
public static boolean isInvocableFrom(Class expected, Class given) {
if(expected.isAssignableFrom(given)) {
return true;
} else if (hasWrapper(expected)) {
return given.equals(getWrapper(expected));
} else {
return false;
}
}
public static boolean hasPrimitive(Class javaClass) {
if(javaClass.equals(Integer.class)) { return true; }
if(javaClass.equals(Long.class)) { return true; }
if(javaClass.equals(Float.class)) { return true; }
if(javaClass.equals(Double.class)) { return true; }
if(javaClass.equals(Short.class)) { return true; }
if(javaClass.equals(Void.class)) { return true; }
if(javaClass.equals(Character.class)) { return true; }
if(javaClass.equals(Byte.class)) { return true; }
if(javaClass.equals(Boolean.class)) { return true; }
return false;
}
public static Class getPrimitive(Class javaClass) {
if(javaClass.equals(Integer.class)) { return Integer.TYPE; }
if(javaClass.equals(Long.class)) { return Long.TYPE; }
if(javaClass.equals(Float.class)) { return Float.TYPE; }
if(javaClass.equals(Double.class)) { return Double.TYPE; }
if(javaClass.equals(Short.class)) { return Short.TYPE; }
if(javaClass.equals(Void.class)) { return Void.TYPE; }
if(javaClass.equals(Character.class)) { return Character.TYPE; }
if(javaClass.equals(Byte.class)) { return Byte.TYPE; }
if(javaClass.equals(Boolean.class)) { return Boolean.TYPE; }
return null;
}
public static boolean hasWrapper(Class javaClass) {
if(javaClass.equals(Integer.TYPE)) { return true; }
if(javaClass.equals(Long.TYPE)) { return true; }
if(javaClass.equals(Float.TYPE)) { return true; }
if(javaClass.equals(Double.TYPE)) { return true; }
if(javaClass.equals(Short.TYPE)) { return true; }
if(javaClass.equals(Void.TYPE)) { return true; }
if(javaClass.equals(Character.TYPE)) { return true; }
if(javaClass.equals(Byte.TYPE)) { return true; }
if(javaClass.equals(Boolean.TYPE)) { return true; }
return false;
}
public static Class getWrapper(Class javaClass) {
if(javaClass.equals(Integer.TYPE)) { return Integer.class; }
if(javaClass.equals(Long.TYPE)) { return Long.class; }
if(javaClass.equals(Float.TYPE)) { return Float.class; }
if(javaClass.equals(Double.TYPE)) { return Double.class; }
if(javaClass.equals(Short.TYPE)) { return Short.class; }
if(javaClass.equals(Void.TYPE)) { return Void.class; }
if(javaClass.equals(Character.TYPE)) { return Character.class; }
if(javaClass.equals(Byte.TYPE)) { return Byte.class; }
if(javaClass.equals(Boolean.TYPE)) { return Boolean.class; }
return null;
}
/**
* Recherche une methode nommee 'methodName', invocable a partir d'arguments
* de types parameterTypes. Si plusieurs methodes correcpondantes sont trouvees,
* on en renvoie une au hasard (la premiere de la liste)
* @param methodClass
* @param methodName
* @param parameterTypes
* @return
*/
public static Method findMethod(Class methodClass, String methodName, Class[] parameterTypes) {
try { return findExactMethod(methodClass, methodName, parameterTypes);}
catch (Exception e) {
List methods = getMethods(methodClass, methodName, parameterTypes.length);
List invocableMethods = findInvocableMethods(methods, parameterTypes);
if(invocableMethods.size() > 0) {
return (Method) invocableMethods.get(0);
} else {
return null;
}
}
}
public static List findInvocableMethods(List methods, Class[] parameterTypes) {
Method method;
List invocableMethods = new LinkedList();
for(int i=0; i<methods.size(); i++) {
method = (Method) methods.get(i);
if(isInvocableFrom(method, parameterTypes)) {
invocableMethods.add(method);
}
}
return invocableMethods;
}
/**
* Utilisation directe de la methode 'getMethod' de {@link Class}
* @param methodClass
* @param methodName
* @param parameterTypes
* @return
* @throws SecurityException
* @throws NoSuchMethodException
*/
public static Method findExactMethod(Class methodClass, String methodName, Class[] parameterTypes)
throws SecurityException, NoSuchMethodException {
return methodClass.getMethod(methodName, parameterTypes);
}
public static boolean isInvocableFrom(Method method, Class[] argsTypes) {
Class[] expectedArgsTypes = method.getParameterTypes();
// Si le nombre d'arguments n'est pas le meme, la methode n'est pas
// 'invocable' a partir des arguments proposes
if (argsTypes.length != expectedArgsTypes.length) {
return false;
}
// Si un des types est incompatible, la methode n'est pas
// 'invocable' a partir des arguments propos
for(int i=0; i<argsTypes.length; i++) {
if(!isInvocableFrom(expectedArgsTypes[i], argsTypes[i])) {
return false;
}
}
return true;
}
/**
* Renvoie la liste des methodes de la classe 'methodClass' qui portent le nom
* 'name', et qui prennent 'nbArgs' arguments
* @param methodsClass
* @param name
* @param nbArgs
* @return
*/
public static List getMethods(Class methodsClass, String name, int nbArgs) {
Method[] classMethods = methodsClass.getMethods();
Method temp;
List result = new LinkedList();
for(int i=0; i<classMethods.length; i++) {
temp = classMethods[i];
if(temp.getName().equals(name) && temp.getParameterTypes().length == nbArgs) {
result.add(temp);
}
}
return result;
}
/**
* Renvoie la liste des 'getters' d'une classe, c'est a dire les methodes
* dont le nom commence par 'get' (ou 'is' si l'attribut de la classe est
* booleen) et qui n'ont pas de parametres
* @param javaClass
* @return
*/
public static List getGetters(Class javaClass) {
Method[] classMethods = javaClass.getMethods();
Method temp;
List result = new LinkedList();
for(int i=0; i<classMethods.length; i++) {
temp = classMethods[i];
if((temp.getName().startsWith("get") || temp.getName().startsWith("is"))
&& temp.getParameterTypes().length == 0) {
result.add(temp);
}
}
return result;
}
public static void main(String[] args) {
System.out.println(isInvocableFrom(Integer.TYPE, Integer.class));
}
} |