1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.fatwire.gst.foundation.controller.action;
18
19 import java.lang.annotation.Annotation;
20 import java.lang.reflect.Field;
21 import java.lang.reflect.InvocationTargetException;
22 import java.lang.reflect.Method;
23 import java.util.ArrayList;
24 import java.util.List;
25
26 import org.apache.commons.lang.StringUtils;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.springframework.beans.BeanUtils;
30
31 import com.fatwire.gst.foundation.DebugHelper;
32 import com.fatwire.gst.foundation.controller.annotation.InjectForRequest;
33
34
35
36
37
38
39
40
41 public final class AnnotationInjector {
42 protected static final Log LOG = LogFactory.getLog(AnnotationInjector.class.getPackage().getName());
43 protected static final Log LOG_TIME = LogFactory.getLog(AnnotationInjector.class.getPackage().getName() + ".time");
44
45
46
47
48
49
50
51
52
53
54
55 public static final void inject(final Object object, final Factory factory) {
56 if (object == null) {
57 throw new IllegalArgumentException("object cannot be null.");
58 }
59 if (factory == null) {
60 throw new IllegalArgumentException("factory cannot be null.");
61 }
62 final long start = LOG_TIME.isDebugEnabled() ? System.nanoTime() : 0L;
63 try {
64 Class<?> c = object.getClass();
65
66 for (final Method method : c.getMethods()) {
67 if (method.isAnnotationPresent(InjectForRequest.class)) {
68 injectIntoMethod(object, factory, method);
69 }
70 }
71
72 while (c != Object.class && c != null) {
73 for (final Field field : c.getDeclaredFields()) {
74 if (field.isAnnotationPresent(InjectForRequest.class)) {
75 injectIntoField(object, factory, field);
76 }
77
78 }
79
80 c = c.getSuperclass();
81 }
82 } finally {
83 DebugHelper.printTime(LOG_TIME, "inject model for " + object.getClass().getName(), start);
84 }
85 }
86
87
88
89
90
91
92
93
94
95 public static final Field[] findFieldsWithAnnotation(final Object object,
96 final Class<? extends Annotation> annnotationClass) {
97 if (object == null) {
98 throw new IllegalArgumentException("object must not be null.");
99 }
100 if (annnotationClass == null) {
101 throw new IllegalArgumentException("clazz must not be null.");
102 }
103 final List<Field> x = new ArrayList<Field>();
104 Class<?> c = object.getClass();
105 while (c != Object.class && c != null) {
106 for (final Field field : c.getDeclaredFields()) {
107
108 if (field.isAnnotationPresent(annnotationClass)) {
109 x.add(field);
110 }
111
112 }
113
114 c = c.getSuperclass();
115 }
116 return x.toArray(new Field[x.size()]);
117 }
118
119
120
121
122
123
124
125 public static void injectIntoField(final Object object, final Factory factory, final Field field)
126 throws SecurityException {
127
128 final InjectForRequest ifr = field.getAnnotation(InjectForRequest.class);
129
130 String name = ifr.value();
131 if (StringUtils.isBlank(name)) {
132 name = field.getName();
133 }
134 final Object injectionValue = factory.getObject(name, field.getType());
135 if (injectionValue == null) {
136 throw new InjectionException(factory.getClass().getName() + " does not know how to inject '"
137 + field.getType().getName() + "' into the field '" + field.getName() + "' for an action.");
138 }
139 field.setAccessible(true);
140 if (LOG.isDebugEnabled()) {
141 LOG.debug("Injecting " + injectionValue.getClass().getName() + " into field " + field.getName() + " for "
142 + object.getClass().getName());
143 }
144 try {
145 field.set(object, injectionValue);
146 } catch (final IllegalArgumentException e) {
147 throw new InjectionException("IllegalArgumentException injecting " + injectionValue + " into field "
148 + field.getName(), e);
149 } catch (final IllegalAccessException e) {
150 throw new InjectionException("IllegalAccessException injecting " + injectionValue + " into field "
151 + field.getName(), e);
152 }
153 }
154
155
156
157
158
159
160
161 public static void injectIntoMethod(final Object object, final Factory factory, final Method method)
162 throws SecurityException {
163
164 final InjectForRequest ifr = method.getAnnotation(InjectForRequest.class);
165
166 String name = ifr.value();
167 if (StringUtils.isBlank(name)) {
168 name = BeanUtils.findPropertyForMethod(method).getName();
169 }
170
171 final Class<?> type = method.getParameterTypes()[0];
172 final Object injectionValue = factory.getObject(name, type);
173 if (injectionValue == null) {
174 throw new InjectionException(factory.getClass().getName() + " does not know how to inject '" + type.getName()
175 + "' into the field '" + method.getName() + "' for an action.");
176 }
177
178
179 if (LOG.isDebugEnabled()) {
180 LOG.debug("Injecting " + injectionValue.getClass().getName() + " into field " + method.getName() + " for "
181 + object.getClass().getName());
182 }
183 try {
184 method.invoke(object, injectionValue);
185 } catch (final IllegalArgumentException e) {
186 throw new InjectionException("IllegalArgumentException injecting " + injectionValue + " into method "
187 + method.getName(), e);
188 } catch (final IllegalAccessException e) {
189 throw new InjectionException("IllegalAccessException injecting " + injectionValue + " into method "
190 + method.getName(), e);
191 } catch (final InvocationTargetException e) {
192 throw new InjectionException("InvocationTargetException injecting " + injectionValue
193 + " into method " + method.getName(), e);
194 }
195 }
196
197 }