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 * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant * 009 *****************************************************************************/ 010package org.picocontainer.injectors; 011 012import org.picocontainer.Characteristics; 013import org.picocontainer.ComponentAdapter; 014import org.picocontainer.ComponentMonitor; 015import org.picocontainer.LifecycleStrategy; 016import org.picocontainer.Parameter; 017import org.picocontainer.PicoCompositionException; 018import org.picocontainer.behaviors.AbstractBehaviorFactory; 019 020import java.lang.reflect.Method; 021import java.util.HashSet; 022import java.util.Properties; 023import java.util.Set; 024 025/** 026 * A {@link org.picocontainer.InjectionFactory} for methods. 027 * The factory creates {@link MethodInjector}. 028 * 029 * @author Paul Hammant 030 */ 031@SuppressWarnings("serial") 032public class MethodInjection extends AbstractInjectionFactory { 033 034 private final AbstractInjectionFactory delegate; 035 036 public MethodInjection(String injectionMethodName) { 037 delegate = new MethodInjectionByName(injectionMethodName); 038 } 039 040 public MethodInjection(String... injectionMethodNames) { 041 delegate = new MethodInjectionByName(injectionMethodNames); 042 } 043 044 public MethodInjection() { 045 this("inject"); 046 } 047 048 public MethodInjection(Method injectionMethod) { 049 delegate = new MethodInjectionByReflectionMethod(injectionMethod); 050 } 051 052 public <T> ComponentAdapter<T> createComponentAdapter(ComponentMonitor componentMonitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, 053 Class<T> componentImplementation, Parameter... parameters) throws PicoCompositionException { 054 return delegate.createComponentAdapter(componentMonitor, lifecycleStrategy, componentProperties, componentKey, componentImplementation, parameters); 055 } 056 057 public class MethodInjectionByName extends AbstractInjectionFactory { 058 private final Set<String> injectionMethodNames = new HashSet<String>(); 059 060 public MethodInjectionByName(String... injectionMethodNames) { 061 for (String injectionMethodName : injectionMethodNames) { 062 this.injectionMethodNames.add(injectionMethodName); 063 } 064 } 065 066 public MethodInjectionByName(String injectionMethodName) { 067 this.injectionMethodNames.add(injectionMethodName); 068 } 069 070 public <T> ComponentAdapter<T> createComponentAdapter(ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class<T> componentImplementation, Parameter... parameters) throws PicoCompositionException { 071 boolean useNames = AbstractBehaviorFactory.arePropertiesPresent(componentProperties, Characteristics.USE_NAMES, true); 072 return wrapLifeCycle(new MethodInjector.ByMethodName(componentKey, componentImplementation, parameters, monitor, injectionMethodNames, useNames), lifecycleStrategy); 073 } 074 } 075 076 public class MethodInjectionByReflectionMethod extends AbstractInjectionFactory { 077 private final Method injectionMethod; 078 079 public MethodInjectionByReflectionMethod(Method injectionMethod) { 080 this.injectionMethod = injectionMethod; 081 } 082 083 public <T> ComponentAdapter<T> createComponentAdapter(ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, Properties componentProperties, Object componentKey, Class<T> componentImplementation, Parameter... parameters) throws PicoCompositionException { 084 boolean useNames = AbstractBehaviorFactory.arePropertiesPresent(componentProperties, Characteristics.USE_NAMES, true); 085 if (injectionMethod.getDeclaringClass().isAssignableFrom(componentImplementation)) { 086 return wrapLifeCycle(monitor.newInjector(new MethodInjector.ByReflectionMethod(componentKey, componentImplementation, parameters, monitor, injectionMethod, useNames)), lifecycleStrategy); 087 } else { 088 throw new PicoCompositionException("method [" + injectionMethod + "] not on impl " + componentImplementation.getName()); 089 } 090 } 091 } 092 093}