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 com.thoughtworks.paranamer.CachingParanamer;
020    
021    /**
022     * Injection will happen in a single member function on the component.
023     *
024     * @author Paul Hammant 
025     * 
026     */
027    public abstract class SingleMemberInjector<T> extends AbstractInjector<T> {
028    
029        private transient CachingParanamer paranamer = new CachingParanamer();
030    
031        public SingleMemberInjector(Object componentKey,
032                                    Class componentImplementation,
033                                    Parameter[] parameters,
034                                    ComponentMonitor monitor,
035                                    LifecycleStrategy lifecycleStrategy, boolean useNames) {
036            super(componentKey, componentImplementation, parameters, monitor, lifecycleStrategy, useNames);
037        }
038    
039        protected CachingParanamer getParanamer() {
040            return paranamer;
041        }
042    
043    
044        /**
045         * TODO: shall it box everything?  a bit too few for me (konstantin)
046         */
047        protected Class box(Class parameterType) {
048            if (parameterType.isPrimitive()) {
049                String parameterTypeName = parameterType.getName();
050                if (parameterTypeName == "int") {
051                    return Integer.class;
052                } else if (parameterTypeName == "boolean") {
053                    return Boolean.class;
054                } else if (parameterTypeName == "long") {
055                    return Long.class;
056                } else if (parameterTypeName == "float") {
057                    return Float.class;
058                } else if (parameterTypeName == "double") {
059                    return Double.class;
060                } else if (parameterTypeName == "char") {
061                    return Character.class;
062                } else if (parameterTypeName == "byte") {
063                    return Byte.class;
064                } else if (parameterTypeName == "short") {
065                    return Short.class;
066                }
067            }
068            return parameterType;
069        }
070    
071    
072        @SuppressWarnings("unchecked")
073        protected Object[] getMemberArguments(PicoContainer container, final AccessibleObject member, final Class[] parameterTypes, final Annotation[] bindings) {
074            for (int i = 0; i < parameterTypes.length; i++) {
075                parameterTypes[i] = box(parameterTypes[i]);
076    
077            }
078            Object[] result = new Object[parameterTypes.length];
079            Parameter[] currentParameters = parameters != null ? parameters : createDefaultParameters(parameterTypes);
080    
081            for (int i = 0; i < currentParameters.length; i++) {
082                result[i] = currentParameters[i].resolveInstance(container, this, parameterTypes[i],
083                    new ParameterNameBinding(paranamer, getComponentImplementation(), member, i), useNames(), bindings[i]);
084            }
085            return result;
086        }
087    
088        protected Annotation[] getBindings(Annotation[][] annotationss) {
089            Annotation[] retVal = new Annotation[annotationss.length];
090            for (int i = 0; i < annotationss.length; i++) {
091                Annotation[] annotations = annotationss[i];
092                for (int j = 0; j < annotations.length; j++) {
093                    Annotation annotation = annotations[j];
094                    if (annotation.annotationType().getAnnotation(Bind.class) != null) {
095                        retVal[i] = annotation;
096                        break;
097                    }
098                }
099            }
100            return retVal;
101        }
102    
103    
104    }