    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 Object memberInvocationReturn(Object lastReturn, AccessibleObject member, Object instance) {
    067            return member != null && ((Method)member).getReturnType()!=void.class ? lastReturn : instance;
    068        }
    069
    070        protected Object injectIntoMember(AccessibleObject member, Object componentInstance, Object toInject)
    071            throws IllegalAccessException, InvocationTargetException {
    072            return ((Method)member).invoke(componentInstance, toInject);
    073        }
    074
    075        protected boolean isInjectorMethod(Method method) {
    076            String methodName = method.getName();
    077            return methodName.length() >= getInjectorPrefix().length() + 1 && methodName.startsWith(getInjectorPrefix()) && Character.isUpperCase(methodName.charAt(getInjectorPrefix().length()));
    078        }
    079
    080        protected String getInjectorPrefix() {
    081            return setterMethodPrefix;
    082        }
    083
    084        public String getDescriptor() {
    085            return "SetterInjector-";
    086        }
    087
    088
    089    }