1 10 package org.picocontainer.defaults; 11 12 import java.lang.reflect.InvocationHandler ; 13 import java.lang.reflect.InvocationTargetException ; 14 import java.lang.reflect.Method ; 15 import java.lang.reflect.Proxy ; 16 17 import org.picocontainer.ComponentAdapter; 18 import org.picocontainer.ComponentMonitor; 19 import org.picocontainer.PicoContainer; 20 import org.picocontainer.PicoInitializationException; 21 import org.picocontainer.PicoIntrospectionException; 22 23 35 public class ImplementationHidingComponentAdapter extends DecoratingComponentAdapter { 36 private final boolean strict; 37 38 43 public ImplementationHidingComponentAdapter(ComponentAdapter delegate, boolean strict) { 44 super(delegate); 45 this.strict = strict; 46 } 47 48 public Object getComponentInstance(final PicoContainer container) 49 throws PicoInitializationException, PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException { 50 51 Object componentKey = getDelegate().getComponentKey(); 52 Class [] classes = null; 53 if (componentKey instanceof Class && ((Class ) getDelegate().getComponentKey()).isInterface()) { 54 classes = new Class []{(Class ) getDelegate().getComponentKey()}; 55 } else if (componentKey instanceof Class []) { 56 classes = (Class []) componentKey; 57 } else { 58 if(strict) { 59 throw new PicoIntrospectionException("In strict mode, " + getClass().getName() + " only allows components registered with interface keys (java.lang.Class or java.lang.Class[])"); 60 } 61 return getDelegate().getComponentInstance(container); 62 } 63 64 Class [] interfaces = verifyInterfacesOnly(classes); 65 return createProxy(interfaces, container, getDelegate().getComponentImplementation().getClassLoader()); 66 } 67 68 private Object createProxy(Class [] interfaces, final PicoContainer container, final ClassLoader classLoader) { 69 return Proxy.newProxyInstance(classLoader, 70 interfaces, new InvocationHandler () { 71 public Object invoke(final Object proxy, final Method method, 72 final Object [] args) 73 throws Throwable { 74 Object componentInstance = getDelegate().getComponentInstance(container); 75 ComponentMonitor componentMonitor = currentMonitor(); 76 try { 77 componentMonitor.invoking(method, componentInstance); 78 long startTime = System.currentTimeMillis(); 79 Object object = method.invoke(componentInstance, args); 80 componentMonitor.invoked(method, componentInstance, System.currentTimeMillis() - startTime); 81 return object; 82 } catch (final InvocationTargetException ite) { 83 componentMonitor.invocationFailed(method, componentInstance, ite); 84 throw ite.getTargetException(); 85 } 86 } 87 }); 88 } 89 90 private Class [] verifyInterfacesOnly(Class [] classes) { 91 for (int i = 0; i < classes.length; i++) { 92 if(!classes[i].isInterface()) { 93 throw new PicoIntrospectionException("Class keys must be interfaces. " + classes[i] + " is not an interface."); 94 } 95 } 96 return classes; 97 } 98 99 } 100 | Popular Tags |