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 }