Clover coverage report - Ledge Container - SNAPSHOT
Coverage timestamp: Fri Nov 17 2006 05:16:03 CET
file stats: LOC: 217   Methods: 8
NCLOC: 143   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
SequenceParameter.java 75% 68.8% 75% 70.8%
coverage coverage
 1    //
 2    // Copyright (c) 2003, Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
 3    // All rights reserved.
 4    //
 5    // Redistribution and use in source and binary forms, with or without modification,
 6    // are permitted provided that the following conditions are met:
 7    //
 8    // * Redistributions of source code must retain the above copyright notice,
 9    // this list of conditions and the following disclaimer.
 10    // * Redistributions in binary form must reproduce the above copyright notice,
 11    // this list of conditions and the following disclaimer in the documentation
 12    // and/or other materials provided with the distribution.
 13    // * Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
 14    // nor the names of its contributors may be used to endorse or promote products
 15    // derived from this software without specific prior written permission.
 16    //
 17    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 18    // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 19    // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 20    // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 21    // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 22    // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 23    // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 24    // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 25    // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 26    // POSSIBILITY OF SUCH DAMAGE.
 27    //
 28   
 29    package org.objectledge.pico;
 30   
 31    import java.lang.reflect.Array;
 32    import java.lang.reflect.Constructor;
 33    import java.util.Arrays;
 34    import java.util.Collection;
 35   
 36    import org.picocontainer.ComponentAdapter;
 37    import org.picocontainer.Parameter;
 38    import org.picocontainer.PicoContainer;
 39    import org.picocontainer.PicoException;
 40    import org.picocontainer.PicoInitializationException;
 41    import org.picocontainer.PicoIntrospectionException;
 42    import org.picocontainer.PicoVisitor;
 43   
 44    /**
 45    * Allows hinting the component's constructor arguments of aggregated types.
 46    *
 47    * <p>
 48    * Both Java arrays and <code>java.util.Collection</code> objects are supported.
 49    * The elements of the sequence are <code>org.picocontainer.Parameter</code> objects
 50    * - they may resolve to constants, component references, or nested sequences.
 51    * </p>
 52    *
 53    * @author <a href="Rafal.Krzewski">rafal@caltha.pl</a>
 54    * @version $Id: SequenceParameter.java,v 1.6 2005/07/07 08:30:04 zwierzem Exp $
 55    */
 56    public class SequenceParameter implements Parameter
 57    {
 58    private Parameter[] elements;
 59    private Class implClass;
 60   
 61    /**
 62    * Creates a sequence parameter.
 63    *
 64    * @param elements the sequence elements.
 65    * @param implClass collection implementation class, may be null.
 66    */
 67  860 public SequenceParameter(Parameter[] elements, Class implClass)
 68    {
 69  860 this.elements = elements;
 70  860 this.implClass = implClass;
 71    }
 72   
 73    /**
 74    * {@inheritDoc}
 75    */
 76  860 public Object resolveInstance(PicoContainer container, ComponentAdapter adapter,
 77    Class expectedType)
 78    throws PicoInitializationException
 79    {
 80  860 Class elementType = getElementType(expectedType);
 81  860 Object[] items = new Object[elements.length];
 82  860 for(int i = 0; i < elements.length; i++)
 83    {
 84  1978 items[i] = elements[i].resolveInstance(container, adapter, elementType);
 85    }
 86  860 if(expectedType.getComponentType() != null)
 87    {
 88  774 return toArray(items, expectedType);
 89    }
 90  86 if(Collection.class.isAssignableFrom(expectedType))
 91    {
 92  86 if(implClass != null)
 93    {
 94  86 return toCollection(items, implClass);
 95    }
 96    else
 97    {
 98  0 return toCollection(items, expectedType);
 99    }
 100    }
 101  0 throw new PicoIntrospectionException("not a collection nor array type");
 102    }
 103   
 104    /**
 105    * {@inheritDoc}
 106    */
 107  1118 public boolean isResolvable(PicoContainer container, ComponentAdapter adapter,
 108    Class expectedType)
 109    {
 110  1118 try
 111    {
 112  1118 Class elementType = getElementType(expectedType);
 113  1032 for(Parameter element : elements)
 114    {
 115  2150 if(!element.isResolvable(container, adapter, elementType))
 116    {
 117  172 return false;
 118    }
 119    }
 120  860 return true;
 121    }
 122    catch(PicoIntrospectionException e)
 123    {
 124    // non array or collection type
 125  86 return false;
 126    }
 127    }
 128   
 129    /**
 130    * {@inheritDoc}
 131    */
 132  0 public void verify(PicoContainer container, ComponentAdapter adapter, Class expectedType)
 133    throws PicoIntrospectionException
 134    {
 135  0 Class elementType = getElementType(expectedType);
 136  0 for(Parameter element : elements)
 137    {
 138  0 element.verify(container, adapter, expectedType);
 139    }
 140    }
 141   
 142    /**
 143    * {@inheritDoc}
 144    */
 145  0 public void accept(PicoVisitor visitor)
 146    {
 147  0 visitor.visitParameter(this);
 148  0 for(Parameter element : elements)
 149    {
 150  0 visitor.visitParameter(element);
 151    }
 152    }
 153   
 154  1978 private Class getElementType(Class expectedType)
 155    {
 156  1978 if(expectedType.getComponentType() != null)
 157    {
 158  1720 return expectedType.getComponentType();
 159    }
 160  258 if(Collection.class.isAssignableFrom(expectedType))
 161    {
 162    // Cannot determine actual type parameters from a Class object. This is not supported
 163    // Java5. We could determine the type parameter from the constructor though - we
 164    // would have to be passed java.lang.reflect.ParametrizedType, which can be obtained
 165    // from Constructor.getGenericParameterTypes()
 166  172 return Object.class;
 167    }
 168  86 throw new PicoIntrospectionException("not a collection nor array type");
 169    }
 170   
 171  774 private Object toArray(Object[] source, Class targetType)
 172    {
 173  774 Object target = Array.newInstance(targetType.getComponentType(), source.length);
 174  774 System.arraycopy(source, 0, target, 0, source.length);
 175  774 return target;
 176    }
 177   
 178  86 private Object toCollection(Object[] source, Class targetType)
 179    {
 180  86 Collection target;
 181  86 try
 182    {
 183  86 try
 184    {
 185  86 Constructor ctor = targetType.getConstructor(new Class[] { Integer.TYPE });
 186  86 target = (Collection)ctor.newInstance(new Object[] { new Integer(source.length) });
 187    }
 188    catch(NoSuchMethodException e)
 189    {
 190  0 try
 191    {
 192  0 Constructor ctor = targetType.getConstructor(new Class[0]);
 193  0 target = (Collection)ctor.newInstance(new Object[0]);
 194    }
 195    catch(NoSuchMethodException ee)
 196    {
 197  0 throw new CollectionInstantiationException("cannot instantiate Collection "
 198    + targetType.getName() + " no supported constructors found", ee);
 199    }
 200    }
 201    }
 202    catch(Exception e)
 203    {
 204  0 if(e instanceof PicoException)
 205    {
 206  0 throw (PicoException)e;
 207    }
 208    else
 209    {
 210  0 throw new CollectionInstantiationException("cannot instantiate Collection "
 211    + targetType.getName(), e);
 212    }
 213    }
 214  86 target.addAll(Arrays.asList(source));
 215  86 return target;
 216    }
 217    }