1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.student.common.spring;
17
18 import java.beans.PropertyDescriptor;
19 import java.lang.reflect.Field;
20 import java.lang.reflect.Method;
21 import java.lang.reflect.Proxy;
22 import java.util.Set;
23
24 import javax.annotation.Resource;
25 import javax.inject.Inject;
26 import javax.jws.WebService;
27 import javax.xml.namespace.QName;
28
29 import org.apache.commons.lang.StringUtils;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32 import org.springframework.beans.BeansException;
33 import org.springframework.beans.PropertyValues;
34 import org.springframework.beans.factory.BeanFactory;
35 import org.springframework.beans.factory.BeanFactoryAware;
36 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
37 import org.springframework.beans.factory.annotation.Autowired;
38 import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
39 import org.springframework.beans.factory.annotation.Value;
40 import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
41 import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
42 import org.springframework.core.Ordered;
43 import org.springframework.core.PriorityOrdered;
44 import org.springframework.util.ReflectionUtils;
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 public class WebServiceAwareSpringBeanPostProcessor extends AutowiredAnnotationBeanPostProcessor implements PriorityOrdered, BeanFactoryAware {
62
63 private static final Logger log = LoggerFactory
64 .getLogger(WebServiceAwareSpringBeanPostProcessor.class);
65
66 private BeanFactory beanFactory;
67
68
69
70
71 public WebServiceAwareSpringBeanPostProcessor() {
72 }
73
74
75
76
77
78
79 @Override
80 public int getOrder() {
81 return Ordered.HIGHEST_PRECEDENCE;
82 }
83
84
85
86 @Override
87 public Object postProcessBeforeInitialization(Object bean, String beanName)
88 throws BeansException {
89
90
91 return bean;
92 }
93
94
95
96
97
98
99 @Override
100 public boolean postProcessAfterInstantiation(Object bean, String beanName)
101 throws BeansException {
102
103 Class<? extends Object> beanClass = bean.getClass();
104
105 try {
106 super.processInjection(bean);
107
108 } catch (BeansException e2) {
109
110
111
112 }
113
114 Field[] fields = beanClass.getDeclaredFields();
115
116 for (Field field : fields) {
117
118
119 if (!fieldHasInjectionAnnotation(field))
120 continue;
121
122
123 Object currentValue = null;
124 try {
125
126 ReflectionUtils.makeAccessible(field);
127
128 currentValue = field.get(bean);
129
130 } catch (IllegalArgumentException e1) {
131 log.warn("get error", e1);
132 continue;
133
134 } catch (SecurityException e1) {
135 log.warn("get error", e1);
136 continue;
137 } catch (IllegalAccessException e1) {
138 log.warn("get error", e1);
139 continue;
140 }
141
142
143 if (currentValue != null)
144 continue;
145
146 Class<?> fieldType = field.getType();
147
148 WebService webServiceAnnotation = (WebService) fieldType.getAnnotation(
149 WebService.class);
150
151 if (webServiceAnnotation != null) {
152
153
154
155
156
157 String namespace = webServiceAnnotation.targetNamespace();
158 String serviceName = webServiceAnnotation.serviceName();
159
160 if (serviceName.isEmpty())
161 serviceName = webServiceAnnotation.name();
162
163 if (namespace != null) {
164
165
166
167
168 try {
169
170 Object service = null;
171 try {
172 service = beanFactory.getBean(serviceName, fieldType);
173 } catch (NoSuchBeanDefinitionException e) {
174 service = null;
175
176 }
177
178 if (service != null) {
179 injectServiceReference(bean, beanName, field, service, " from ApplicationContext using BeanName: " + serviceName);
180 continue;
181 }
182
183
184
185
186 final QName name = new QName(namespace, serviceName);
187
188
189
190 try {
191 SerializableProxyInvokationHandler invocationHandler = new SerializableProxyInvokationHandler();
192
193 invocationHandler.setServiceName(name);
194
195 service = Proxy
196 .newProxyInstance(
197 getClass().getClassLoader(),
198 new Class[] { fieldType },
199 invocationHandler);
200
201
202 injectServiceReference(bean, beanName, field, service, " from KSB using QName: " + name);
203
204 } catch (NullPointerException e1) {
205 log.warn("RiceResourceLoader is not configured/initialized properly.", e1);
206
207 continue;
208 }
209
210
211
212
213
214 } catch (Exception e) {
215 log.error(
216 "failed to lookup resource in GlobalResourceLoader ("
217 + namespace + ", " + serviceName + ")",
218 e);
219 continue;
220 }
221 }
222
223 }
224 }
225
226
227 return false;
228 }
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243 private void injectServiceReference(Object bean, String beanName,
244 Field field,
245 Object service, String message) throws IllegalArgumentException, IllegalAccessException {
246
247 String fieldName = field.getName();
248
249 String setterMethodName = "set" + StringUtils.capitalize(fieldName);
250
251 Class<? extends Object> beanClass = bean.getClass();
252
253 Class<?> fieldType = field.getType();
254
255 try {
256
257
258
259
260
261
262
263
264 Method setterMethod = beanClass.getMethod(
265 setterMethodName, field.getType());
266
267 ReflectionUtils.invokeMethod(setterMethod, bean,
268 service);
269
270 log.warn("RESOLVED: beanName = " + beanName + ", fieldName = " + field.getName() + ", fieldType = " + fieldType.getName() + message);
271
272
273 } catch (IllegalArgumentException e) {
274 log.warn("set error", e);
275 } catch (SecurityException e) {
276 log.warn("set error", e);
277 } catch (NoSuchMethodException e) {
278
279
280 ReflectionUtils.makeAccessible(field);
281
282 field.set(bean, service);
283 log.warn("RESOLVED: beanName = " + beanName + ", fieldName = " + field.getName() + ", fieldType = " + fieldType.getName() + message);
284 }
285
286 }
287
288
289
290
291
292
293 @Override
294 public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
295 this.beanFactory = beanFactory;
296 super.setBeanFactory(beanFactory);
297 }
298
299
300
301 @Override
302 public Object postProcessAfterInitialization(Object bean, String beanName)
303 throws BeansException {
304
305
306 return bean;
307 }
308
309 private boolean fieldHasInjectionAnnotation(Field field) {
310
311
312 if (field.getAnnotation(Autowired.class) != null) {
313 log.debug("detected @Autowired annotation on field: "
314 + field.getName());
315 return true;
316 }
317 if (field.getAnnotation(Value.class) != null) {
318 log.debug("detected @Value annotation on field: " + field.getName());
319 return true;
320 }
321 if (field.getAnnotation(Resource.class) != null) {
322 log.debug("detected @Resource annotation on field: "
323 + field.getName());
324 return true;
325 }
326 if (field.getAnnotation(Inject.class) != null) {
327 log.debug("detected @Inject annotation on field: "
328 + field.getName());
329 return true;
330 }
331
332
333 return false;
334
335 }
336
337
338
339 }