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