Clover coverage report - picocontainer - 1.2-beta-1
Coverage timestamp: Sun May 29 2005 14:29:04 BST
file stats: LOC: 129   Methods: 5
NCLOC: 59   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ImplementationHidingComponentAdapter.java 100% 100% 100% 100%
coverage
 1    /*****************************************************************************
 2    * Copyright (C) PicoContainer Organization. All rights reserved. *
 3    * ------------------------------------------------------------------------- *
 4    * The software in this package is published under the terms of the BSD *
 5    * style license a copy of which has been included with this distribution in *
 6    * the LICENSE.txt file. *
 7    * *
 8    * Original code by *
 9    *****************************************************************************/
 10    package org.picocontainer.alternatives;
 11   
 12    import org.picocontainer.ComponentAdapter;
 13    import org.picocontainer.PicoContainer;
 14    import org.picocontainer.PicoInitializationException;
 15    import org.picocontainer.PicoIntrospectionException;
 16    import org.picocontainer.defaults.AssignabilityRegistrationException;
 17    import org.picocontainer.defaults.DecoratingComponentAdapter;
 18    import org.picocontainer.defaults.NotConcreteRegistrationException;
 19   
 20    import java.lang.reflect.InvocationHandler;
 21    import java.lang.reflect.InvocationTargetException;
 22    import java.lang.reflect.Method;
 23    import java.lang.reflect.Proxy;
 24   
 25    /**
 26    * This component adapter makes it possible to hide the implementation
 27    * of a real subject (behind a proxy) provided the key is an interface.
 28    * <p/>
 29    * This class exists here, because a) it has no deps on external jars, b) dynamic proxy is quite easy.
 30    * The user is prompted to look at nanocontainer-proxytoys for alternate and bigger implementations.
 31    *
 32    * @author Aslak Helles&oslash;y
 33    * @author Paul Hammant
 34    * @version $Revision: 1882 $
 35    * @see org.nanocontainer.proxytoys.HotSwappingComponentAdapter for a more feature-rich version of this class.
 36    * @see org.nanocontainer.proxytoys.HotSwappingComponentAdapterFactory
 37    * @since 1.1
 38    */
 39    public class ImplementationHidingComponentAdapter extends DecoratingComponentAdapter {
 40    private final boolean strict;
 41   
 42  112 public ImplementationHidingComponentAdapter(ComponentAdapter delegate, boolean strict) {
 43  112 super(delegate);
 44  112 this.strict = strict;
 45    }
 46   
 47  98 public Object getComponentInstance(final PicoContainer container)
 48    throws PicoInitializationException, PicoIntrospectionException, AssignabilityRegistrationException, NotConcreteRegistrationException {
 49   
 50  98 Object componentKey = getDelegate().getComponentKey();
 51  98 Class[] classes = null;
 52  98 if (componentKey instanceof Class && ((Class) getDelegate().getComponentKey()).isInterface()) {
 53  54 classes = new Class[]{(Class) getDelegate().getComponentKey()};
 54  44 } else if (componentKey instanceof Class[]) {
 55  4 classes = (Class[]) componentKey;
 56    } else {
 57  40 if(strict) {
 58  2 throw new PicoIntrospectionException("In strict mode, " + getClass().getName() + " only allows components registered with interface keys (java.lang.Class or java.lang.Class[])");
 59    }
 60  38 return getDelegate().getComponentInstance(container);
 61    }
 62   
 63  58 Class[] interfaces = verifyInterfacesOnly(classes);
 64  56 return createProxy(interfaces, container);
 65    }
 66   
 67  56 private Object createProxy(Class[] interfaces, final PicoContainer container) {
 68  56 return Proxy.newProxyInstance(getClass().getClassLoader(),
 69    interfaces, new InvocationHandler() {
 70  24 public Object invoke(final Object proxy, final Method method,
 71    final Object[] args)
 72    throws Throwable {
 73  24 try {
 74  24 Object componentInstance = getDelegate().getComponentInstance(container);
 75  24 return method.invoke(componentInstance, args);
 76    } catch (final InvocationTargetException ite) {
 77  6 throw ite.getTargetException();
 78    }
 79    }
 80    });
 81    }
 82   
 83  58 private Class[] verifyInterfacesOnly(Class[] classes) {
 84  58 for (int i = 0; i < classes.length; i++) {
 85  60 if(!classes[i].isInterface()) {
 86  2 throw new PicoIntrospectionException("Class keys must be interfaces. " + classes[i] + " is not an interface.");
 87    }
 88    }
 89  56 return classes;
 90    }
 91   
 92    // These two methods are copied from ProxyToys' ClassHierarchyIntrospector
 93    // TODO: Why? These two are currently not called in the complete Pico/Nano/Micro codebase ...
 94    // they just decrease coverage significantly ...
 95    /* *
 96    * Get all interfaces of the given type.
 97    * If the type is a class, the returned list contains any interface, that is
 98    * implemented by the class. If the type is an interface, the all
 99    * superinterfaces and the interface itself are included.
 100    *
 101    * @param clazz type to explore.
 102    * @return an array with all interfaces. The array may be empty.
 103    */
 104    /*
 105    public static Class[] getAllInterfaces(Class clazz) {
 106    Set interfaces = new HashSet();
 107    getInterfaces(clazz, interfaces);
 108    return (Class[]) interfaces.toArray(new Class[interfaces.size()]);
 109    }
 110   
 111    private static void getInterfaces(Class clazz, Set interfaces) {
 112    if (clazz.isInterface()) {
 113    interfaces.add(clazz);
 114    }
 115    // Class.getInterfaces will return only the interfaces that are
 116    // implemented by the current class. Therefore we must loop up
 117    // the hierarchy for the superclasses and the superinterfaces.
 118    while (clazz != null) {
 119    Class[] implemented = clazz.getInterfaces();
 120    for (int i = 0; i < implemented.length; i++) {
 121    if (!interfaces.contains(implemented[i])) {
 122    getInterfaces(implemented[i], interfaces);
 123    }
 124    }
 125    clazz = clazz.getSuperclass();
 126    }
 127    }
 128    */
 129    }