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 *****************************************************************************/
010
011 package org.picocontainer.injectors;
012
013 import org.picocontainer.ComponentAdapter;
014 import org.picocontainer.ComponentMonitor;
015 import org.picocontainer.Parameter;
016 import org.picocontainer.PicoCompositionException;
017 import org.picocontainer.Characteristics;
018 import org.picocontainer.LifecycleStrategy;
019 import org.picocontainer.InjectionFactory;
020 import org.picocontainer.behaviors.AbstractBehaviorFactory;
021 import org.picocontainer.injectors.MethodInjection;
022 import org.picocontainer.annotations.Inject;
023
024 import java.io.Serializable;
025 import java.lang.reflect.Field;
026 import java.lang.reflect.Method;
027 import java.util.Properties;
028
029 /**
030 * Creates instances Injectors, depending on whether the component is the presence of Annotations and characteristics.
031 *
032 * @author Paul Hammant
033 */
034 public class AdaptiveInjection implements InjectionFactory, Serializable {
035
036 public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor,
037 LifecycleStrategy lifecycleStrategy,
038 Properties componentProperties,
039 Object componentKey,
040 Class componentImplementation,
041 Parameter... parameters) throws PicoCompositionException {
042 ComponentAdapter componentAdapter = null;
043 componentAdapter = makeIfFieldAnnotationInjection(componentImplementation,
044 componentMonitor,
045 lifecycleStrategy,
046 componentProperties,
047 componentKey,
048 componentAdapter,
049 parameters);
050
051 if (componentAdapter != null) {
052 return componentAdapter;
053 }
054
055
056 componentAdapter = makeIfMethodAnnotationInjection(componentImplementation,
057 componentMonitor,
058 lifecycleStrategy,
059 componentProperties,
060 componentKey,
061 componentAdapter,
062 parameters);
063
064 if (componentAdapter != null) {
065 return componentAdapter;
066 }
067
068 componentAdapter = makeIfSetterInjection(componentProperties,
069 componentMonitor,
070 lifecycleStrategy,
071 componentKey,
072 componentImplementation,
073 componentAdapter,
074 parameters);
075
076 if (componentAdapter != null) {
077 return componentAdapter;
078 }
079
080 componentAdapter = makeIfMethodInjection(componentProperties,
081 componentMonitor,
082 lifecycleStrategy,
083 componentKey,
084 componentImplementation,
085 componentAdapter,
086 parameters);
087
088 if (componentAdapter != null) {
089 return componentAdapter;
090 }
091
092
093 return makeDefaultInjection(componentProperties,
094 componentMonitor,
095 lifecycleStrategy,
096 componentKey,
097 componentImplementation,
098 parameters);
099 }
100
101 protected ComponentAdapter makeDefaultInjection(Properties componentProperties,
102 ComponentMonitor componentMonitor,
103 LifecycleStrategy lifecycleStrategy,
104 Object componentKey,
105 Class componentImplementation, Parameter... parameters) {
106 AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.CDI);
107 return new ConstructorInjection().createComponentAdapter(componentMonitor,
108 lifecycleStrategy,
109 componentProperties,
110 componentKey,
111 componentImplementation,
112 parameters);
113 }
114
115 protected ComponentAdapter makeIfSetterInjection(Properties componentProperties,
116 ComponentMonitor componentMonitor,
117 LifecycleStrategy lifecycleStrategy,
118 Object componentKey,
119 Class componentImplementation,
120 ComponentAdapter componentAdapter,
121 Parameter... parameters) {
122 if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.SDI)) {
123 componentAdapter = new SetterInjection().createComponentAdapter(componentMonitor, lifecycleStrategy,
124 componentProperties,
125 componentKey,
126 componentImplementation,
127 parameters);
128 }
129 return componentAdapter;
130 }
131
132 protected ComponentAdapter makeIfMethodInjection(Properties componentProperties,
133 ComponentMonitor componentMonitor,
134 LifecycleStrategy lifecycleStrategy,
135 Object componentKey,
136 Class componentImplementation,
137 ComponentAdapter componentAdapter,
138 Parameter... parameters) {
139 if (AbstractBehaviorFactory.removePropertiesIfPresent(componentProperties, Characteristics.METHOD_INJECTION)) {
140 componentAdapter = new MethodInjection().createComponentAdapter(componentMonitor, lifecycleStrategy,
141 componentProperties,
142 componentKey,
143 componentImplementation,
144 parameters);
145 }
146 return componentAdapter;
147 }
148
149
150 protected ComponentAdapter makeIfMethodAnnotationInjection(Class componentImplementation,
151 ComponentMonitor componentMonitor,
152 LifecycleStrategy lifecycleStrategy,
153 Properties componentProperties,
154 Object componentKey,
155 ComponentAdapter componentAdapter,
156 Parameter... parameters) {
157 if (isMethodAnnotationInjection(componentImplementation)) {
158 componentAdapter =
159 new AnnotatedMethodInjection().createComponentAdapter(componentMonitor,
160 lifecycleStrategy,
161 componentProperties,
162 componentKey,
163 componentImplementation,
164 parameters);
165 }
166 return componentAdapter;
167 }
168
169 protected ComponentAdapter makeIfFieldAnnotationInjection(Class componentImplementation,
170 ComponentMonitor componentMonitor,
171 LifecycleStrategy lifecycleStrategy,
172 Properties componentProperties,
173 Object componentKey, ComponentAdapter componentAdapter, Parameter... parameters)
174 {
175 if (isFieldAnnotationInjection(componentImplementation)) {
176 componentAdapter =
177 new AnnotatedFieldInjection().createComponentAdapter(componentMonitor,
178 lifecycleStrategy,
179 componentProperties,
180 componentKey,
181 componentImplementation,
182 parameters);
183 }
184 return componentAdapter;
185 }
186
187 protected boolean isMethodAnnotationInjection(Class componentImplementation) {
188 Method[] methods = componentImplementation.getDeclaredMethods();
189 for (Method method : methods) {
190 if (method.getAnnotation(Inject.class) != null) {
191 return true;
192 }
193 }
194 return false;
195 }
196
197 protected boolean isFieldAnnotationInjection(Class componentImplementation) {
198 Field[] fields = componentImplementation.getDeclaredFields();
199 for (Field field : fields) {
200 if (field.getAnnotation(Inject.class) != null) {
201 return true;
202 }
203 }
204 return false;
205 }
206
207 }