psmith 2003/09/17 20:08:45 Modified: src/java/org/apache/log4j/plugins PluginRegistry.java tests/src/java/org/apache/log4j/plugins PluginTestCase.java Added: src/java/org/apache/log4j/plugins PluginEvent.java PluginListener.java Log: Added PluginEvent & associated Listener class to the PluginRegistry. Also included Test case to verify. PluginRegistry now exposes via listeners when each Plugin is started/stopped via the Registry. This is majorily useful in GUI situations where the View is/should be decoupled from the a controller/actions that modify the registry. Jalopolized. Revision Changes Path 1.8 +107 -36 jakarta-log4j/src/java/org/apache/log4j/plugins/PluginRegistry.java Index: PluginRegistry.java =================================================================== RCS file: /home/cvs/jakarta-log4j/src/java/org/apache/log4j/plugins/PluginRegistry.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- PluginRegistry.java 26 Jun 2003 22:59:44 -0000 1.7 +++ PluginRegistry.java 18 Sep 2003 03:08:45 -0000 1.8 @@ -53,12 +53,14 @@ import org.apache.log4j.spi.LoggerRepository; import org.apache.log4j.spi.LoggerRepositoryEventListener; +import java.util.ArrayList; import java.util.Collections; -import java.util.Map; import java.util.HashMap; -import java.util.List; -import java.util.ArrayList; import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.swing.event.EventListenerList; /** @@ -76,6 +78,8 @@ /** the listener used to listen for repository events. */ private static RepositoryListener listener = new RepositoryListener(); + private static final EventListenerList listenerList = + new EventListenerList(); /** Starts a Plugin with default logger repository. @@ -101,31 +105,33 @@ * @param name The name to check the repository for * @return true if the name is already in use, otherwise false */ - public static boolean pluginNameExists(String name){ + public static boolean pluginNameExists(String name) { LoggerRepository repository = LogManager.getLoggerRepository(); return pluginNameExists(name, repository); } - /** * Returns true if the specified name is already taken by - * an existing Plugin registered within the scope of the specified + * an existing Plugin registered within the scope of the specified * LoggerRepository. * @param name The name to check the repository for * @param repository the repository to check the name against * @return true if the name is already in use, otherwise false */ - public static boolean pluginNameExists(String name, LoggerRepository repository){ - synchronized(repositoryMap){ + public static boolean pluginNameExists( + String name, LoggerRepository repository) { + synchronized (repositoryMap) { Map pluginMap = (Map) repositoryMap.get(repository); - if( pluginMap != null && pluginMap.containsKey(name)){ + + if ((pluginMap != null) && pluginMap.containsKey(name)) { return true; } } + return false; } - + /** Starts a plugin with a given logger repository. @@ -175,60 +181,102 @@ // start the new plugin plugin.activateOptions(); + firePluginStarted(plugin); return plugin; } } /** - Returns all the plugins for a given repository. - - @param repository the logger repository to get the plugins from. - @return List list of plugins from the repository. */ + * @param plugin + */ + private static void firePluginStarted(Plugin plugin) { + PluginListener[] listeners = + (PluginListener[]) listenerList.getListeners(PluginListener.class); + + PluginEvent e = null; + + for (int i = 0; i < listeners.length; i++) { + if (e == null) { + e = new PluginEvent(plugin); + } + + listeners[i].pluginStarted(e); + } + } + + private static void firePluginStopped(Plugin plugin) { + PluginListener[] listeners = + (PluginListener[]) listenerList.getListeners(PluginListener.class); + + PluginEvent e = null; + + for (int i = 0; i < listeners.length; i++) { + if (e == null) { + e = new PluginEvent(plugin); + } + + listeners[i].pluginStopped(e); + } + } + + /** + Returns all the plugins for a given repository. + + @param repository the logger repository to get the plugins from. + @return List list of plugins from the repository. */ public static List getPlugins(LoggerRepository repository) { synchronized (repositoryMap) { // get plugin map for repository Map pluginMap = (Map) repositoryMap.get(repository); + if (pluginMap == null) { - return Collections.EMPTY_LIST; + return Collections.EMPTY_LIST; } else { - List pluginList = new ArrayList(pluginMap.size()); - Iterator iter = pluginMap.values().iterator(); - while (iter.hasNext()) { - pluginList.add(iter.next()); - } - return pluginList; + List pluginList = new ArrayList(pluginMap.size()); + Iterator iter = pluginMap.values().iterator(); + + while (iter.hasNext()) { + pluginList.add(iter.next()); + } + + return pluginList; } } } - + /** Returns all the plugins for a given repository that are instances of a certain class. - + @param repository the logger repository to get the plugins from. @param pluginClass the class the plugin must implement to be selected. @return List list of plugins from the repository. */ - public static List getPlugins(LoggerRepository repository, Class pluginClass) { + public static List getPlugins( + LoggerRepository repository, Class pluginClass) { synchronized (repositoryMap) { // get plugin map for repository Map pluginMap = (Map) repositoryMap.get(repository); + if (pluginMap == null) { - return Collections.EMPTY_LIST; + return Collections.EMPTY_LIST; } else { - List pluginList = new ArrayList(pluginMap.size()); - Iterator iter = pluginMap.values().iterator(); - while (iter.hasNext()) { - Object plugin = iter.next(); - if (pluginClass.isInstance(plugin)) { - pluginList.add(plugin); - } - } - return pluginList; + List pluginList = new ArrayList(pluginMap.size()); + Iterator iter = pluginMap.values().iterator(); + + while (iter.hasNext()) { + Object plugin = iter.next(); + + if (pluginClass.isInstance(plugin)) { + pluginList.add(plugin); + } + } + + return pluginList; } } } - + /** Stops a plugin by plugin object. @@ -281,6 +329,7 @@ // remove it from the plugin map pluginMap.remove(pluginName); + firePluginStopped(plugin); // if no more plugins, remove the plugin map from // repository map @@ -318,13 +367,35 @@ Iterator iter = pluginMap.values().iterator(); while (iter.hasNext()) { - ((Plugin) iter.next()).shutdown(); + Plugin plugin = (Plugin) iter.next(); + plugin.shutdown(); + firePluginStopped(plugin); } // since no more plugins, remove plugin map from // the repository repositoryMap.remove(repository); } + } + + /** + * Adds a PluginListener to this registry to be notified + * of PluginEvents + * + * @param l PluginListener to add to this registry + */ + public static final void addPluginListener(PluginListener l) { + listenerList.add(PluginListener.class, l); + } + + /** + * Removes a particular PluginListener from this registry + * such that it will no longer be notified of PluginEvents + * + * @param l PluginListener to remove + */ + public static final void removePluginListener(PluginListener l) { + listenerList.remove(PluginListener.class, l); } /** 1.1 jakarta-log4j/src/java/org/apache/log4j/plugins/PluginEvent.java Index: PluginEvent.java =================================================================== /* * ============================================================================ * The Apache Software License, Version 1.1 * ============================================================================ * * Copyright (C) 1999 The Apache Software Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. The end-user documentation included with the redistribution, if any, must * include the following acknowledgment: "This product includes software * developed by the Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, if * and wherever such third-party acknowledgments normally appear. * * 4. The names "log4j" and "Apache Software Foundation" must not be used to * endorse or promote products derived from this software without prior * written permission. For written permission, please contact * [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", nor may * "Apache" appear in their name, without prior written permission of the * Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This software consists of voluntary contributions made by many individuals * on behalf of the Apache Software Foundation. For more information on the * Apache Software Foundation, please see <http://www.apache.org/>. * */ package org.apache.log4j.plugins; import java.util.EventObject; /** * All Plugin events are encapsulated in this class, which * simply contains the source Plugin, but may in future include more * information. * * @author Paul Smith */ public class PluginEvent extends EventObject { /** * @param source The source plugin of the event */ PluginEvent(Plugin source) { super(source); } /** * Returns the source Plugin of this event, which is simple * the getSource() method casted to Plugin for convenience. * @return Plugin source of this event */ public Plugin getPlugin() { return (Plugin) getSource(); } } 1.1 jakarta-log4j/src/java/org/apache/log4j/plugins/PluginListener.java Index: PluginListener.java =================================================================== /* * ============================================================================ * The Apache Software License, Version 1.1 * ============================================================================ * * Copyright (C) 1999 The Apache Software Foundation. All rights reserved. * * Redistribution and use in source and binary forms, with or without modifica- * tion, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. The end-user documentation included with the redistribution, if any, must * include the following acknowledgment: "This product includes software * developed by the Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, if * and wherever such third-party acknowledgments normally appear. * * 4. The names "log4j" and "Apache Software Foundation" must not be used to * endorse or promote products derived from this software without prior * written permission. For written permission, please contact * [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache", nor may * "Apache" appear in their name, without prior written permission of the * Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * This software consists of voluntary contributions made by many individuals * on behalf of the Apache Software Foundation. For more information on the * Apache Software Foundation, please see <http://www.apache.org/>. * */ /* */ package org.apache.log4j.plugins; import java.util.EventListener; /** * PluginListeners are notified when plugins are started or stopped * by the PluginRegistry. * * @author Paul Smith <[EMAIL PROTECTED]> */ public interface PluginListener extends EventListener { public void pluginStarted(PluginEvent e); public void pluginStopped(PluginEvent e); } 1.8 +47 -0 jakarta-log4j/tests/src/java/org/apache/log4j/plugins/PluginTestCase.java Index: PluginTestCase.java =================================================================== RCS file: /home/cvs/jakarta-log4j/tests/src/java/org/apache/log4j/plugins/PluginTestCase.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- PluginTestCase.java 17 Sep 2003 23:30:14 -0000 1.7 +++ PluginTestCase.java 18 Sep 2003 03:08:45 -0000 1.8 @@ -368,6 +368,26 @@ Compare.compare(getOutputFile(testName), getWitnessFile(testName))); } + public void testPluginListeners(){ + Plugin p = new PluginTester1("MyNewPlugin",1); + PluginListenerLatch l = new PluginListenerLatch(); + PluginRegistry.stopAllPlugins(); + PluginRegistry.addPluginListener(l); + PluginRegistry.startPlugin(p); + + PluginEvent e = l.LastEvent; + + assertTrue("PluginListener should have been notified of start", l.StartLatch); + assertTrue("PluginListener stop latch should not be activated", !l.StopLatch); + assertTrue("PluginListener should be given reference to Plugin", e.getPlugin() == p); + + PluginRegistry.stopAllPlugins(); + assertTrue("PluginListener should have been notified of stop", l.StopLatch); + assertTrue("PluginListener should not have been notified of start", !l.StartLatch); + assertTrue("PluginListener should be given reference to Plugin", l.LastEvent.getPlugin() == p); + assertTrue("PluginListener should have received a distinct event object", l.LastEvent != e); + } + public void testPropertyChangeListeners() { Plugin plugin = new PluginTester1("PluginTest1", 1); @@ -456,10 +476,37 @@ suite.addTest(new PluginTestCase("test1")); suite.addTest(new PluginTestCase("test2")); suite.addTest(new PluginTestCase("testPropertyChangeListeners")); + suite.addTest(new PluginTestCase("testPluginListeners")); return suite; } + private static class PluginListenerLatch implements PluginListener{ + private boolean StartLatch; + private boolean StopLatch; + private PluginEvent LastEvent; + /* (non-Javadoc) + * @see org.apache.log4j.plugins.PluginListener#pluginStarted(org.apache.log4j.plugins.PluginEvent) + */ + public void pluginStarted(PluginEvent e) { + StartLatch = true; + LastEvent = e; + } + + /* (non-Javadoc) + * @see org.apache.log4j.plugins.PluginListener#pluginStopped(org.apache.log4j.plugins.PluginEvent) + */ + public void pluginStopped(PluginEvent e) { + StopLatch = true; + LastEvent = e; + } + void reset(){ + StartLatch = false; + StopLatch = false; + LastEvent = null; + } + } + private static class PropertyChangeListenerLatch implements PropertyChangeListener { boolean latch = false;
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]