Notifier is a class which makes handling an event-listener queue a lot easier.

It throws the exception when the notify fails.


git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/lang/trunk@137121 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Henri Yandell 2002-11-12 03:01:05 +00:00
parent 864c478a4d
commit dfac194424
2 changed files with 293 additions and 0 deletions

View File

@ -0,0 +1,186 @@
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, 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 acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", 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 apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names 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 (INCLUDING, 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.commons.lang;
import java.util.ArrayList;
import java.util.EventObject;
import java.util.Iterator;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
/**
* A utility which takes much of the pain out of the Event/Listener
* system. It handles the collection, and the loop-notification.
* Reflection is used for the actual notification call.
*
* Alternate strategies are usable. For example this class currently
* does not enforce a particular interface, which means it cannot
* cache that method. Doing this probably makes a lot of sense.
*/
public class Notifier {
private ArrayList listeners = new ArrayList();
private Method listenerMethod;
private String methodName;
private Class clss;
public Notifier() {
}
public Notifier(Class listener) {
this.clss = clss;
// now we check methods, if only one of them, then
// let's set it
Method[] meths = clss.getDeclaredMethods();
if(meths.length == 0) {
this.listenerMethod = meths[0];
}
}
/**
* Set the name of the method to call upon the listeners.
*/
public void setListenerMethod(String name) {
this.methodName = name;
if(this.clss != null) {
try {
// then we get the Method object
this.listenerMethod = this.clss.getDeclaredMethod(name, new Class[] { EventObject.class} );
} catch(NoSuchMethodException nsme) {
// nsme.printStackTrace();
throw new IllegalArgumentException("Method not on Class. ");
}
}
}
public void addListener(Object not) {
this.listeners.add(not);
}
public void removeListener(Object not) {
this.listeners.remove(not);
}
public ArrayList getListeners() {
ArrayList cloned = new ArrayList();
cloned.addAll(listeners);
return cloned;
}
/**
* Convenience method for when a listener has a single method.
* Currently this method needs to be called, but it's possible
* that by providing the interface class, it can be assumed as
* to what the listening method is.
*/
public void notify(EventObject event) throws NotifierException {
if(this.clss == null) {
notify(this.methodName, event);
} else {
notify(this.listenerMethod, event);
}
}
/**
* Notify the listeners of a certain event, to a certain method.
* This is usable when a Listener has more than one method and
* a single Notifier wants to be shared.
*/
public void notify(Method listenerMethod, EventObject event) throws NotifierException {
Iterator itr = getListeners().iterator();
while(itr.hasNext()) {
try {
Object listener = itr.next();
listenerMethod.invoke( listener, new Object[] { event } );
} catch(SecurityException se) {
throw new NotifierException(se);
} catch(IllegalAccessException iae) {
throw new NotifierException(iae);
} catch(IllegalArgumentException iae) {
throw new NotifierException(iae);
} catch(InvocationTargetException ite) {
throw new NotifierException(ite);
}
}
}
/**
* Notify the listeners of a certain event, to a certain method.
* This is usable when a Listener has more than one method and
* a single Notifier wants to be shared.
*/
public void notify(String methodName, EventObject event) throws NotifierException {
Iterator itr = getListeners().iterator();
while(itr.hasNext()) {
try {
Object listener = itr.next();
Class clss = listener.getClass();
Method method = clss.getMethod(methodName, new Class[] { event.getClass() } );
method.invoke( listener, new Object[] { event } );
} catch(SecurityException se) {
throw new NotifierException(se);
} catch(NoSuchMethodException nsme) {
throw new NotifierException(nsme);
} catch(IllegalAccessException iae) {
throw new NotifierException(iae);
} catch(IllegalArgumentException iae) {
throw new NotifierException(iae);
} catch(InvocationTargetException ite) {
throw new NotifierException(ite);
}
}
}
}

View File

@ -0,0 +1,107 @@
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, 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 acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", 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 apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names 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 (INCLUDING, 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.commons.lang;
import org.apache.commons.lang.exception.NestableException;
/**
* Exception thrown when something goes wrong in notifying.
*
* @author <a href="mailto:bayard@apache.org">Henri Yandell</a>
* @version $Id: NotifierException.java,v 1.1 2002/11/12 03:01:05 bayard Exp $
*/
public class NotifierException extends NestableException {
/**
* Constructs a new <code>NotifierException</code> without specified
* detail message.
*/
public NotifierException() {
super();
}
/**
* Constructs a new <code>NotifierException</code> with specified
* detail message.
*
* @param msg the error message.
*/
public NotifierException(String msg) {
super(msg);
}
/**
* Constructs a new <code>NotifierException</code> with specified
* nested <code>Throwable</code> root cause.
*
* @param rootCause the exception or error that caused this exception
* to be thrown.
*/
public NotifierException(Throwable rootCause) {
super(rootCause);
}
/**
* Constructs a new <code>NotifierException</code> with specified
* detail message and nested <code>Throwable</code> root cause.
*
* @param msg the error message.
* @param rootCause the exception or error that caused this exception
* to be thrown.
*/
public NotifierException(String msg, Throwable rootCause) {
super(msg, rootCause);
}
}