Index: topia/src/java/org/codelutin/topia/hook/DefaultHookHelper.java diff -u /dev/null topia/src/java/org/codelutin/topia/hook/DefaultHookHelper.java:1.1 --- /dev/null Thu Jul 15 13:13:18 2004 +++ topia/src/java/org/codelutin/topia/hook/DefaultHookHelper.java Thu Jul 15 13:13:13 2004 @@ -0,0 +1,94 @@ +/* *##% + * Copyright (C) 2002, 2003 Code Lutin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *##%*/ + +/* * + * DefaultHookHelper.java + * + * Created: 3 juil. 2004 + * + * @author Benjamin Poussin + * Copyright Code Lutin + * @version $Revision: 1.1 $ + * + * Mise a jour: $Date: 2004/07/15 13:13:13 $ + * par : $Author: bpoussin $ + */ + +package org.codelutin.topia.hook; + +import java.util.Properties; +import java.util.IdentityHashMap; +import java.lang.reflect.Proxy; +import java.lang.reflect.InvocationHandler; +import java.util.ArrayList; +import org.codelutin.topia.TopiaContext; + +public class DefaultHookHelper implements HookHelper { // DefaultHookHelper + + protected TopiaContext context = null; + protected Properties properties = null; + protected IdentityHashMap hooked = new IdentityHashMap(); + + /** + * @param properties propriétés permettant de paramètrer les hooks + */ + public DefaultHookHelper(TopiaContext context, Properties properties){ + this.context = context; + this.properties = properties; + } + + public Object addHookSupport(Object o, Class []interfaces){ + if(o == null || Proxy.isProxyClass(o.getClass())){ + return o; + } + Object result = hooked.get(o); + if(result == null){ + InvocationHandler handler = + new ProxyHookHandler( + o, + hasCall("hook.call.pre"), + hasCall("hook.call.methode"), + hasCall("hook.call.post")); + + ArrayList classes = new ArrayList(); + classes.add(Hookable.class); + + for(int i=0; i + * Copyright Code Lutin + * @version $Revision: 1.1 $ + * + * Mise a jour: $Date: 2004/07/15 13:13:13 $ + * par : $Author: bpoussin $ + */ + +package org.codelutin.topia.hook; + +/** +* Classe permettant la simplification de la mise en place des hooks sur un +* objet +*/ +public interface HookHelper { // HookHelper + + /** + * Ajoute le support des hooks a un objet. Si l'objet passé en argument + * a déjà eu les hooks d'ajouté alors on ne fait rien. Alors on retourne + * le même objet supportant les hooks + * @param o l'objet sur lequel il faut ajouter les hooks + * @param interfaces les interfaces que doit implanter l'objet en plus des + * hook + */ + public Object addHookSupport(Object o, Class []interfaces); + +} // HookHelper + Index: topia/src/java/org/codelutin/topia/hook/Hookable.java diff -u /dev/null topia/src/java/org/codelutin/topia/hook/Hookable.java:1.1 --- /dev/null Thu Jul 15 13:13:18 2004 +++ topia/src/java/org/codelutin/topia/hook/Hookable.java Thu Jul 15 13:13:13 2004 @@ -0,0 +1,45 @@ +/* *##% + * Copyright (C) 2002, 2003 Code Lutin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *##%*/ + +/* * + * Hookable.java + * + * Created: 13 mai 2004 + * + * @author Benjamin Poussin + * Copyright Code Lutin + * @version $Revision: 1.1 $ + * + * Mise a jour: $Date: 2004/07/15 13:13:13 $ + * par : $Author: bpoussin $ + */ + +package org.codelutin.topia.hook; + +/** +* Interface dont doivent hériter les classes qui supporte les hooks pour leurs +* méthode. +* @see HookProxy +*/ +public interface Hookable { // Hookable + + public void addPreHook(String methodeName, TopiaHook o); + public void addPostHook(String methodeName, TopiaHook o); + +} // Hookable + Index: topia/src/java/org/codelutin/topia/hook/HookableSupport.java diff -u /dev/null topia/src/java/org/codelutin/topia/hook/HookableSupport.java:1.1 --- /dev/null Thu Jul 15 13:13:18 2004 +++ topia/src/java/org/codelutin/topia/hook/HookableSupport.java Thu Jul 15 13:13:13 2004 @@ -0,0 +1,107 @@ +/* *##% + * Copyright (C) 2002, 2003 Code Lutin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *##%*/ + +/* * + * HookableSupport.java + * + * Created: 13 mai 2004 + * + * @author Benjamin Poussin + * Copyright Code Lutin + * @version $Revision: 1.1 $ + * + * Mise a jour: $Date: 2004/07/15 13:13:13 $ + * par : $Author: bpoussin $ + */ + +package org.codelutin.topia.hook; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; +import java.util.Iterator; + +/** +* Cette classe implante Hookable, pour mettre en place facilement le support +* de hook +* Aucune garantie n'est donnée sur l'ordre d'execution des hooks, quelque soit +* l'ordre d'ajout des hooks. +*/ +public class HookableSupport implements Hookable { // HookableSupport + + protected HashMap preHooks = new HashMap(); + protected HashMap postHooks = new HashMap(); + + /** + * Ajoute un pre hook a une methode + */ + public void addPreHook(String methodeName, TopiaHook o){ + Set hooks = getPreHook(methodeName); + hooks.add(o); + } + + /** + * Ajoute un post hook a une methode + */ + public void addPostHook(String methodeName, TopiaHook o){ + Set hooks = getPostHook(methodeName); + hooks.add(o); + } + + /** + * Appelle tout les pre hooks d'une methode + */ + public void preCall(String methodeName, Object[] arguments){ + for(Iterator i=getPreHook(methodeName).iterator(); i.hasNext();){ + TopiaHook hook = (TopiaHook)i.next(); + hook.call(methodeName, arguments, null); + } + } + + /** + * Appelle tout les post hooks d'une methode, l'objet result de l'appel + * au premier hook est passé comme result pour l'appel au deuxieme hook + * et ainsi de suite + */ + public Object postCall(String methodeName, Object[] arguments, + Object result){ + for(Iterator i=getPostHook(methodeName).iterator(); i.hasNext();){ + TopiaHook hook = (TopiaHook)i.next(); + result = hook.call(methodeName, arguments, result); + } + return result; + } + + protected Set getPreHook(String methodeName){ + Set result = (Set)preHooks.get(methodeName); + if(result == null){ + preHooks.put(methodeName, result=new HashSet()); + } + return result; + } + + protected Set getPostHook(String methodeName){ + Set result = (Set)postHooks.get(methodeName); + if(result == null){ + preHooks.put(methodeName, result=new HashSet()); + } + return result; + } + +} // HookableSupport + Index: topia/src/java/org/codelutin/topia/hook/ProxyHookHandler.java diff -u /dev/null topia/src/java/org/codelutin/topia/hook/ProxyHookHandler.java:1.1 --- /dev/null Thu Jul 15 13:13:18 2004 +++ topia/src/java/org/codelutin/topia/hook/ProxyHookHandler.java Thu Jul 15 13:13:13 2004 @@ -0,0 +1,85 @@ +/* *##% + * Copyright (C) 2002, 2003 Code Lutin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *##%*/ + +/* * + * ProxyHookHandler.java + * + * Created: 13 mai 2004 + * + * @author Benjamin Poussin + * Copyright Code Lutin + * @version $Revision: 1.1 $ + * + * Mise a jour: $Date: 2004/07/15 13:13:13 $ + * par : $Author: bpoussin $ + */ + +package org.codelutin.topia.hook; + +import java.lang.reflect.InvocationHandler; +import java.beans.Expression; +import java.lang.reflect.Method; +import java.lang.Throwable; + +public class ProxyHookHandler extends HookableSupport + implements InvocationHandler { // ProxyHookHandler + protected Object hookedObject = null; + protected boolean callPre = true; + protected boolean callMethode = true; + protected boolean callPost = true; + + public ProxyHookHandler(Object hookedObject){ + this(hookedObject, true, true, true); + } + + public ProxyHookHandler(Object hookedObject, + boolean callPre, boolean callMethode, boolean callPost){ + this.hookedObject = hookedObject; + this.callPre = callPre; + this.callMethode = callMethode; + this.callPost = callPost; + } + + public Object getObject(){ + return hookedObject; + } + + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable { + Object result =null; + String methodName = method.getName(); + if("addPreHook".equals(methodName)){ + addPreHook((String)args[0], (TopiaHook)args[1]); + }else if("addPostHook".equals(methodName)){ + addPreHook((String)args[0], (TopiaHook)args[1]); + }else{ + if(callPre){ + preCall(methodName, args); + } + if(callMethode){ + Expression e = new Expression(hookedObject, methodName, args); + result = e.getValue(); + } + if(callPost){ + result = postCall(methodName, args, result); + } + } + return result; + } +} // ProxyHookHandler + Index: topia/src/java/org/codelutin/topia/hook/TopiaHook.java diff -u /dev/null topia/src/java/org/codelutin/topia/hook/TopiaHook.java:1.1 --- /dev/null Thu Jul 15 13:13:18 2004 +++ topia/src/java/org/codelutin/topia/hook/TopiaHook.java Thu Jul 15 13:13:13 2004 @@ -0,0 +1,50 @@ +/* *##% + * Copyright (C) 2002, 2003 Code Lutin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *##%*/ + +/* * + * TopiaHook.java + * + * Created: 13 mai 2004 + * + * @author Benjamin Poussin + * Copyright Code Lutin + * @version $Revision: 1.1 $ + * + * Mise a jour: $Date: 2004/07/15 13:13:13 $ + * par : $Author: bpoussin $ + */ + +package org.codelutin.topia.hook; + +/** +* Interface permettant de créer un objet hook que l'on enregistrera sur +* un objet hookable. +*/ +public interface TopiaHook { // TopiaHook + /** + * Cette méthode est appellé soit avant soit après l'execution de la méthode + * de l'objet suivant sont enregistrement. + * @param methodeName le nom de la méthode sur lequel le hook a été fait + * @param arguments les arguments de la méthode + * @param result si le hook est posé en postHook et que la méthode retourne + * un résultat alors result à la valeur du résultat, null sinon. + */ + public Object call(String methodeName, Object[] arguments, Object result); + +} // TopiaHook +