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 }