1 10 package org.picocontainer.gems.adapters; 11 12 import com.thoughtworks.proxy.Invoker; 13 import com.thoughtworks.proxy.ProxyFactory; 14 import com.thoughtworks.proxy.factory.StandardProxyFactory; 15 import com.thoughtworks.proxy.kit.ReflectionUtils; 16 17 import org.picocontainer.ComponentAdapter; 18 import org.picocontainer.PicoContainer; 19 import org.picocontainer.PicoInitializationException; 20 import org.picocontainer.PicoIntrospectionException; 21 import org.picocontainer.defaults.AssignabilityRegistrationException; 22 import org.picocontainer.defaults.CachingComponentAdapter; 23 import org.picocontainer.defaults.DecoratingComponentAdapter; 24 import org.picocontainer.defaults.NotConcreteRegistrationException; 25 26 import java.lang.reflect.InvocationTargetException ; 27 import java.lang.reflect.Method ; 28 import java.lang.reflect.Proxy ; 29 import java.util.Set ; 30 31 32 46 public class ThreadLocalComponentAdapter extends DecoratingComponentAdapter { 47 48 private transient Class [] interfaces; 49 private ProxyFactory proxyFactory; 50 51 58 public ThreadLocalComponentAdapter(final ComponentAdapter delegate, final ProxyFactory proxyFactory) 59 throws PicoIntrospectionException { 60 super(new CachingComponentAdapter(delegate, new ThreadLocalReference())); 61 this.proxyFactory = proxyFactory; 62 interfaces = getInterfaces(); 63 } 64 65 71 public ThreadLocalComponentAdapter(final ComponentAdapter delegate) throws PicoIntrospectionException { 72 this(new CachingComponentAdapter(delegate, new ThreadLocalReference()), new StandardProxyFactory()); 73 } 74 75 public Object getComponentInstance(final PicoContainer pico) 76 throws PicoInitializationException, PicoIntrospectionException, AssignabilityRegistrationException, 77 NotConcreteRegistrationException { 78 79 if (interfaces == null) { 80 interfaces = getInterfaces(); 81 } 82 83 final ComponentAdapter delegate = getDelegate(); 84 final Invoker invoker = new ThreadLocalInvoker(pico, delegate); 85 return proxyFactory.createProxy(interfaces, invoker); 86 } 87 88 final private Class [] getInterfaces() { 89 final Object componentKey = getComponentKey(); 90 final Class [] interfaces; 91 if (componentKey instanceof Class && ((Class )componentKey).isInterface()) { 92 interfaces = new Class []{(Class )componentKey}; 93 } else { 94 final Set allInterfaces = ReflectionUtils.getAllInterfaces(getComponentImplementation()); 95 interfaces = (Class [])allInterfaces.toArray(new Class [allInterfaces.size()]); 96 } 97 if (interfaces.length == 0) { 98 throw new PicoIntrospectionException("Can't proxy implementation for " 99 + getComponentImplementation().getName() 100 + ". It does not implement any interfaces."); 101 } 102 return interfaces; 103 } 104 105 final static private class ThreadLocalInvoker implements Invoker { 106 107 private final PicoContainer pico; 108 private final ComponentAdapter delegate; 109 110 private ThreadLocalInvoker(final PicoContainer pico, final ComponentAdapter delegate) { 111 this.pico = pico; 112 this.delegate = delegate; 113 } 114 115 public Object invoke(final Object proxy, final Method method, final Object [] args) throws Throwable { 116 final Object delegatedInstance = delegate.getComponentInstance(pico); 117 if (method.equals(ReflectionUtils.equals)) { return new Boolean (args[0] != null && args[0].equals(delegatedInstance)); 119 } else { 120 try { 121 return method.invoke(delegatedInstance, args); 122 } catch (final InvocationTargetException e) { 123 throw e.getTargetException(); 124 } 125 } 126 } 127 } 128 } | Popular Tags |