001    package org.shiftone.jrat.util;
002    
003    
004    import org.shiftone.jrat.core.JRatException;
005    import org.shiftone.jrat.util.log.Logger;
006    
007    import java.lang.reflect.InvocationHandler;
008    import java.lang.reflect.Method;
009    import java.lang.reflect.Proxy;
010    import java.util.ArrayList;
011    import java.util.List;
012    
013    
014    /**
015     * @author jeff@shiftone.org (Jeff Drost)
016     */
017    public class CompositeInvocationHandler implements InvocationHandler {
018    
019        private static final Logger LOG = Logger.getLogger(CompositeInvocationHandler.class);
020        private final Class iface;
021        private final List targets = new ArrayList();
022        private final Object proxy;
023    
024        public CompositeInvocationHandler(Class iface) {
025            this.iface = iface;
026            this.proxy = Proxy.newProxyInstance(iface.getClassLoader(), new Class[]{iface}, this);
027        }
028    
029    
030        public synchronized int getTargetCount() {
031            return targets.size();
032        }
033    
034    
035        public synchronized void addTarget(Object target) {
036    
037            if (iface.isAssignableFrom(target.getClass())) {
038                targets.add(target);
039            } else {
040                throw new JRatException("unable to add target of type " + target.getClass());
041            }
042        }
043    
044    
045        public synchronized Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
046    
047            for (int i = 0; i < targets.size(); i++) {
048                LOG.debug("invoke " + method.getName() + " " + (i + 1) + " of " + targets.size());
049    
050                Object target = targets.get(i);
051    
052                try {
053                    method.invoke(target, args);
054                }
055                catch (Throwable e) {
056                    LOG.error("error running method " + method.getName() + " on " + target, e);
057                }
058            }
059    
060            return null;
061        }
062    
063    
064        public Object getProxy() {
065            return proxy;
066        }
067    }