Clover coverage report - Ledge Components - SNAPSHOT
Coverage timestamp: Fri Nov 17 2006 05:13:20 CET
file stats: LOC: 222   Methods: 7
NCLOC: 146   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
DefaultEventWhiteboard.java 46.4% 57.4% 71.4% 55.1%
coverage coverage
 1    //
 2    //Copyright (c) 2003, Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
 3    //All rights reserved.
 4    //
 5    //Redistribution and use in source and binary forms, with or without modification,
 6    //are permitted provided that the following conditions are met:
 7    //
 8    //* Redistributions of source code must retain the above copyright notice,
 9    //this list of conditions and the following disclaimer.
 10    //* Redistributions in binary form must reproduce the above copyright notice,
 11    //this list of conditions and the following disclaimer in the documentation
 12    //and/or other materials provided with the distribution.
 13    //* Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
 14    //nor the names of its contributors may be used to endorse or promote products
 15    //derived from this software without specific prior written permission.
 16    //
 17    //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 18    //AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 19    //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 20    //IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 21    //INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 22    //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 23    //OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 24    //WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 25    //ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 26    //POSSIBILITY OF SUCH DAMAGE.
 27    //
 28   
 29    package org.objectledge.event;
 30   
 31    import java.lang.reflect.InvocationHandler;
 32    import java.lang.reflect.InvocationTargetException;
 33    import java.lang.reflect.Method;
 34    import java.lang.reflect.Proxy;
 35    import java.rmi.Remote;
 36    import java.util.HashMap;
 37    import java.util.HashSet;
 38    import java.util.Iterator;
 39    import java.util.Map;
 40    import java.util.Set;
 41    import java.util.WeakHashMap;
 42   
 43    import org.jcontainer.dna.Logger;
 44   
 45    /**
 46    * Default event forwarder implementation.
 47    *
 48    * @author <a href="mailto:rafal@caltha.pl">Rafal Krzewski</a>
 49    * @version $Id: DefaultEventWhiteboard.java,v 1.7 2006/02/08 18:22:08 zwierzem Exp $
 50    */
 51    public class DefaultEventWhiteboard implements EventWhiteboard
 52    {
 53    /** The logger. */
 54    private Logger logger;
 55   
 56    /**
 57    * The Map Listener interface -> ( Map trigger object -> Set of Listeners )
 58    */
 59    private Map<Class,Map<Object,Map>> interfaceMap = new HashMap<Class,Map<Object,Map>>();
 60   
 61    /** Created proxies for <code>Remote</code> objects. */
 62    private Map<Remote,Map<Class,Object>> proxies = new WeakHashMap<Remote,Map<Class,Object>>();
 63   
 64    /** The EventWhiteboardFactory */
 65    private EventWhiteboardFactory eventSystem;
 66   
 67    // Initailization ////////////////////////////////////////////////////////
 68   
 69    /**
 70    * Crates an EventWhiteboard instance.
 71    *
 72    * @param eventSystem the event system component.
 73    * @param logger the logger.
 74    */
 75  414 public DefaultEventWhiteboard(EventWhiteboardFactory eventSystem, Logger logger)
 76    {
 77  414 this.logger = logger;
 78  414 this.eventSystem = eventSystem;
 79    }
 80   
 81    /**
 82    * {@inheritDoc}
 83    */
 84  138 public synchronized void addListener(Class iface, Object listener, Object object)
 85    throws IllegalArgumentException
 86    {
 87  138 if (!iface.isInterface())
 88    {
 89  0 throw new IllegalArgumentException(iface.getName() + " is not an interface type");
 90    }
 91  138 if (!iface.isInstance(listener))
 92    {
 93  0 throw new IllegalArgumentException("Handler class " + listener.getClass().getName() +
 94    " does not implement " + iface.getName());
 95    }
 96  138 Map<Object,Map> triggerMap = interfaceMap.get(iface);
 97  138 if (triggerMap == null)
 98    {
 99  138 triggerMap = new WeakHashMap<Object,Map>();
 100  138 interfaceMap.put(iface, triggerMap);
 101    }
 102  138 Map handlers = triggerMap.get(object);
 103  138 if (handlers == null)
 104    {
 105  138 handlers = new WeakHashMap();
 106  138 triggerMap.put(object, handlers);
 107    }
 108  138 handlers.put(listener, null);
 109    }
 110   
 111    /**
 112    * {@inheritDoc}
 113    */
 114  92 public synchronized void removeListener(Class iface, Object listener, Object object)
 115    {
 116  92 Map triggerMap = (Map)interfaceMap.get(iface);
 117  92 if (triggerMap != null)
 118    {
 119  0 Map handlers = (Map)triggerMap.get(object);
 120  0 if (handlers != null)
 121    {
 122  0 handlers.remove(listener);
 123    }
 124    }
 125    }
 126   
 127    /**
 128    * {@inheritDoc}
 129    */
 130  0 public synchronized void addRemoteListener(Class iface, Remote listener, Object object)
 131    throws IllegalArgumentException
 132    {
 133  0 InvocationHandler handler = new RemoteInvocationHandler(iface, listener);
 134  0 Object proxy = Proxy.newProxyInstance(this.getClass().getClassLoader(),
 135    new Class[] { iface }, handler);
 136  0 Map<Class,Object> ifMap = proxies.get(listener);
 137  0 if(ifMap == null)
 138    {
 139  0 ifMap = new HashMap<Class,Object>();
 140  0 proxies.put(listener, ifMap);
 141    }
 142  0 ifMap.put(iface, proxy);
 143  0 addListener(iface, proxy, object);
 144    }
 145   
 146    /**
 147    * {@inheritDoc}
 148    */
 149  0 public synchronized void removeRemoteListener(Class iface, Remote listener, Object object)
 150    {
 151  0 Map ifMap = (Map)proxies.get(listener);
 152  0 if(ifMap != null)
 153    {
 154  0 Object proxy = ifMap.get(iface);
 155  0 if(proxy != null)
 156    {
 157  0 removeListener(iface, proxy, object);
 158    }
 159    }
 160    }
 161   
 162    /**
 163    * {@inheritDoc}
 164    */
 165  184 public void fireEvent(Method method, Object[] args, Object object)
 166    {
 167  184 if(eventSystem.isAsynchronous())
 168    {
 169  0 eventSystem.enqueueEvent(this, method, args, object);
 170    }
 171    else
 172    {
 173  184 dispatchEvent(method, args, object);
 174    }
 175    }
 176   
 177  184 void dispatchEvent(Method method, Object[] args, Object object)
 178    {
 179  184 Class iface = method.getDeclaringClass();
 180  184 Set currentHandlers = null;
 181  184 synchronized(this)
 182    {
 183  184 Map<Object,Map> triggerMap = interfaceMap.get(iface);
 184  184 if(triggerMap != null)
 185    {
 186  92 Map handlers = triggerMap.get(object);
 187  92 if(handlers != null)
 188    {
 189  92 currentHandlers = new HashSet(handlers.keySet());
 190    }
 191    }
 192    }
 193  184 if(currentHandlers != null)
 194    {
 195  92 Iterator i = currentHandlers.iterator();
 196  92 while(i.hasNext())
 197    {
 198  92 Object handler = i.next();
 199  92 try
 200    {
 201  92 method.invoke(handler, args);
 202    }
 203    catch(ThreadDeath t)
 204    {
 205  0 throw t;
 206    }
 207    catch(VirtualMachineError t)
 208    {
 209  0 throw t;
 210    }
 211    catch(InvocationTargetException e)
 212    {
 213  0 logger.error("Failed to invoke handler", e.getTargetException());
 214    }
 215    catch(Throwable t)
 216    {
 217  0 logger.error("Failed to invoke handler", t);
 218    }
 219    }
 220    }
 221    }
 222    }