You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by oh...@apache.org on 2011/11/28 22:05:40 UTC
svn commit: r1207608 -
/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/event/EventSource.java
Author: oheger
Date: Mon Nov 28 21:05:39 2011
New Revision: 1207608
URL: http://svn.apache.org/viewvc?rev=1207608&view=rev
Log:
Java 1.5 compatibility: Javadocs, raw types, etc. Replaced event listener collections by CopyOnWriteArrayList.
Modified:
commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/event/EventSource.java
Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/event/EventSource.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/event/EventSource.java?rev=1207608&r1=1207607&r2=1207608&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/event/EventSource.java (original)
+++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/event/EventSource.java Mon Nov 28 21:05:39 2011
@@ -20,7 +20,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
-import java.util.LinkedList;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
* <p>
@@ -29,8 +29,8 @@ import java.util.LinkedList;
* <p>
* This class implements functionality for managing a set of event listeners
* that can be notified when an event occurs. It can be extended by
- * configuration classes that support the event machanism. In this case these
- * classes only need to call the <code>fireEvent()</code> method when an event
+ * configuration classes that support the event mechanism. In this case these
+ * classes only need to call the {@code fireEvent()} method when an event
* is to be delivered to the registered listeners.
* </p>
* <p>
@@ -38,28 +38,28 @@ import java.util.LinkedList;
* on a configuration that cause events. The operations are synchronized.
* </p>
* <p>
- * With the <code>detailEvents</code> property the number of detail events can
+ * With the {@code detailEvents} property the number of detail events can
* be controlled. Some methods in configuration classes are implemented in a way
* that they call other methods that can generate their own events. One example
- * is the <code>setProperty()</code> method that can be implemented as a
- * combination of <code>clearProperty()</code> and <code>addProperty()</code>.
- * With <code>detailEvents</code> set to <b>true</b>, all involved methods
+ * is the {@code setProperty()} method that can be implemented as a
+ * combination of {@code clearProperty()} and {@code addProperty()}.
+ * With {@code detailEvents} set to <b>true</b>, all involved methods
* will generate events (i.e. listeners will receive property set events,
* property clear events, and property add events). If this mode is turned off
* (which is the default), detail events are suppressed, so only property set
* events will be received. Note that the number of received detail events may
* differ for different configuration implementations.
- * <code>{@link org.apache.commons.configuration.HierarchicalConfiguration HierarchicalConfiguration}</code>
- * for instance has a custom implementation of <code>setProperty()</code>,
+ * {@link org.apache.commons.configuration.HierarchicalConfiguration HierarchicalConfiguration}
+ * for instance has a custom implementation of {@code setProperty()},
* which does not generate any detail events.
* </p>
* <p>
* In addition to "normal" events, error events are supported. Such
* events signal an internal problem that occurred during access of properties.
* For them a special listener interface exists:
- * <code>{@link ConfigurationErrorListener}</code>. There is another set of
+ * {@link ConfigurationErrorListener}. There is another set of
* methods dealing with event listeners of this type. The
- * <code>fireError()</code> method can be used by derived classes to send
+ * {@code fireError()} method can be used by derived classes to send
* notifications about errors to registered observers.
* </p>
*
@@ -70,16 +70,16 @@ import java.util.LinkedList;
public class EventSource
{
/** A collection for the registered event listeners. */
- private Collection listeners;
+ private Collection<ConfigurationListener> listeners;
/** A collection for the registered error listeners.*/
- private Collection errorListeners;
+ private Collection<ConfigurationErrorListener> errorListeners;
/** A counter for the detail events. */
private int detailEvents;
/**
- * Creates a new instance of <code>EventSource</code>.
+ * Creates a new instance of {@code EventSource}.
*/
public EventSource()
{
@@ -93,7 +93,8 @@ public class EventSource
*/
public void addConfigurationListener(ConfigurationListener l)
{
- doAddListener(listeners, l);
+ checkListener(l);
+ listeners.add(l);
}
/**
@@ -105,7 +106,7 @@ public class EventSource
*/
public boolean removeConfigurationListener(ConfigurationListener l)
{
- return doRemoveListener(listeners, l);
+ return listeners.remove(l);
}
/**
@@ -113,13 +114,13 @@ public class EventSource
* currently registered at this object.
*
* @return a collection with the registered
- * <code>ConfigurationListener</code>s (this collection is a snapshot
+ * {@code ConfigurationListener}s (this collection is a snapshot
* of the currently registered listeners; manipulating it has no effect
* on this event source object)
*/
- public Collection getConfigurationListeners()
+ public Collection<ConfigurationListener> getConfigurationListeners()
{
- return doGetListeners(listeners);
+ return Collections.unmodifiableCollection(new ArrayList<ConfigurationListener>(listeners));
}
/**
@@ -127,7 +128,7 @@ public class EventSource
*/
public void clearConfigurationListeners()
{
- doClearListeners(listeners);
+ listeners.clear();
}
/**
@@ -137,17 +138,14 @@ public class EventSource
*/
public boolean isDetailEvents()
{
- synchronized (listeners)
- {
- return detailEvents > 0;
- }
+ return checkDetailEvents(0);
}
/**
* Determines whether detail events should be generated. If enabled, some
* methods can generate multiple update events. Note that this method
* records the number of calls, i.e. if for instance
- * <code>setDetailEvents(false)</code> was called three times, you will
+ * {@code setDetailEvents(false)} was called three times, you will
* have to invoke the method as often to enable the details.
*
* @param enable a flag if detail events should be enabled or disabled
@@ -176,7 +174,8 @@ public class EventSource
*/
public void addErrorListener(ConfigurationErrorListener l)
{
- doAddListener(errorListeners, l);
+ checkListener(l);
+ errorListeners.add(l);
}
/**
@@ -189,7 +188,7 @@ public class EventSource
*/
public boolean removeErrorListener(ConfigurationErrorListener l)
{
- return doRemoveListener(errorListeners, l);
+ return errorListeners.remove(l);
}
/**
@@ -199,7 +198,7 @@ public class EventSource
*/
public void clearErrorListeners()
{
- doClearListeners(errorListeners);
+ errorListeners.clear();
}
/**
@@ -207,19 +206,19 @@ public class EventSource
* currently registered at this object.
*
* @return a collection with the registered
- * <code>ConfigurationErrorListener</code>s (this collection is a
+ * {@code ConfigurationErrorListener}s (this collection is a
* snapshot of the currently registered listeners; it cannot be manipulated)
* @since 1.4
*/
- public Collection getErrorListeners()
+ public Collection<ConfigurationErrorListener> getErrorListeners()
{
- return doGetListeners(errorListeners);
+ return Collections.unmodifiableCollection(new ArrayList<ConfigurationErrorListener>(errorListeners));
}
/**
* Creates an event object and delivers it to all registered event
* listeners. The method will check first if sending an event is allowed
- * (making use of the <code>detailEvents</code> property), and if
+ * (making use of the {@code detailEvents} property), and if
* listeners are registered.
*
* @param type the event's type
@@ -229,31 +228,24 @@ public class EventSource
*/
protected void fireEvent(int type, String propName, Object propValue, boolean before)
{
- Collection listenersToCall = null;
-
- synchronized (listeners)
+ if (checkDetailEvents(-1))
{
- if (detailEvents >= 0 && listeners.size() > 0)
+ Iterator<ConfigurationListener> it = listeners.iterator();
+ if (it.hasNext())
{
- // Copy listeners to another collection so that manipulating
- // the listener list during event delivery won't cause problems
- listenersToCall = new ArrayList(listeners);
- }
- }
-
- if (listenersToCall != null)
- {
- ConfigurationEvent event = createEvent(type, propName, propValue, before);
- for (Iterator it = listenersToCall.iterator(); it.hasNext();)
- {
- ((ConfigurationListener) it.next()).configurationChanged(event);
+ ConfigurationEvent event =
+ createEvent(type, propName, propValue, before);
+ while (it.hasNext())
+ {
+ it.next().configurationChanged(event);
+ }
}
}
}
/**
- * Creates a <code>ConfigurationEvent</code> object based on the passed in
- * parameters. This is called by <code>fireEvent()</code> if it decides
+ * Creates a {@code ConfigurationEvent} object based on the passed in
+ * parameters. This is called by {@code fireEvent()} if it decides
* that an event needs to be generated.
*
* @param type the event's type
@@ -274,42 +266,32 @@ public class EventSource
* @param type the event's type
* @param propName the name of the affected property (can be <b>null</b>)
* @param propValue the value of the affected property (can be <b>null</b>)
- * @param ex the <code>Throwable</code> object that caused this error event
+ * @param ex the {@code Throwable} object that caused this error event
* @since 1.4
*/
protected void fireError(int type, String propName, Object propValue, Throwable ex)
{
- Collection listenersToCall = null;
-
- synchronized (errorListeners)
+ Iterator<ConfigurationErrorListener> it = errorListeners.iterator();
+ if (it.hasNext())
{
- if (errorListeners.size() > 0)
+ ConfigurationErrorEvent event =
+ createErrorEvent(type, propName, propValue, ex);
+ while (it.hasNext())
{
- // Copy listeners to another collection so that manipulating
- // the listener list during event delivery won't cause problems
- listenersToCall = new ArrayList(errorListeners);
- }
- }
-
- if (listenersToCall != null)
- {
- ConfigurationErrorEvent event = createErrorEvent(type, propName, propValue, ex);
- for (Iterator it = listenersToCall.iterator(); it.hasNext();)
- {
- ((ConfigurationErrorListener) it.next()).configurationError(event);
+ it.next().configurationError(event);
}
}
}
/**
- * Creates a <code>ConfigurationErrorEvent</code> object based on the
- * passed in parameters. This is called by <code>fireError()</code> if it
+ * Creates a {@code ConfigurationErrorEvent} object based on the
+ * passed in parameters. This is called by {@code fireError()} if it
* decides that an event needs to be generated.
*
* @param type the event's type
* @param propName the name of the affected property (can be <b>null</b>)
* @param propValue the value of the affected property (can be <b>null</b>)
- * @param ex the <code>Throwable</code> object that caused this error
+ * @param ex the {@code Throwable} object that caused this error
* event
* @return the event object
* @since 1.4
@@ -320,15 +302,16 @@ public class EventSource
}
/**
- * Overrides the <code>clone()</code> method to correctly handle so far
+ * Overrides the {@code clone()} method to correctly handle so far
* registered event listeners. This implementation ensures that the clone
* will have empty event listener lists, i.e. the listeners registered at an
- * <code>EventSource</code> object will not be copied.
+ * {@code EventSource} object will not be copied.
*
* @return the cloned object
* @throws CloneNotSupportedException if cloning is not allowed
* @since 1.4
*/
+ @Override
protected Object clone() throws CloneNotSupportedException
{
EventSource copy = (EventSource) super.clone();
@@ -337,73 +320,42 @@ public class EventSource
}
/**
- * Adds a new listener object to a listener collection. This is done in a
- * synchronized block. The listener must not be <b>null</b>.
+ * Checks whether the specified event listener is not <b>null</b>. If this
+ * is the case, an {@code IllegalArgumentException} exception is thrown.
*
- * @param listeners the collection with the listeners
- * @param l the listener object
+ * @param l the listener to be checked
+ * @throws IllegalArgumentException if the listener is <b>null</b>
*/
- private static void doAddListener(Collection listeners, Object l)
+ private static void checkListener(Object l)
{
if (l == null)
{
throw new IllegalArgumentException("Listener must not be null!");
}
- synchronized (listeners)
- {
- listeners.add(l);
- }
- }
-
- /**
- * Removes an event listener from a listener collection. This is done in a
- * synchronized block.
- *
- * @param listeners the collection with the listeners
- * @param l the listener object
- * @return a flag whether the listener could be found and removed
- */
- private static boolean doRemoveListener(Collection listeners, Object l)
- {
- synchronized (listeners)
- {
- return listeners.remove(l);
- }
}
/**
- * Removes all entries from the given list of event listeners.
- *
- * @param listeners the collection with the listeners
+ * Initializes the collections for storing registered event listeners.
*/
- private static void doClearListeners(Collection listeners)
+ private void initListeners()
{
- synchronized (listeners)
- {
- listeners.clear();
- }
+ listeners = new CopyOnWriteArrayList<ConfigurationListener>();
+ errorListeners = new CopyOnWriteArrayList<ConfigurationErrorListener>();
}
/**
- * Returns an unmodifiable snapshot of the given event listener collection.
+ * Helper method for checking the current counter for detail events. This
+ * method checks whether the counter is greater than the passed in limit.
*
- * @param listeners the collection with the listeners
- * @return a snapshot of the listeners collection
+ * @param limit the limit to be compared to
+ * @return <b>true</b> if the counter is greater than the limit,
+ * <b>false</b> otherwise
*/
- private static Collection doGetListeners(Collection listeners)
+ private boolean checkDetailEvents(int limit)
{
synchronized (listeners)
{
- return Collections.unmodifiableCollection(new ArrayList(listeners));
+ return detailEvents > limit;
}
}
-
- /**
- * Initializes the collections for storing registered event listeners.
- */
- private void initListeners()
- {
- listeners = new LinkedList();
- errorListeners = new LinkedList();
- }
}