1 package com.bm.introspectors;
2
3 import java.beans.PropertyDescriptor;
4 import java.lang.annotation.Annotation;
5 import java.lang.reflect.Field;
6 import java.lang.reflect.InvocationTargetException;
7 import java.lang.reflect.Method;
8 import java.lang.reflect.ParameterizedType;
9 import java.lang.reflect.Type;
10
11 import org.apache.commons.beanutils.PropertyUtils;
12 import org.apache.commons.lang.builder.EqualsBuilder;
13 import org.apache.commons.lang.builder.HashCodeBuilder;
14
15
16 import com.bm.ejb3metadata.annotations.metadata.FieldAnnotationMetadata;
17 import com.bm.utils.Ejb3Utils;
18
19
20
21
22
23
24
25
26
27
28 public class Property {
29
30 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(Property.class);
31
32 private final String propertyName;
33
34 private final Field fieldName;
35
36 private final PropertyDescriptor property;
37
38 private final Class declaringClass;
39
40 private final boolean accessTypeField;
41
42
43
44
45
46
47
48
49
50
51 public Property(Class declaringClass, PropertyDescriptor property) {
52 this.propertyName = property.getName();
53 this.property = property;
54 this.fieldName = null;
55 this.accessTypeField = false;
56 this.declaringClass = declaringClass;
57 }
58
59
60
61
62
63
64
65
66 public Property(FieldAnnotationMetadata metaData) {
67 this.propertyName = metaData.getFieldName();
68 this.property = null;
69 this.accessTypeField = true;
70 try {
71 this.declaringClass = Thread.currentThread()
72 .getContextClassLoader().loadClass(
73 metaData.getClassAnnotationMetadata()
74 .getClassName().replace('/', '.'));
75 } catch (ClassNotFoundException e) {
76 throw new RuntimeException("The class ("
77 + metaData.getClassAnnotationMetadata().getClassName()
78 + ") was not found");
79 }
80
81 try {
82 this.fieldName = this.declaringClass
83 .getDeclaredField(this.propertyName);
84 } catch (SecurityException e) {
85 throw new RuntimeException("The field (" + this.propertyName
86 + ") in Class ("
87 + metaData.getClassAnnotationMetadata().getClassName()
88 + ") was not found");
89 } catch (NoSuchFieldException e) {
90 throw new RuntimeException("The field (" + this.propertyName
91 + ") in Class ("
92 + metaData.getClassAnnotationMetadata().getClassName()
93 + ") was not found");
94 }
95 }
96
97
98
99
100
101
102
103 public Property(Field fieldName) {
104 this.propertyName = fieldName.getName();
105 this.fieldName = fieldName;
106 this.property = null;
107 this.accessTypeField = true;
108 this.declaringClass = fieldName.getDeclaringClass();
109 }
110
111
112
113
114
115
116
117
118
119
120
121
122 public void setField(Object instance, Object value)
123 throws IllegalAccessException {
124 try {
125 if (this.accessTypeField) {
126
127 if (!this.fieldName.isAccessible()) {
128 this.fieldName.setAccessible(true);
129 this.fieldName.set(instance, value);
130 this.fieldName.setAccessible(false);
131 } else {
132 this.fieldName.set(instance, value);
133 }
134 } else {
135 try {
136
137 PropertyUtils.setProperty(instance, this.propertyName,
138 value);
139 } catch (InvocationTargetException e) {
140 log.error("Can¥t set the value (" + value
141 + ") in property: " + this.propertyName);
142 throw new IllegalAccessException(
143 "Can¥t invoke the setter method set"
144 + this.propertyName);
145 } catch (NoSuchMethodException e) {
146 log.error("Can¥t set the value (" + value
147 + ") in property: " + this.propertyName);
148 throw new IllegalAccessException(
149 "Can¥t invoke the setter method set"
150 + this.propertyName);
151 } catch (IllegalArgumentException e) {
152 log.error("Can¥t set the value (" + value
153 + ") in property: " + this.propertyName);
154 throw e;
155 }
156 }
157 } catch (IllegalAccessException ex) {
158 log.error("Can¥t set the value (" + value + ") in property: "
159 + this.propertyName, ex);
160 throw ex;
161 } catch (RuntimeException ruex) {
162
163 log.error("Can¥t set the value (" + value + ") in property: "
164 + this.propertyName, ruex);
165 throw ruex;
166
167 }
168 }
169
170
171
172
173
174
175
176
177
178
179
180 public Object getField(Object instance) throws IllegalAccessException {
181 Object back = null;
182 if (this.accessTypeField) {
183
184 if (!this.fieldName.isAccessible()) {
185 this.fieldName.setAccessible(true);
186 back = this.fieldName.get(instance);
187 this.fieldName.setAccessible(false);
188 } else {
189 back = this.fieldName.get(instance);
190 }
191 } else {
192 try {
193
194 back = PropertyUtils.getProperty(instance, this.propertyName);
195 } catch (InvocationTargetException e) {
196 throw new IllegalAccessException(
197 "Can¥t invoke the getter method get"
198 + this.propertyName);
199 } catch (NoSuchMethodException e) {
200 throw new IllegalAccessException(
201 "Can¥t invoke the getter method get"
202 + this.propertyName);
203 }
204 }
205 return back;
206 }
207
208
209
210
211
212
213 public Class getType() {
214 if (this.accessTypeField) {
215 return this.fieldName.getType();
216 }
217 final Method method = this.property.getReadMethod();
218 return method.getReturnType();
219
220 }
221
222
223
224
225
226
227
228
229
230 public Type getGenericType() {
231 if (this.accessTypeField) {
232 return this.fieldName.getGenericType();
233 }
234 final Method methodToFind = this.property.getReadMethod();
235 return methodToFind.getGenericReturnType();
236 }
237
238
239
240
241
242
243
244 @SuppressWarnings("unchecked")
245 public Class<Object> getGenericTypeClass() {
246 if (this.getGenericType() instanceof ParameterizedType) {
247 final ParameterizedType type = (ParameterizedType) this
248 .getGenericType();
249 if (type.getActualTypeArguments().length == 1) {
250 Class<Object> ty = (Class<Object>) type
251 .getActualTypeArguments()[0];
252 return ty;
253 }
254 }
255 return null;
256 }
257
258
259
260
261
262
263 public String getName() {
264 return this.propertyName;
265 }
266
267
268
269
270
271
272 public Class getDeclaringClass() {
273 return this.declaringClass;
274 }
275
276
277
278
279
280
281
282
283
284 @Override
285 public boolean equals(Object other) {
286 if (other instanceof Property) {
287 final Property otherC = (Property) other;
288 final EqualsBuilder eqBuilder = new EqualsBuilder();
289 eqBuilder.append(this.accessTypeField, otherC.accessTypeField);
290 eqBuilder.append(this.fieldName, otherC.fieldName);
291 eqBuilder.append(this.property, otherC.property);
292 return eqBuilder.isEquals();
293
294 }
295 return false;
296 }
297
298
299
300
301
302
303
304 @Override
305 public int hashCode() {
306 final HashCodeBuilder hcBuilder = new HashCodeBuilder(3, 17);
307 hcBuilder.append(this.accessTypeField);
308 hcBuilder.append(this.fieldName);
309 hcBuilder.append(this.property);
310 return hcBuilder.toHashCode();
311 }
312
313
314
315
316
317
318 public PropertyDescriptor getProperty() {
319 return property;
320 }
321
322
323
324
325
326
327 public String getPropertyName() {
328 return propertyName;
329 }
330
331
332
333
334
335
336
337
338
339
340 public <T extends Annotation> T getAnnotation(Class<T> annnotation) {
341 if (this.accessTypeField) {
342 return this.fieldName.getAnnotation(annnotation);
343 }
344 return this.property.getReadMethod().getAnnotation(annnotation);
345 }
346
347
348
349
350
351
352
353 @Override
354 public String toString() {
355 final StringBuilder sb = new StringBuilder();
356 sb.append("Declared in Class: (").append(
357 Ejb3Utils.getShortClassName(this.getDeclaringClass())).append(
358 ") Prop.Name: (").append(this.propertyName)
359 .append(") - Type (").append(
360 Ejb3Utils.getShortClassName(this.getType()))
361 .append(")");
362 return sb.toString();
363 }
364 }