Bueno, pues vamos a avanzar un poco más en nuestras clases de utilidad y hoy vamos a poner unos cuantos métodos con los que poder usar el API reflection.
Éste API es muy usado dentro de la comunidad y es una herramienta muy potente a la hora de invocar métodos o clases por ejemplo definidos en base de datos.
Obtener una clase a partir de un nombre:
/**
* Obtiene una clase a partir del nombre de la misma.
*
* @param clazz La cadena que identifica la clase que se quiere obtener.
*
* @return La clase correspondiente si se ha encontrado, y sino una excepción PLNException.
* @throws La excepción Exception.
*/
@SuppressWarnings("unchecked")
public static Class getClass (String clazz) throws Exception {
Class result = null;
try {
result = Class.forName(clazz);
} catch (ClassNotFoundException e) {
log.error("No se encuentra la clase " + clazz, e);
throw new Exception("No se encuentra la clase " + clazz,e);
} catch (NullPointerException e) {
log.error("Se ha pasado un nombre de clase null ", e);
throw new Exception("Se ha pasado un nombre de clase null ",e);
}
return result;
}
Obtener el método de una clase (solo los visibles):
/**
* Dada una clase, una cadena que identificará al método y la lista de parámetros, devuelve el
* método público correspondiente de la clase, y si éste no existiera o si se encontrara algún
* problema, se lanzará la excepción Exception.
*
* @param clazz
* La clase donde se pretende encontrar el método.
* @param method
* La cadena que representa el método a buscar en la clase.
* @param params
* La lista de parámetros que necesita el método.
*
* @return El método en cuestión o una excepción Exception.
* @throws La excepción Exception.
*/
@SuppressWarnings("unchecked")
public static Method getMethod (Class clazz, String method, List<String> params) throws Exception {
Method result = null;
if (params == null){
log.error("Parámetros nulos ");
throw new Exception("Parámetros nulos ");
}
Class [] parametros = new Class[params.size()];
int i = 0;
for (String className : params) {
parametros [i++] = getClass(className);
}
try {
result = clazz.getMethod(method, parametros);
} catch (SecurityException e) {
log.error("Error en la seguridad " + method, e);
throw new Exception("Error en la seguridad " + method, e);
} catch (NoSuchMethodException e) {
log.error("No se encuentra el método " + method, e);
throw new Exception("No se encuentra el método " + method, e);
} catch (NullPointerException e) {
log.error("Se han pasado parámetros null ", e);
throw new Exception("Se han pasado parámetros null ",e);
}
return result;
}
Obtener el método de una clase (todos y cada uno sean visibles o no):
/**
* Dada una clase, una cadena que identificará al método y la lista de parámetros, devuelve el
* método correspondiente de la clase, sea o no público, y si éste no existiera o si se
* encontrara algún problema, se lanzará la excepción Exception.
*
* @param clazz
* La clase donde se pretende encontrar el método.
* @param method
* La cadena que representa el método a buscar en la clase.
* @param params
* La lista de parámetros que necesita el método. Un ejemplo sería "java.util.List".
*
* @return El método en cuestión o una excepción Exception.
* @throws La excepción Exception.
*/
@SuppressWarnings("unchecked")
public static Method getDeclaredMethod (Class clazz, String method, List<String> params) throws Exception {
Method result = null;
if (params == null){
log.error("Parámetros nulos ");
throw new Exception("Parámetros nulos ");
}
Class [] parametros = new Class[params.size()];
int i = 0;
for (String className : params) {
parametros [i++] = getClass(className);
}
try {
result = clazz.getDeclaredMethod(method, parametros);
} catch (SecurityException e) {
log.error("Error en la seguridad " + method, e);
throw new Exception("Error en la seguridad " + method, e);
} catch (NoSuchMethodException e) {
log.error("No se encuentra el método " + method, e);
throw new Exception("No se encuentra el método " + method, e);
} catch (NullPointerException e) {
log.error("Se han pasado parámetros null ", e);
throw new Exception("Se han pasado parámetros null ",e);
}
return result;
}
Invocar un método de una clase:
/**
* Método encargado de, dada una clase y un método de la misma, con sus correspondientes
* parámetros, invocar el mismo, obteniendo como resultado en la clase Object, el resultado
* de su ejecución.
*
* @param className
* La cadena que representa la clase que se quiere manejar.
* @param methodName
* La cadena que representa el método que se quiere invocar.
* @param params
* La lista de parámetros que se tienen que pasar al método para realizar su ejecución.
*
* @return El objeto que retorna la ejecución del método.
* @throws Exception
*/
public static Object invoke (String className, String methodName, List<Object> params) throws Exception {
Object result = null;
Object instance = null;
Method metodo = null;
List<String> lParametros = new ArrayList<String> ();
for (Object object : params) {
lParametros.add(object.getClass().getName());
}
try {
instance = getClass(className).newInstance();
metodo = getDeclaredMethod(getClass(className), methodName, lParametros);
metodo.setAccessible(true);
result = metodo.invoke(instance, params.toArray(new Object[params.size()]));
} catch (SecurityException e) {
log.error("Error en la seguridad " + instance, e);
throw new Exception("Error en la seguridad " + instance, e);
} catch (IllegalArgumentException e) {
log.error("IllegalArgumentException invoke ", e);
throw new Exception("IllegalArgumentException invoke ", e);
} catch (IllegalAccessException e) {
log.error("IllegalAccessException invoke ", e);
throw new Exception("IllegalAccessException invoke ", e);
} catch (InvocationTargetException e) {
log.error("InvocationTargetException invoke ", e);
throw new Exception("InvocationTargetException invoke ", e);
} catch (InstantiationException e) {
log.error("InstantiationException a la hora de instanciar la clase ", e);
throw new Exception("InstantiationException a la hora de instanciar la clase ", e);
}
return result;
}
Esto se puede mejorar mucho con el uso de anotaciones, así es que cualquier propuesta siempre es bien recibida!

Deja un comentario