/** * Copyright (C) 2008-2010, Squale Project - http://www.squale.org * * This file is part of Squale. * * Squale is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or any later version. * * Squale is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Squale. If not, see <http://www.gnu.org/licenses/>. */ /* * Created on Mar 30, 2004 */ package org.squale.jraf.provider.accessdelegate; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.squale.jraf.commons.exception.JrafEnterpriseException; import org.squale.jraf.spi.accessdelegate.IAccessDelegateProvider; import org.squale.jraf.spi.accessdelegate.IApplicationComponent; /** * <p>Title : ExecuteHelper.java</p> * <p>Description : Helper pour aider la delegation des appels de methodes * dans les application component</p> * <p>Copyright : Copyright (c) 2004</p> * */ public class ExecuteHelper { private final static int DEPTH = 3; /** logger */ private static final Log log = LogFactory.getLog(ExecuteHelper.class); /** * Methode execute pour les application component * @param in_applicationComponent application component * @param in_method methode a invoquer * @param in_parameters parametres de la methode * @return retour de la methode * @throws JrafEnterpriseException */ public final static Object execute( IApplicationComponent in_applicationComponent, String in_method, Object[] in_parameters) throws JrafEnterpriseException { Object lc_returnedObject = null; Method lc_method = null; // recuperation de l'access delegate provider IAccessDelegateProvider lc_adp = null; lc_adp = in_applicationComponent.getAccessDelegateProvider(); // validation de l'existance du service if (log.isDebugEnabled()) { log.debug( "Validation du composant " + in_applicationComponent.getApplicationComponent() + "." + in_method); } // valide l'existance du service if (!lc_adp .validateService( in_applicationComponent.getApplicationComponent(), in_method)) { // le service n'existe pas log.error( "Le composant " + in_applicationComponent.getApplicationComponent() + "." + in_method + " n'est pas defini dans le contrat de l'application component"); throw new JrafEnterpriseException( "Le composant " + in_applicationComponent.getApplicationComponent() + "." + in_method + " n'est pas defini dans le contrat de l'application component"); } // le service existe if (log.isDebugEnabled()) { log.debug( "Le composant " + in_applicationComponent.getApplicationComponent() + "." + in_method + " existe"); } // delegue l'appel de methode sur l'ejb local try { lc_method = internalFindMethod( in_applicationComponent.getClass(), in_method, in_parameters); if (lc_method == null) { log.error( "Le composant " + in_applicationComponent.getApplicationComponent() + "." + in_method + " n'est pas defini (introuvable dans la classe Java)."); throw new JrafEnterpriseException( "Le composant " + in_applicationComponent.getApplicationComponent() + "." + in_method + " n'est pas defini (introuvable dans la classe Java)."); } lc_returnedObject = lc_method.invoke(in_applicationComponent, in_parameters); } catch (IllegalAccessException e) { log.error( "Le composant " + in_applicationComponent.getApplicationComponent() + "." + in_method + " n'est pas accessible", e); throw new JrafEnterpriseException( "Le composant " + in_applicationComponent.getApplicationComponent() + "." + in_method + " n'est pas accessible"); } catch (InvocationTargetException e) { // convertie l'exception convertInvocationTargetException( in_applicationComponent, in_method, e); } // le service existe if (log.isDebugEnabled()) { log.debug( "La delegation de l'appel " + in_applicationComponent.getApplicationComponent() + "." + in_method + " s'est deroule avec succes"); } // retourne l'objet retourne par l'appel de methode return lc_returnedObject; } /** * Valide la concordance entre les parametres d'entree * et les parametres de la methode candidate. * Recherche la validite de l'heritage jusqu'au niveau DEPTH * @param in_argCount nombre d'arguments * @param in_parameters parametres d'entree * @param in_parameterTypes parametres de la methode trouvee * @return true si les parametres sont en concordance, false sinon. */ protected final static boolean checkParametersMatch( int in_argCount, Object[] in_parameters, Class[] in_parameterTypes) { Class cla = null; Class[] ifcs = null; // on parcours les parametres for (int j = 0; j < in_argCount; j++) { // si le parametre est null on le passe if (in_parameters[j] == null) { continue; } // si les parametres sont diff�rents if (!in_parameterTypes[j] .getName() .equals(in_parameters[j].getClass().getName())) { // Type de l'arborescence � �tudier. // if (in_parameterTypes[j].isInterface()) // ifcs = in_parameters[j].getClass().getInterfaces(); // else // ifcs = in_parameters[j].getClass().getClasses(); // Param�tre candidat // if ((ifcs.length != 0) // && ifcs[0].isAssignableFrom(in_parameterTypes[j])) // Le parametre de la methode utilisateur est-il assignable a la methode candidate if (in_parameterTypes[j] .isAssignableFrom(in_parameters[j].getClass())) continue; else { return false; } } else continue; } return true; } /** * Recherche une methode a partir de ce nom et de ces parametres. * La methode est recherchee dans toute la hierarchie du type et de ces parametres. * @param in_class classe * @param in_methodName nom de la methode * @param in_parameters parametres * @return methode trouvee */ public final static Method internalFindMethod( Class in_class, String in_methodName, Object[] in_parameters) { Method[] lc_methods = null; Method lc_method = null; Class[] lc_param = null; boolean paramHok = false; int lc_argCount = 0; if (in_parameters != null) lc_argCount = in_parameters.length; for (Class cl = in_class; cl != null; cl = cl.getSuperclass()) { lc_methods = cl.getMethods(); lc_method = null; for (int i = 0; i < lc_methods.length; i++) { lc_method = lc_methods[i]; if (lc_method == null) continue; int mods = lc_method.getModifiers(); if (Modifier.isStatic(mods)) continue; if (lc_method.getName().equals(in_methodName) && lc_method.getParameterTypes().length == lc_argCount) { // System.out.println("Methode candidate: " + method.getName() + " param length: " + method.getParameterTypes().length); // System.out.println("Methode recherchee: " + methodName + " parameter length: " + argCount); lc_param = lc_method.getParameterTypes(); // for (int j = 0; j < argCount; j++) // System.out.println("pfind = " + param[j].getName()); // for (int j = 0; j < argCount; j++) // System.out.println("psearch = " + parameter[j] ); // parameter[j].getClass().getName()); paramHok = checkParametersMatch( lc_argCount, in_parameters, lc_param); if (paramHok) { return lc_method; } } } } // cas pour la recherche dans des interfaces parentes Class[] ifcs = in_class.getInterfaces(); for (int i = 0; i < ifcs.length; i++) { lc_method = internalFindMethod(ifcs[i], in_methodName, in_parameters); if (lc_method != null) { return lc_method; } } return null; } /** * Convertie une InvocationTargetException en JrafEnterpriseException * @param in_ac application component * @param in_method method * @param in_ite exception * @throws JrafEnterpriseException */ public final static void convertInvocationTargetException( IApplicationComponent in_ac, String in_method, InvocationTargetException in_ite) throws JrafEnterpriseException { Throwable t = in_ite.getTargetException(); if (t != null) { if (log.isDebugEnabled()) { log.debug( "Probleme lors de l'invocation du composant " + in_ac.getApplicationComponent() + "." + in_method, t); } if (t instanceof JrafEnterpriseException) { // deja une JRAFEnterpriseException throw (JrafEnterpriseException) t; } else { // on transforme l'exception contenu en JRAFEnterpriseException throw new JrafEnterpriseException( "Probleme lors de l'invocation du composant " + in_ac.getApplicationComponent() + "." + in_method, t); } } else { // cas anormal: L' InvocationTargetException ne contient pas // d'exception. // ne doit pas se produire if (log.isDebugEnabled()) { log.debug( "Probleme lors de l'invocation du composant : l'exception recuperee n'est pas conforme. " + in_ac.getApplicationComponent() + "." + in_method, in_ite); } throw new JrafEnterpriseException( "Probleme lors de l'invocation du composant : l'exception recuperee n'est pas conforme. " + in_ac.getApplicationComponent() + "." + in_method, in_ite); } } }