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