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     * Original code by                                                          *
009     *****************************************************************************/
010    package org.picocontainer.injectors;
011    
012    import org.picocontainer.ComponentMonitor;
013    import org.picocontainer.Parameter;
014    import org.picocontainer.LifecycleStrategy;
015    import org.picocontainer.behaviors.PropertyApplicator;
016    import org.picocontainer.behaviors.Cached;
017    
018    import java.lang.reflect.Method;
019    import java.lang.reflect.AccessibleObject;
020    import java.lang.reflect.InvocationTargetException;
021    
022    /**
023     * Instantiates components using empty constructors and
024     * <a href="http://picocontainer.org/setter-injection.html">Setter Injection</a>.
025     * For easy setting of primitive properties, also see {@link PropertyApplicator}.
026     * <p/>
027     * <em>
028     * Note that this class doesn't cache instances. If you want caching,
029     * use a {@link Cached} around this one.
030     * </em>
031     * </p>
032     *
033     * @author Aslak Helles&oslash;y
034     * @author J&ouml;rg Schaible
035     * @author Mauro Talevi
036     * @author Paul Hammant
037     */
038    @SuppressWarnings("serial")
039    public class SetterInjector<T> extends IterativeInjector<T> {
040    
041        private final String setterMethodPrefix;
042    
043        /**
044         * Constructs a SetterInjector
045         *
046         * @param componentKey            the search key for this implementation
047         * @param componentImplementation the concrete implementation
048         * @param parameters              the parameters to use for the initialization
049         * @param monitor                 the component monitor used by this addAdapter
050         * @param lifecycleStrategy       the component lifecycle strategy used by this addAdapter
051         * @param setterMethodPrefix
052         * @throws org.picocontainer.injectors.AbstractInjector.NotConcreteRegistrationException
053         *                              if the implementation is not a concrete class.
054         * @throws NullPointerException if one of the parameters is <code>null</code>
055         */
056        public SetterInjector(final Object componentKey,
057                              final Class componentImplementation,
058                              Parameter[] parameters,
059                              ComponentMonitor monitor,
060                              LifecycleStrategy lifecycleStrategy,
061                              String setterMethodPrefix, boolean useNames) throws  NotConcreteRegistrationException {
062            super(componentKey, componentImplementation, parameters, monitor, lifecycleStrategy, useNames);
063            this.setterMethodPrefix = setterMethodPrefix;
064        }
065    
066        protected void injectIntoMember(AccessibleObject member, Object componentInstance, Object toInject)
067            throws IllegalAccessException, InvocationTargetException {
068            ((Method)member).invoke(componentInstance, toInject);
069        }
070    
071        protected boolean isInjectorMethod(Method method) {
072            String methodName = method.getName();
073            return methodName.length() >= getInjectorPrefix().length() + 1 && methodName.startsWith(getInjectorPrefix()) && Character.isUpperCase(methodName.charAt(getInjectorPrefix().length()));
074        }
075    
076        protected String getInjectorPrefix() {
077            return setterMethodPrefix;
078        }
079    
080        public String getDescriptor() {
081            return "SetterInjector-"; 
082        }
083    
084    
085    }