fnBrito.com
ClinicalDataBase
ClinicalDataBank
WebLog

« January 2005 »
SunMonTueWedThuFriSat
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
19
21
22
23
24
25
26
27
28
29
30
31
     
Hoy

XML


20050120 Thursday January 20, 2005

¿Quién me llama?:: Una píldora de esas que surgen por casualidad en el curro diario...

En ocasiones necesitamos que un método sepa la identidad del que le llamó, para actuar en consecuencia. Supongamos por ejemplo que tenemos un DataSource al que acceden distintos componentes de nuestra aplicación. Y supongamos que hay componentes pensados exclusivamente para acceder en modo lectura, así que decidimos que en ese caso les devolvemos un wraper sobre la conexión real que impida lanzar consultas SQL que no empiecen por "SELECT". No parece demasiado complicado, salvo por el hecho de que en la interfaz DataSource sólo tenemos un método getConnection() (y otro getConnection(String usr, String pwd), pero que no es la solución), así que ni podemos utilizar un parámetro (algo del tipo getConnection(Object caller)), ni tampoco usar métodos distintos en cada caso.

En este punto necesitamos que getConnection sea capaz de averiguar quién le llamó, para actuar en consecuencia. Así es como lo estamos solucionando nosotros: el siguiente método nos permite hacerlo de una forma muy sencilla:

    /**
     * Devuelve la traza de clases en la llamada al método, con
     * una profundidad máxima de [depth] elementos.
     * @param deph
     * @return
     */
    public static Class[] whoCalledMe(int depth){ 
       StackTraceElement[] elements = new Throwable().getStackTrace();
       Class[] trace = new Class[Math.min(depth,elements.length)];
       for(int i = 0; i<trace.length;i++){
           try {
            trace[i] = Class.forName(elements[i].getClassName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
       }       
       return trace;
    }

Veis que el procedimiento es bastantes sencillo: crear un Throwable y pedir el StackTrace. De esta manera tenemos los nombres de las clases involucradas en la llamada, siendo la primera obviamente la que llamó al propio whoCalledMe, y la segunda la que llamó al método que llamó a whoCalledMe, y así sucesivamente.
(2005-01-20 10:59:25.0) Permalink Comentarios [4]