Author: bayard
Date: Sun Jul 18 06:05:51 2010
New Revision: 965165
URL: http://svn.apache.org/viewvc?rev=965165&view=rev
Log:
Adding Michael Wooten's event support utilities from LANG-580
Added:
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/AbstractEventSupport.java
(with props)
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/EventSupport.java
(with props)
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/ReflectiveEventSupport.java
(with props)
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/event/
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/event/AbstractEventSupportTest.java
(with props)
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/event/ReflectiveEventSupportTest.java
(with props)
Added:
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/AbstractEventSupport.java
URL:
http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/AbstractEventSupport.java?rev=965165&view=auto
==============================================================================
---
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/AbstractEventSupport.java
(added)
+++
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/AbstractEventSupport.java
Sun Jul 18 06:05:51 2010
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.lang3.event;
+
+import java.io.Serializable;
+import java.util.EventListener;
+import java.util.EventObject;
+import java.util.Iterator;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.commons.lang3.Validate;
+
+/**
+ * <p>
+ * The AbstractEventSupport class provides an abstract base class framework for
+ * managing {...@link EventListener} objects and for firing {...@link
EventObject}s to
+ * those listeners. The class provides the ability to register a "source"
object
+ * that should be used as the source of the events, as well as the ability to
+ * register and unregister listeners in a thread-safe manner. The class also
+ * provides support for iterating over the registered listeners.
+ * </p>
+ *
+ * <p>
+ * Subclasses of the AbstractEventSupport class are designed to implement
+ * methods for firing events. The implementations can make use of both the
+ * iterable functionality and use the associated source object as the source
+ * of the events.
+ * </p>
+ *
+ * <p>
+ * Example:
+ * <code><pre>
+ * public WindowSupport extends AbstractEventSupport<WindowListener> {
+ *
+ * public WindowSupport(Window source) {
+ * super(source);
+ * }
+ *
+ * public void fireWindowOpened(int windowId, int oldState, int newState) {
+ * WindowEvent windowEvent =
+ * new WindowEvent((Window) getSource(), windowId, oldState,
newState);
+ * for (WindowListener listener : this)
+ * {
+ * listener.windowOpened(windowEvent);
+ * }
+ * }
+ * }
+ * </pre></code>
+ * </p>
+ *
+ * @author <a href="mailto:[email protected]">Michael Wooten</a>
+ *
+ * @param <L> the subclass of {...@link EventListener} that this event support
+ * class can register.
+ *
+ * @since 3.0
+ */
+public abstract class AbstractEventSupport<L extends EventListener>
+ implements EventSupport<L>, Iterable<L>, Serializable {
+
+ /**
+ * The serialization unique version identifier.
+ */
+ private static final long serialVersionUID = 20100310L;
+
+ /**
+ * The list used to hold the registered listeners. This list is
+ * intentionally a thread-safe copy-on-write-array so that traversals over
+ * the list of listeners will be atomic.
+ */
+ private final CopyOnWriteArrayList<L> listeners;
+
+ /**
+ * The object registered as the source of events fired to the listeners.
+ */
+ private final Object source;
+
+ /**
+ * Constructs a new AbstractEventSupport object and associates it with the
+ * object that will be used as the source of all events sent to the
+ * listeners.
+ *
+ * @param source the object that will be used as the source of all events
+ * posted to the listeners.
+ *
+ * @throws NullPointerException if <code>source</code> is
+ * <code>null</code>.
+ */
+ protected AbstractEventSupport(Object source) {
+ Validate.notNull(source, "source cannot be null");
+ this.source = source;
+ this.listeners = new CopyOnWriteArrayList<L>();
+ }
+
+ /**
+ * Registers a listener to receive events posted the by the supported
class.
+ *
+ * @param listener the listener to register for posted events. Values of
+ * <code>null</code> will be ignored.
+ */
+ public void addListener(L listener) {
+ if (listener != null)
+ {
+ this.listeners.add(listener);
+ }
+ }
+
+ /**
+ * Unregisters a listener from receiving events posted by the supported
+ * class.
+ *
+ * @param listener the listener to stop posting events to. Values of
+ * <code>null</code> will be ignored.
+ */
+ public void removeListener(L listener) {
+ if (listener != null)
+ {
+ this.listeners.remove(listener);
+ }
+ }
+
+ /**
+ * Returns a reference to the object registered as the source of events
+ * broadcast to the listeners.
+ *
+ * @return the object that was initially registered to be the source of all
+ * events sent to the listeners.
+ */
+ public Object getSource() {
+ return this.source;
+ }
+
+ /**
+ * Returns an iterator over the current list of listeners. This iterator is
+ * immutable and does not support {...@link Iterator#remove()} operations.
+ *
+ * @return an iterator to iterate over the currently registered listeners.
+ */
+ public Iterator<L> iterator() {
+ return this.listeners.iterator();
+ }
+}
Propchange:
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/AbstractEventSupport.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/EventSupport.java
URL:
http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/EventSupport.java?rev=965165&view=auto
==============================================================================
---
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/EventSupport.java
(added)
+++
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/EventSupport.java
Sun Jul 18 06:05:51 2010
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.lang3.event;
+
+import java.util.EventListener;
+
+/**
+ * <p>
+ * The EventSupport interface identifies as class as being able to register
+ * listeners for events.
+ * </p>
+ *
+ * @author <a href="mailto:[email protected]">Michael Wooten</a>
+ *
+ * @param <L> the subclass of {...@link EventListener} that this event support
+ * class can register.
+ *
+ * @since 3.0
+ */
+public interface EventSupport<L extends EventListener> {
+
+ /**
+ * Registers a listener to receive events posted the by the supported
class.
+ *
+ * @param listener the listener to register for posted events. Values of
+ * <code>null</code> will be ignored.
+ */
+ public void addListener(L listener);
+
+ /**
+ * Unregisters a listener from receiving events posted by the supported
+ * class.
+ *
+ * @param listener the listener to stop posting events to. Values of
+ * <code>null</code> will be ignored.
+ */
+ public void removeListener(L listener);
+}
Propchange:
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/EventSupport.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/ReflectiveEventSupport.java
URL:
http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/ReflectiveEventSupport.java?rev=965165&view=auto
==============================================================================
---
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/ReflectiveEventSupport.java
(added)
+++
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/ReflectiveEventSupport.java
Sun Jul 18 06:05:51 2010
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.lang3.event;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.EventListener;
+import java.util.EventObject;
+
+import org.apache.commons.lang3.Validate;
+import org.apache.commons.lang3.reflect.MethodUtils;
+
+/**
+ * <p>
+ * The ReflectiveEventSupport class provides a means of posting
+ * {...@link EventObject}s to registered listeners. The class uses reflection
to
+ * call specified methods on the listeners, either by {...@link Method} or
method
+ * name.
+ * </p>
+ *
+ * <p>
+ * <em>NOTE: The methods on the listeners must be accessible in order to be
+ * called.</em>
+ * </p>
+ *
+ * <p>
+ * Example:
+ * <code><pre>
+ * ReflectiveEventSupport<ChangeListener> reflectiveEventSupport =
+ * new ReflectiveEventSupport<ChangeListener>(this);
+ *
+ * ...
+ *
+ * reflectiveEventSupport.addListener(listener);
+ *
+ * ...
+ *
+ * reflectiveEventSupport.fireEvent("stateChanged",
+ * new ChangeEvent(reflectiveEventSupport.getSource());
+ * </pre></code>
+ * </p>
+ *
+ * @author <a href="mailto:[email protected]">Michael Wooten</a>
+ *
+ * @param <L> the subclass of {...@link EventListener} that this event support
+ * class can register.
+ *
+ * @since 3.0
+ */
+public class ReflectiveEventSupport<L extends EventListener>
+ extends AbstractEventSupport<L> {
+
+ /**
+ * The serialization unique version identifier.
+ */
+ private static final long serialVersionUID = 20100310L;
+
+ /**
+ * Constructs a new ReflectiveEventSupport object and associates it with
the
+ * object that can be used as the source of all events sent to the
+ * listeners.
+ *
+ * @param source the object that can be used as the source of all events
+ * posted to the listeners.
+ *
+ * @throws NullPointerException if <code>source</code> is
+ * <code>null</code>.
+ */
+ public ReflectiveEventSupport(Object source) {
+ super(source);
+ }
+
+ /**
+ * Fires the provided event object to the named method specified on each
of
+ * the listeners registered with this event support class.
+ *
+ * @param <E>
+ * the {...@link EventObject} type that will be posted to the
+ * listeners.
+ *
+ * @param methodName
+ * the name of the method that should be called on each of the
+ * listeners.
+ * @param eventObject
+ * the event object that will be passed to the listener's
method.
+ *
+ * @throws NullPointerException
+ * if <code>methodName</code> is <code>null</code>.
+ * @throws NoSuchMethodException
+ * if there is no such accessible method
+ * @throws InvocationTargetException
+ * wraps an exception thrown by the method invoked
+ * @throws IllegalAccessException
+ * if the requested method is not accessible via reflection
+ */
+ public <E extends EventObject> void fireEvent(String methodName, E
eventObject)
+ throws NoSuchMethodException, IllegalAccessException,
InvocationTargetException {
+ Validate.notNull(methodName, "methodName cannot be null");
+ for (L listener : this) {
+ MethodUtils.invokeMethod(listener, methodName, eventObject);
+ }
+ }
+
+ /**
+ * Fires the provided event object to the method specified on each of the
+ * listeners registered with this event support class.
+ *
+ * @param <E>
+ * the {...@link EventObject} type that will be posted to the
+ * listeners.
+ * @param method
+ * the method that should be called on each of the listeners.
+ * @param eventObject
+ * the event object that will be passed to the listener's
method.
+ *
+ * @throws NullPointerException
+ * if <code>method</code> is <code>null</code>.
+ * @throws NoSuchMethodException
+ * if there is no such accessible method
+ * @throws InvocationTargetException
+ * wraps an exception thrown by the method invoked
+ * @throws IllegalAccessException
+ * if the requested method is not accessible via reflection
+ */
+ public <E extends EventObject> void fireEvent(Method method, E
eventObject)
+ throws NoSuchMethodException, IllegalAccessException,
InvocationTargetException {
+ Validate.notNull(method, "method cannot be null");
+ Method accessibleMethod = MethodUtils.getAccessibleMethod(method);
+ for (L listener : this) {
+ accessibleMethod.invoke(listener, eventObject);
+ }
+ }
+}
Propchange:
commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/event/ReflectiveEventSupport.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/event/AbstractEventSupportTest.java
URL:
http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/event/AbstractEventSupportTest.java?rev=965165&view=auto
==============================================================================
---
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/event/AbstractEventSupportTest.java
(added)
+++
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/event/AbstractEventSupportTest.java
Sun Jul 18 06:05:51 2010
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.lang3.event;
+
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import junit.framework.TestCase;
+
+/**
+ * <p>
+ * The {...@link AbstractEventSupportTestCase} class provides test cases for
+ * testing the {...@link AbstractEventSupport} class.
+ * </p>
+ *
+ * @author <a href="mailto:[email protected]">Michael Wooten</a>
+ *
+ * @since 3.0
+ */
+public class AbstractEventSupportTest extends TestCase {
+
+ /**
+ * The event support mock object that will be used for testing.
+ */
+ private AbstractEventSupport<ChangeListener> eventSupport;
+
+ /**
+ * Creates the implementation of {...@link AbstractEventSupport} that will
be
+ * used for testing.
+ */
+ public void setUp() throws Exception {
+ eventSupport = new AbstractEventSupportMock(this);
+ }
+
+ /**
+ * Tests that the
+ * {...@link AbstractEventSupport#addListener(java.util.EventListener)}
+ * properly registers a listener.
+ */
+ public void testAddListener() {
+ ChangeListener changeListener = new ChangeListenerMock();
+ eventSupport.addListener(changeListener);
+ assertTrue(eventSupport.iterator().hasNext());
+ assertEquals(changeListener, eventSupport.iterator().next());
+ }
+
+ /**
+ * Tests that the
+ * {...@link AbstractEventSupport#addListener(java.util.EventListener)}
+ * method performs no operation when provided the value of
+ * <code>null</code>.
+ */
+ public void testAddNullListener() {
+ eventSupport.addListener(null);
+ assertFalse(eventSupport.iterator().hasNext());
+ }
+
+ /**
+ * Tests that the
+ * {...@link AbstractEventSupport#removeListener(java.util.EventListener)}
+ * properly removes a previously registered listener.
+ */
+ public void testRemoveListener() {
+ ChangeListener changeListener = new ChangeListenerMock();
+ eventSupport.addListener(changeListener);
+ assertTrue(eventSupport.iterator().hasNext());
+ eventSupport.removeListener(changeListener);
+ assertFalse(eventSupport.iterator().hasNext());
+ }
+
+ /**
+ * Tests that the
+ * {...@link AbstractEventSupport#removeListener(java.util.EventListener)}
+ * method performs no operation when provided the value of
+ * <code>null</code>.
+ */
+ public void testRemoveNullListener() {
+ ChangeListener changeListener = new ChangeListenerMock();
+ eventSupport.addListener(changeListener);
+ assertTrue(eventSupport.iterator().hasNext());
+ eventSupport.removeListener(null);
+ assertTrue(eventSupport.iterator().hasNext());
+ }
+
+ /**
+ * Tests that the source registered with the event support is the one
+ * provided by {...@link AbstractEventSupport#getSource()}.
+ */
+ public void testGetSource() {
+ assertEquals(this, eventSupport.getSource());
+ }
+
+ /**
+ * Tests that the event support object returns an iterator of the
registered
+ * listeners.
+ */
+ public void testIterator() {
+ ChangeListener changeListener = new ChangeListenerMock();
+ eventSupport.addListener(changeListener);
+ assertNotNull(eventSupport.iterator());
+ assertTrue(eventSupport.iterator().hasNext());
+ }
+
+ /**
+ * <p>
+ * The AbstractEventSupportMock class provides a mock version of the
+ * {...@link AbstractEventSupport} class that can be used for testing since
+ * AbstractEventSupport is an abstract class.
+ * </p>
+ */
+ @SuppressWarnings("serial")
+ private class AbstractEventSupportMock extends
AbstractEventSupport<ChangeListener> {
+
+ /**
+ * Constructs a new AbstractEventSupportMock and associates it with the
+ * source of the events.
+ *
+ * @param source the source of the events.
+ */
+ public AbstractEventSupportMock(Object source) {
+ super(source);
+ }
+ }
+
+ /**
+ * <p>
+ * The ChangeListenerMock class provides a mock version of the
+ * {...@link ChangeListener} interface that can be used for testing.
+ * </p>
+ */
+ private class ChangeListenerMock implements ChangeListener {
+ public void stateChanged(ChangeEvent changeEvent) {
+ }
+ }
+}
Propchange:
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/event/AbstractEventSupportTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/event/ReflectiveEventSupportTest.java
URL:
http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/event/ReflectiveEventSupportTest.java?rev=965165&view=auto
==============================================================================
---
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/event/ReflectiveEventSupportTest.java
(added)
+++
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/event/ReflectiveEventSupportTest.java
Sun Jul 18 06:05:51 2010
@@ -0,0 +1,355 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.lang3.event;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import junit.framework.TestCase;
+
+/**
+ * <p>
+ * The ReflectiveEventSupportTest class provides a set of unit tests for the
+ * {...@link ReflectiveEventSupport} class.
+ * </p>
+ *
+ * @author <a href="mailto:[email protected]">Michael Wooten</a>
+ *
+ * @since 3.0
+ */
+public class ReflectiveEventSupportTest extends TestCase {
+
+ /**
+ * The event support mock object that will be used for testing.
+ */
+ private ReflectiveEventSupport<ChangeListener> eventSupport;
+
+ /**
+ * The first listener that will be registered for change events.
+ */
+ private ChangeDetectedChangeListener firstChangeListener;
+
+ /**
+ * The second listener that will be registered for change events.
+ */
+ private ChangeDetectedChangeListener secondChangeListener;
+
+ /**
+ * Creates the {...@link ReflectiveEventSupport} instance under test and
+ * registers a couple of {...@link ChangeDetectedChangeListener}s with the
+ * event support.
+ */
+ protected void setUp() throws Exception {
+ eventSupport = new ReflectiveEventSupport<ChangeListener>(this);
+ firstChangeListener = new ChangeDetectedChangeListener();
+ secondChangeListener = new ChangeDetectedChangeListener();
+ eventSupport.addListener(firstChangeListener);
+ eventSupport.addListener(secondChangeListener);
+ }
+
+ /**
+ * Tests the {...@link
ReflectiveEventSupport#ReflectiveEventSupport(Object)}
+ * constructor.
+ */
+ public void testReflectiveEventSupport() {
+ try
+ {
+ new ReflectiveEventSupport<ChangeListener>(null);
+ fail("ReflectiveEventSupport(null) did not throw an
IllegalArgumentException");
+ }
+ catch (NullPointerException iae)
+ {
+ // Success, the exception was properly thrown
+ }
+ }
+
+ /**
+ * Tests the
+ * {...@link ReflectiveEventSupport#fireEvent(String,
java.util.EventObject)}
+ * method to ensure that events will be propagated to accessible methods
+ * with the provided name.
+ *
+ * @throws NoSuchMethodException
+ * @throws IllegalAccessException
+ * @throws InvocationTargetException
+ */
+ public void testFireEventByMethodName() throws NoSuchMethodException,
+ IllegalAccessException, InvocationTargetException {
+ ChangeEvent changeEvent = new ChangeEvent(eventSupport.getSource());
+ eventSupport.fireEvent("stateChanged", changeEvent);
+ assertTrue("ChangeEvent not propogated to first change lisetener",
+ firstChangeListener.isChanged());
+ assertTrue("ChangeEvent not propogated to second change lisetener",
+ secondChangeListener.isChanged());
+ }
+
+ /**
+ * Tests the
+ * {...@link ReflectiveEventSupport#fireEvent(String,
java.util.EventObject)}
+ * method to ensure that a {...@link NoSuchMethodException} is thrown if
the
+ * method is not accessible.
+ *
+ * @throws IllegalAccessException
+ * @throws InvocationTargetException
+ */
+ public void testFireEventByMethodNameToInaccessibleMethods()
+ throws IllegalAccessException, InvocationTargetException {
+
+ ChangeEvent changeEvent = new ChangeEvent(eventSupport.getSource());
+
+ try
+ {
+ eventSupport.fireEvent("privateMethod", changeEvent);
+ fail("eventSupport.fireEvent() did not throw an exception " +
+ "for a private method");
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ // Success
+ }
+
+ try
+ {
+ eventSupport.fireEvent("protectedMethod", changeEvent);
+ fail("eventSupport.fireEvent() did not throw an exception " +
+ "for a protected method");
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ // Success
+ }
+
+ try
+ {
+ eventSupport.fireEvent("defaultMethod", changeEvent);
+ fail("eventSupport.fireEvent() did not throw an exception " +
+ "for a default method");
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ // Success
+ }
+ }
+
+ /**
+ * Tests the
+ * {...@link ReflectiveEventSupport#fireEvent(String,
java.util.EventObject)}
+ * method to ensure that a {...@link NullPointerException} is thrown if a
+ * <code>null</code> value is provided for the method name.
+ *
+ * @throws NoSuchMethodException
+ * @throws IllegalAccessException
+ * @throws InvocationTargetException
+ */
+ public void testFireEventNullMethodName() throws NoSuchMethodException,
+ IllegalAccessException,
+ InvocationTargetException {
+ try
+ {
+ ChangeEvent changeEvent = new
ChangeEvent(eventSupport.getSource());
+ eventSupport.fireEvent((String) null, changeEvent);
+ fail("eventSupport.fireEvent() did not throw an exception for a " +
+ "null method name.");
+ }
+ catch (NullPointerException npe)
+ {
+ // Success
+ }
+ }
+
+ /**
+ * Tests the
+ * {...@link ReflectiveEventSupport#fireEvent(Method,
java.util.EventObject)}
+ * method to ensure that events will be propagated to the accessible method
+ * provided.
+ *
+ * @throws NoSuchMethodException
+ * @throws IllegalAccessException
+ * @throws InvocationTargetException
+ */
+ public void testFireEventByMethod() throws NoSuchMethodException,
+ IllegalAccessException, InvocationTargetException {
+ ChangeEvent changeEvent = new ChangeEvent(eventSupport.getSource());
+ Method stateChangedMethod =
+ ChangeListener.class.getMethod("stateChanged", ChangeEvent.class);
+ eventSupport.fireEvent(stateChangedMethod, changeEvent);
+ assertTrue("ChangeEvent not propogated to first change lisetener",
+ firstChangeListener.isChanged());
+ assertTrue("ChangeEvent not propogated to second change lisetener",
+ secondChangeListener.isChanged());
+ }
+
+ /**
+ * Tests the
+ * {...@link ReflectiveEventSupport#fireEvent(Method,
java.util.EventObject)}
+ * method to ensure that a {...@link NoSuchMethodException} is thrown if
the
+ * method is not accessible.
+ *
+ * @throws IllegalAccessException
+ * @throws InvocationTargetException
+ */
+ public void testFireEventByMethodToInaccessibleMethods()
+ throws IllegalAccessException, InvocationTargetException {
+
+ ChangeEvent changeEvent = new ChangeEvent(eventSupport.getSource());
+
+ try
+ {
+ Method privateMethod =
+ ChangeListener.class.getMethod("privateMethod",
+ ChangeEvent.class);
+ eventSupport.fireEvent(privateMethod, changeEvent);
+ fail("eventSupport.fireEvent() did not throw an exception " +
+ "for a private method");
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ // Success
+ }
+
+ try
+ {
+ Method protectedMethod =
+ ChangeListener.class.getMethod("protectedMethod",
+ ChangeEvent.class);
+ eventSupport.fireEvent(protectedMethod, changeEvent);
+ fail("eventSupport.fireEvent() did not throw an exception " +
+ "for a protected method");
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ // Success
+ }
+
+ try
+ {
+ Method defaultMethod =
+ ChangeListener.class.getMethod("defaultMethod",
+ ChangeEvent.class);
+ eventSupport.fireEvent(defaultMethod, changeEvent);
+ fail("eventSupport.fireEvent() did not throw an exception " +
+ "for a default method");
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ // Success
+ }
+ }
+
+ /**
+ * Tests the
+ * {...@link ReflectiveEventSupport#fireEvent(Method,
java.util.EventObject)}
+ * method to ensure that a {...@link NullPointerException} is thrown if a
+ * <code>null</code> value is provided for the method.
+ *
+ * @throws NoSuchMethodException
+ * @throws IllegalAccessException
+ * @throws InvocationTargetException
+ */
+ public void testFireEventNullMethod() throws NoSuchMethodException,
+ IllegalAccessException, InvocationTargetException {
+ try
+ {
+ ChangeEvent changeEvent = new
ChangeEvent(eventSupport.getSource());
+ eventSupport.fireEvent((Method) null, changeEvent);
+ fail("eventSupport.fireEvent() did not throw an exception for a " +
+ "null method.");
+ }
+ catch (NullPointerException npe)
+ {
+ // Success
+ }
+ }
+
+ /**
+ * Tests the {...@link ReflectiveEventSupport#getSource()} method to
ensure it
+ * returns the source object it was originally provided.
+ */
+ public void testGetSource() {
+ assertEquals(this, eventSupport.getSource());
+ }
+
+ /**
+ * <p>
+ * The ChangeDetectedChangeListener class provides a version of the
+ * {...@link ChangeListener} interface that detects when the listener has
+ * been called. The class provides an {...@link #isChanged()} method that
+ * will indicate whether or not the listener has been called.
+ * </p>
+ */
+ public class ChangeDetectedChangeListener implements ChangeListener {
+
+ /**
+ * Represents whether or not the listener has detected a change.
+ */
+ private boolean changed = false;
+
+ /**
+ * Called whenever a change is detected.
+ *
+ * @param changeEvent the change event indicating a state change.
+ */
+ public void stateChanged(ChangeEvent changeEvent) {
+ this.changed = true;
+ }
+
+ /**
+ * Returns whether or not the listener has detected a change event.
+ *
+ * @return <code>true</code> if the listener has detected a change
+ * event, <code>false</code> otherwise.
+ */
+ public boolean isChanged() {
+ return this.changed;
+ }
+
+ /**
+ * A default (package private) method used to test
+ * ReflectiveEventSupport calls to inaccessible methods.
+ *
+ * @param changeEvent not used.
+ */
+ void defaultMethod(ChangeEvent changeEvent) {
+ this.changed = true;
+ }
+
+ /**
+ * A protected method used to test ReflectiveEventSupport calls to
+ * inaccessible methods.
+ *
+ * @param changeEvent not used.
+ */
+ protected void protectedMethod(ChangeEvent changeEvent) {
+ this.changed = true;
+ }
+
+ /**
+ * A private method used to test ReflectiveEventSupport calls to
+ * inaccessible methods.
+ *
+ * @param changeEvent not used.
+ */
+ @SuppressWarnings("unused")
+ private void privateMethod(ChangeEvent changeEvent) {
+ this.changed = true;
+ }
+ }
+}
Propchange:
commons/proper/lang/trunk/src/test/java/org/apache/commons/lang3/event/ReflectiveEventSupportTest.java
------------------------------------------------------------------------------
svn:eol-style = native