Removing ReflectiveEventSupport per author's suggestion.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/lang/trunk@966769 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
91a90af767
commit
4f2cfd7a78
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
* 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:mwooten.dev@gmail.com">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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,355 +0,0 @@
|
|||
/*
|
||||
* 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:mwooten.dev@gmail.com">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;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue