*
*/
package callback;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* This is a callback controller
* @author daniel zhou
*
*/
public class CallbackDispatcher {
private Map _ifaceToHandler =new HashMap();
private static class CallbackHandler implements InvocationHandler{
private Set _listeners = new HashSet();
private CallbackType _type;
public CallbackHandler(CallbackType type){
_type=type;
}
private void addListener(Object o){
synchronized (_listeners) {
_listeners.add(o);
}
}
private void removeListener(Object o) {
synchronized (_listeners) {
_listeners.remove(o);
}
}
public Object invoke(Object proxy, Method meth, Object[] methArgs) throws Throwable{
Set listeners;
synchronized(_listeners){
listeners = new HashSet(_listeners);
}
return _type.callListeners(meth, methArgs, listeners);
}
}
/**
* register an listener
* @param iFace
* @param o
*/
public void registerListener(Class iFace, Object o){
CallbackHandler handler;
//check registered or not
if (!iFace.isAssignableFrom(o.getClass())) {
throw new IllegalArgumentException("Object [" + o + "] does not " +
"implement [" + iFace.getName() +
"]");
}
//try to get the callbackhandler
synchronized(_ifaceToHandler){
handler = (CallbackHandler) _ifaceToHandler.get(iFace);
}
//not register and warn
if (handler==null) {
throw new IllegalArgumentException("No callback for interface [" +
iFace.getName() + "] exists");
}
//register
handler.addListener(o);
}
/**
* unregister
* @param iFace
* @param o
*/
public void unregisterListener(Class iFace, Object o){
CallbackHandler handler;
//get the callback handler
synchronized(_ifaceToHandler){
handler = (CallbackHandler) _ifaceToHandler.get(iFace);
}
//unregister
if (handler!=null) {
handler.removeListener(o);
}
}
/**
* Generates a caller with the callback type of
* {@link CallbackType.RETURN_LAST}
*
* @see #generateCaller(Class, CallbackType)
*/
public Object generateCaller(Class iFace) {
return generateCaller(iFace, CallbackType.RETURN_LAST);
}
/**
* Generates the 'caller' side of the caller/listener relationship.
*
* When methods on the returned object are invoked, the listeners
* registered via {@link #registerListener(Class, Object)} for the given
* interface will be executed.
*
* The execution of the callbacks, the order they are called, the
* exception handling, values returned etc. are all handled by the passed
* {@link CallbackType}.
*
* @param iFace Interface to generate the caller for
* @param type Type specifying the way that the caller will process
* callbacks
*
* @return An object implementing the passed interface. The methods on
* this object will execute callbacks on registered listeners.
*/
public Object generateCaller(Class iFace, CallbackType type) {
CallbackHandler newHandler;
Object src;
if (!iFace.isInterface()) {
throw new IllegalArgumentException("Class [" + iFace.getName() +
"] is not an interface");
}
newHandler = new CallbackHandler(type);
src = Proxy.newProxyInstance(iFace.getClassLoader(),
new Class[] { iFace }, newHandler);
synchronized(_ifaceToHandler) {
if (_ifaceToHandler.containsKey(iFace)) {
throw new IllegalArgumentException("Caller already generated " +
" for interface [" +
iFace.getName() + "]");
}
_ifaceToHandler.put(iFace, newHandler);
}
return src;
}
}
*
*/
package schedular;
import callback.CallbackDispatcher;
/**
* @author daniel zhou
*
*/
public class Schedulaer_Test {
/**
* @param args
*/
public static void main(String[] args) {
//callbacks handler
CallbackDispatcher _callbacks = new CallbackDispatcher();
//caller handler
ShutdownCallback _caller = (ShutdownCallback) _callbacks.generateCaller(ShutdownCallback.class);
//new implement
ShutdownCallback _shutdown = new ShutdownCallback(){
@Override
public void shutdown() {
System.out.println("I have been called!");
}
};
//register
_callbacks.registerListener(ShutdownCallback.class, _shutdown);
//call
_caller.shutdown();
}
}