package common;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Executes a method in an object dinamically. It's a wrapper to the java
* reflection way of execute methods dinamically.
*/
public class DuckType {
public static T execute(Object object, String methodName, Object ... parameters) {
if (object == null) return null;
if (methodName == null || methodName.equals("")) return null;
Class[] classes = extractClassesFromParameters(parameters);
try {
return (T) executeEasyWay(object, methodName, classes, parameters);
} catch (NoSuchMethodException e) {
return (T) executeHardWay(object, methodName, classes, parameters);
} catch (SecurityException e) {
return null;
} catch (IllegalArgumentException e) {
return null;
} catch (IllegalAccessException e) {
return null;
} catch (InvocationTargetException e) {
return null;
}
}
private static Object executeEasyWay(Object object, String methodName, Class[] classes, Object... parameters) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
Method method = object.getClass().getMethod(methodName, classes);
return method.invoke(object, parameters);
}
private static Object executeHardWay(Object object, String methodName, Class[] classes, Object... parameters) {
// it didn't find the method in the easy way, trying the hard way
Method[] methods = object.getClass().getMethods();
for (Method method : methods) {
Class[] methodTypes = method.getParameterTypes();
// Ignore methods with different names
if (!methodName.equals(method.getName())) continue;
// Ignore methods with different number of parameters
if (methodTypes.length != classes.length) continue;
boolean isMethodExecutable = true;
for (int i = 0; i < methodTypes.length; i++) {
Class methodType = (Class) methodTypes[i];
Class parameterType = classes[i];
if (!methodType.isAssignableFrom(parameterType)) {
isMethodExecutable = false;
break;
}
}
try {
if (isMethodExecutable) return method.invoke(object, parameters);
} catch (IllegalArgumentException e1) {
return null;
} catch (IllegalAccessException e1) {
return null;
} catch (InvocationTargetException e1) {
return null;
}
}
return null;
}
private static Class[] extractClassesFromParameters(Object[] parameters) {
Class[] classes = new Class[parameters.length];
for (int i = 0; i < parameters.length; i++) {
Object parameter = parameters[i];
classes[i] = parameter.getClass();
}
return classes;
}
}
quinta-feira, janeiro 12, 2006
Duck Type em Java
Como o Java é uma linguagem boa e com excelentes APIs, mas muito tosca em algumas coisas básicas (como manipulação de Strings e Coleções), volta e meio fazemos alguns utilitários estúpidos pra facilitar a vida.
Aqui vai um dos meus, um simples wrapper para facilitar a chamada de métodos dinâmicos.
Assinar:
Postar comentários (Atom)
Nenhum comentário:
Postar um comentário