package toolspack;
import java.lang.reflect.*;
/**
* NB: L'uso della reflection non consente di invocare un metodo, di cui si conosce solo il
* nome, con i parametri corretti, come si fa normalmente quando si scrive del codice e
* si invoca il metodo di un oggetto. Con la reflection è invece necessario prima reperire il
* metodo, e solo successivamente invocarlo su determinati parametri. Questo ha notevoli
* implicazioni perché non sempre si conosce la signature del metodo da invocare ed essa,
* inoltre, non è sempre determinabile a partire dalle classi degli oggetti da passare come
* parametri al metodo!! Infatti la signature potrebbe afferire ad una superclasse o
* superinterfaccia degli oggetti da passare come paramtri!
* Questa classe fornisce il metodo getMethodRecursive per risolvere il problema, ma SOLO per
* metodi con un unico parametro!!!
* @author Stefano Ricciarelli
* @version 1.2 - Date: 28-06-2002
*/
public class Reflect {
public Reflect() {
}
/**
* Restituisce, facendo uso della reflection, il metodo di nome methodName,
* della classe className, avente un unico argomento di classe "compatibile" con
* la classe onlyOneMetohdParamClass. Più precisamente ricerca inizialmente
* un metodo con argomento di classe onlyOneMetohdParamClass, se non lo trova continua
* ricercando un metodo avente per argomento un'interfaccia implementata dalla classe
* onlyOneMetohdParamClass; infine ricerca un metodo avente per argomento una superclasse
* della classe onlyOneMetohdParamClass. Il procedimento è ricorsivo salendo lungo la
* gerarchia delle superclassi della classe onlyOneMetohdParamClass.
* @param className la classe nella quale si cerca il metodo
* @param methodName il nome del metodo da cercare
* @param onlyOneMetohdParamClass la classe che deve essere accettata come argomento
* dal metodo ricercato
* @return un metodo in grado di accettare un parametro di classe onlyOneMetohdParamClass
*/
public static Method getMethodRecursive(
Class className, String methodName, Class onlyOneMetohdParamClass) {
Method method = null;
try {
method = className.getMethod(methodName, new Class[]{onlyOneMetohdParamClass});
}
catch (Exception ex) {
Class[] interfaces = onlyOneMetohdParamClass.getInterfaces();
int i = 0;
while (i
* NB: le classi degli oggetti params devono essere necessariamente le stesse
* (quindi non delle sottoclassi o delle implementazioni di interfacce) della
* signature del metodo methodName!
* @param o l'oggetto su cui invocare il metodo
* @param methodName il metodo da invocare
* @param params array degli oggetti argomenti del metodo.
* @return il valore di ritorno del metodo invocato
* @throws Exception propaga le eventuali eccezioni generatesi con la reflection
*/
public static synchronized Object invoke(Object o, String methodName
, Object[] params) throws Exception {
return invoke2(o, methodName, getClasses(params), params);
}
/**
* Invoca attraverso la reflection il metodo methodName, con l'unico
* parametro param, sull'oggetto o.
* NB: le classi degli oggetti params devono essere necessariamente le stesse
* (quindi non delle sottoclassi o delle implementazioni di interfacce) della
* signature del metodo methodName!
* @param o l'oggetto su cui invocare il metodo
* @param methodName il metodo da invocare
* @param param l'oggetto argomento del metodo.
* @return il valore di ritorno del metodo invocato
* @throws Exception propaga le eventuali eccezioni generatesi con la reflection
*/
public static synchronized Object invoke(Object o, String methodName
, Object param) throws Exception {
Logger.print("Invoco il metodo "+methodName+" sull'oggetto "+o+" con parametro "+param
+ " di classe "+ param.getClass() );
return invoke2(o, methodName, new Class[]{param.getClass()}, new Object[]{param});
}
/**
* Invoca attraverso la reflection il metodo methodName avente signature paramClass,
* con l'unico parametro param, sull'oggetto o.
* NB: le classi degli oggetti params devono essere necessariamente le stesse
* (quindi non delle sottoclassi o delle implementazioni di interfacce) della
* signature del metodo methodName!
* @param o l'oggetto su cui invocare il metodo
* @param methodName il metodo da invocare
* @param param l'oggetto argomento del metodo.
* @param paramClass la classe dell'oggetto argomento del metodo.
* @return il valore di ritorno del metodo invocato
* @throws Exception propaga le eventuali eccezioni generatesi con la reflection
*/
public static synchronized Object invoke(Object o, String methodName
, Object param, Class paramClass) throws Exception {
return invoke2(o, methodName, new Class[]{paramClass}, new Object[]{param});
}
/**
* Invoca attraverso la reflection il metodo methodName, con l'unico
* parametro param, sull'oggetto o ricercando un metodo con signature compatibile
* con la classe del parametro param.
* @param o l'oggetto su cui invocare il metodo
* @param methodName il metodo da invocare
* @param param l'oggetto argomento del metodo.
* @return il valore di ritorno del metodo invocato
* @throws Exception propaga le eventuali eccezioni generatesi con la reflection
*/
public static synchronized Object invokeSearching(Object o, String methodName
, Object param) throws Exception {
return getMethodRecursive(o.getClass(), methodName, param.getClass())
.invoke(new Object[]{o}, new Object[]{param});
}
/**
* Invoca attraverso la reflection il metodo methodName, senza parametri, sull'oggetto o.
* NB: le classi degli oggetti params devono essere necessariamente le stesse
* (quindi non delle sottoclassi o delle implementazioni di interfacce) della
* signature del metodo methodName!
* @param o l'oggetto su cui invocare il metodo
* @param methodName il metodo da invocare
* @return il valore di ritorno del metodo invocato
* @throws Exception propaga le eventuali eccezioni generatesi con la reflection
*/
public static synchronized Object invoke(Object o, String methodName) throws Exception {
Logger.print("Invoco il metodo "+methodName+" sull'oggetto "+o+" senza parametri ");
return invoke2(o, methodName, new Class[]{}, new Object[]{});
}
/**
* Provvede ad invocare il metodo di nome methodName con signature definata dall'
* array classes, sull'oggetto o con parametri l'array di oggetto params
* @param o l'oggetto su cui invocare il metodo
* @param methodName il nome del metodo da invocare
* @param classes la signature del metodo
* @param params i parametri del metodo
* @return l'oggetto restituito dal metodo invocato
* @throws Exception eventuali eccezioni generate dalla reflection
*/
private static Object invoke2(Object o, String methodName
, Class[] classes, Object[] params) throws Exception {
return o.getClass().getMethod(methodName, classes).invoke(o, params);
}
/**
* Dato un array di oggetti o restituisce un array contente le rispettive classi
* @param o l'array degli oggetti
* @return l'array delle classi
*/
private static Class[] getClasses(Object[] o) {
Class[] c = new Class[o.length];
for (int i=0; i