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