Clover coverage report - picocontainer - 1.2-beta-1
Coverage timestamp: Sun May 29 2005 14:29:04 BST
file stats: LOC: 143   Methods: 8
NCLOC: 70   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
InstantiatingComponentAdapter.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.defaults;
 11   
 12    import org.picocontainer.Parameter;
 13    import org.picocontainer.PicoContainer;
 14    import org.picocontainer.PicoIntrospectionException;
 15    import org.picocontainer.PicoVisitor;
 16   
 17    import java.lang.reflect.Constructor;
 18    import java.lang.reflect.InvocationTargetException;
 19    import java.lang.reflect.Modifier;
 20   
 21    /**
 22    * This ComponentAdapter will instantiate a new object for each call to
 23    * {@link org.picocontainer.ComponentAdapter#getComponentInstance(PicoContainer)}.
 24    * That means that when used with a PicoContainer, getComponentInstance will
 25    * return a new object each time.
 26    *
 27    * @author Aslak Hellesøy
 28    * @author Paul Hammant
 29    * @author Jörg Schaible
 30    * @version $Revision: 1820 $
 31    * @since 1.0
 32    */
 33    public abstract class InstantiatingComponentAdapter extends AbstractComponentAdapter {
 34    /** The cycle guard for the verification. */
 35    protected transient Guard verifyingGuard;
 36    /** The parameters to use for initialization. */
 37    protected transient Parameter[] parameters;
 38    /** Flag indicating instanciation of non-public classes. */
 39    protected boolean allowNonPublicClasses;
 40   
 41    protected static abstract class Guard extends ThreadLocalCyclicDependencyGuard {
 42    protected PicoContainer guardedContainer;
 43  124 protected void setArguments(PicoContainer container) {
 44  124 this.guardedContainer = container;
 45    }
 46    }
 47   
 48    /**
 49    * Constructs a new ComponentAdapter for the given key and implementation.
 50    * @param componentKey the search key for this implementation
 51    * @param componentImplementation the concrete implementation
 52    * @param parameters the parameters to use for the initialization
 53    * @param allowNonPublicClasses flag to allow instantiation of non-public classes.
 54    * @throws AssignabilityRegistrationException if the key is a type and the implementation cannot be assigned to.
 55    * @throws NotConcreteRegistrationException if the implementation is not a concrete class.
 56    */
 57  1208 protected InstantiatingComponentAdapter(Object componentKey, Class componentImplementation, Parameter[] parameters, boolean allowNonPublicClasses) {
 58  1208 super(componentKey, componentImplementation);
 59  1208 checkConcrete();
 60   
 61  1204 this.parameters = parameters;
 62  1204 this.allowNonPublicClasses = allowNonPublicClasses;
 63    }
 64   
 65  1208 private void checkConcrete() throws NotConcreteRegistrationException {
 66    // Assert that the component class is concrete.
 67  1208 boolean isAbstract = (getComponentImplementation().getModifiers() & Modifier.ABSTRACT) == Modifier.ABSTRACT;
 68  1208 if (getComponentImplementation().isInterface() || isAbstract) {
 69  4 throw new NotConcreteRegistrationException(getComponentImplementation());
 70    }
 71    }
 72   
 73    /**
 74    * Create default parameters for the given types.
 75    *
 76    * @param parameters the parameter types
 77    * @return the array with the default parameters.
 78    */
 79  2688 protected Parameter[] createDefaultParameters(Class[] parameters) {
 80  2688 Parameter[] componentParameters = new Parameter[parameters.length];
 81  2688 for (int i = 0; i < parameters.length; i++) {
 82  2866 componentParameters[i] = ComponentParameter.DEFAULT;
 83    }
 84  2688 return componentParameters;
 85    }
 86   
 87  64 public void verify(final PicoContainer container) throws PicoIntrospectionException {
 88  64 if (verifyingGuard == null) {
 89  54 verifyingGuard = new Guard() {
 90  62 public Object run() {
 91  62 final Constructor constructor = getGreediestSatisfiableConstructor(guardedContainer);
 92  34 final Class[] parameterTypes = constructor.getParameterTypes();
 93  34 final Parameter[] currentParameters = parameters != null ? parameters : createDefaultParameters(parameterTypes);
 94  34 for (int i = 0; i < currentParameters.length; i++) {
 95  14 currentParameters[i].verify(container, InstantiatingComponentAdapter.this, parameterTypes[i]);
 96    }
 97  30 return null;
 98    }
 99    };
 100    }
 101  64 verifyingGuard.setArguments(container);
 102  64 verifyingGuard.observe(getComponentImplementation());
 103    }
 104   
 105  178 public void accept(PicoVisitor visitor) {
 106  178 super.accept(visitor);
 107  178 if (parameters != null) {
 108  34 for (int i = 0; i < parameters.length; i++) {
 109  50 parameters[i].accept(visitor);
 110    }
 111    }
 112    }
 113   
 114    /**
 115    * Instantiate an object with given parameters and respect the accessible flag.
 116    *
 117    * @param constructor the constructor to use
 118    * @param parameters the parameters for the constructor
 119    * @return the new object.
 120    * @throws InstantiationException
 121    * @throws IllegalAccessException
 122    * @throws InvocationTargetException
 123    */
 124  906 protected Object newInstance(Constructor constructor, Object[] parameters) throws InstantiationException, IllegalAccessException, InvocationTargetException {
 125  906 if (allowNonPublicClasses) {
 126  24 constructor.setAccessible(true);
 127    }
 128  906 return constructor.newInstance(parameters);
 129    }
 130   
 131    /**
 132    * Find and return the greediest satisfiable constructor.
 133    *
 134    * @param container the PicoContainer to resolve dependencies.
 135    * @return the found constructor.
 136    * @throws PicoIntrospectionException
 137    * @throws UnsatisfiableDependenciesException
 138    * @throws AmbiguousComponentResolutionException
 139    * @throws AssignabilityRegistrationException
 140    * @throws NotConcreteRegistrationException
 141    */
 142    protected abstract Constructor getGreediestSatisfiableConstructor(PicoContainer container) throws PicoIntrospectionException, UnsatisfiableDependenciesException, AmbiguousComponentResolutionException, AssignabilityRegistrationException, NotConcreteRegistrationException;
 143    }