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 }