avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Leo Sutic" <leo.su...@inspireinfrastructure.com>
Subject RE: Wanting delegates
Date Thu, 03 Oct 2002 08:46:14 GMT
Berin,

this is what I want:



import java.lang.reflect.*;
import java.util.*;

/**
 * Interface for events. See the Button class below for example of use.
 */
interface Event {
    public void register (Object o);
    public void deregister (Object o);
}

/**
 * Creates events (multicast delegates)
 */
class EventFactory {
    
    static class EventHandler implements InvocationHandler {
        
        private ArrayList handlers = new ArrayList ();
        private Method registerMethod;
        private Method deregisterMethod;
                
        public EventHandler () {
            try {
                registerMethod = Event.class.getDeclaredMethod
("register", new Class[] { Object.class });
                deregisterMethod = Event.class.getDeclaredMethod
("deregister", new Class[] { Object.class });
            } catch (Exception e) {
                // If this happens we've had a severe error somewhere.
                throw new Error (e.toString ());
            }
        }
        
        public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable  {
            System.out.println ("EventHandler invocation: " +
method.getName ());
            if (method.equals (registerMethod)) {
                handlers.add (args[0]);
                return null;
            } else if (method.equals (deregisterMethod)) {
                handlers.remove (args[0]);
                return null;
            } else {
                Iterator iter = handlers.iterator ();
                while (iter.hasNext ()) {
                    method.invoke (iter.next (), args);
                }
                
                // As events are multicast, the only allowed return
value is void.
                
                return null;
            }
        }
    }
    
    public static Event newEvent (Class delegateInterface) {
        return (Event) Proxy.newProxyInstance
(delegateInterface.getClassLoader (),
            new Class[]{ Event.class, delegateInterface }, new
EventHandler () );
    }
    
}

/**
 * Creates delegates.
 */
class DelegateFactory {
    
    static class DelegateHandler implements InvocationHandler {
        
        private final Object instance;
        private final Method delegateMethod;
        
        public DelegateHandler (Object instance, String methodName) {
            this.instance = instance;
            
            // Right now we only test on method name.
            // This could be extended to test on delegate 
            // method signature.
            
            Class instanceClass = instance.getClass ();
            Method[] methods = instanceClass.getDeclaredMethods ();
            Method method = null;
            for (int i = 0; i < methods.length; i++) {
                if (methods[i].getName ().equals (methodName)) {
                    method = methods[i];
                }
            }
            this.delegateMethod = method;
        }
                
        public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable {
            return delegateMethod.invoke (instance, args);
        }
    }
    
    public static Object newDelegate (Object instance, String
methodName, Class delegateInterface) {
        return Proxy.newProxyInstance (delegateInterface.getClassLoader
(),
            new Class[]{ delegateInterface }, new DelegateHandler
(instance, methodName) );
    }
    
}

// -------------------- Test Code

class Button {
    
    interface Delegate {
        public String action ();
    }
    
    public Event multicast = EventFactory.newEvent (Delegate.class);
    public Delegate unicast = null;
    
    public void fireMulticast () {
        ((Delegate) multicast).action ();
    }
    
    public void fireUnicast () {
        String result = ((Delegate) unicast).action ();
        System.out.println ("Result from unicast is " + result);
    }
}

public class Hack {
    
    public String myFirstEventHandler () {
        System.out.println ("In myFirstEventHandler.");
        return "myFirstEventHandler";
    }
    
    public String mySecondEventHandler () {
        System.out.println ("In mySecondEventHandler.");
        return "mySecondEventHandler";
    }
    
    public String myDelegate () {
        System.out.println ("In myDelegate.");
        return "delegate";
    }
    
    public void run () {
        Button button = new Button ();
        
        button.multicast.register (DelegateFactory.newDelegate (this,
"myFirstEventHandler", Button.Delegate.class));
        button.multicast.register (DelegateFactory.newDelegate (this,
"mySecondEventHandler", Button.Delegate.class));
        
        button.unicast = (Button.Delegate) DelegateFactory.newDelegate
(this, "myDelegate", Button.Delegate.class);
        
        button.fireMulticast ();
        button.fireUnicast ();
    }
    
    public static void main (String[] args) {
        new Hack ().run ();
    }
}
 


--
To unsubscribe, e-mail:   <mailto:avalon-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-dev-help@jakarta.apache.org>


Mime
View raw message