001    /*****************************************************************************
002     * Copyright (c) PicoContainer Organization. All rights reserved.            *
003     * ------------------------------------------------------------------------- *
004     * The software in this package is published under the terms of the BSD      *
005     * style license a copy of which has been included with this distribution in *
006     * the LICENSE.txt file.                                                     *
007     *                                                                           *
008     *****************************************************************************/
009    package org.picocontainer.injectors;
010    
011    import org.picocontainer.ComponentMonitor;
012    import org.picocontainer.LifecycleStrategy;
013    import org.picocontainer.Parameter;
014    import org.picocontainer.PicoContainer;
015    import org.picocontainer.annotations.Bind;
016    
017    import java.lang.annotation.Annotation;
018    import java.lang.reflect.AccessibleObject;
019    import java.lang.reflect.Type;
020    
021    import com.thoughtworks.paranamer.CachingParanamer;
022    
023    /**
024     * Injection will happen in a single member function on the component.
025     *
026     * @author Paul Hammant 
027     * 
028     */
029    public abstract class SingleMemberInjector<T> extends AbstractInjector<T> {
030    
031        private transient CachingParanamer paranamer = new CachingParanamer();
032    
033        public SingleMemberInjector(Object componentKey,
034                                    Class componentImplementation,
035                                    Parameter[] parameters,
036                                    ComponentMonitor monitor,
037                                    LifecycleStrategy lifecycleStrategy, boolean useNames) {
038            super(componentKey, componentImplementation, parameters, monitor, lifecycleStrategy, useNames);
039        }
040    
041        protected CachingParanamer getParanamer() {
042            return paranamer;
043        }
044    
045        @SuppressWarnings("unchecked")
046        protected Object[] getMemberArguments(PicoContainer container, final AccessibleObject member, final Type[] parameterTypes, final Annotation[] bindings) {
047            for (int i = 0; i < parameterTypes.length; i++) {
048                parameterTypes[i] = box(parameterTypes[i]);
049    
050            }
051            Object[] result = new Object[parameterTypes.length];
052            Parameter[] currentParameters = parameters != null ? parameters : createDefaultParameters(parameterTypes);
053    
054            for (int i = 0; i < currentParameters.length; i++) {
055                result[i] = currentParameters[i].resolveInstance(container, this, parameterTypes[i],
056                    new ParameterNameBinding(paranamer, getComponentImplementation(), member, i), useNames(), bindings[i]);
057            }
058            return result;
059        }
060    
061        protected Annotation[] getBindings(Annotation[][] annotationss) {
062            Annotation[] retVal = new Annotation[annotationss.length];
063            for (int i = 0; i < annotationss.length; i++) {
064                Annotation[] annotations = annotationss[i];
065                for (int j = 0; j < annotations.length; j++) {
066                    Annotation annotation = annotations[j];
067                    if (annotation.annotationType().getAnnotation(Bind.class) != null) {
068                        retVal[i] = annotation;
069                        break;
070                    }
071                }
072            }
073            return retVal;
074        }
075    
076    
077    }