MentaContainer

Rev

Rev 4 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 soliveira 1
package org.mentacontainer.util;
2
 
3
import java.lang.reflect.Field;
4
import java.lang.reflect.InvocationTargetException;
5
import java.lang.reflect.Method;
6
import java.text.DateFormat;
7
import java.util.ArrayList;
8
import java.util.HashMap;
9
import java.util.Iterator;
10
import java.util.List;
11
import java.util.Locale;
12
import java.util.Map;
13
 
14
public class InjectionUtils {
15
 
16
        /**
17
         * The character used to separate the prefix from the value name when you
18
         * are using the getObject method with a prefix. You can change the value of
19
         * this prefix if you want to by changing this static variable.
20
         *
21
         * Ex: getObject(User.class, "user") will get all values that begin with
22
         * "user.".
23
         */
24
        public static char PREFIX_SEPARATOR = '.';
25
 
26
        private static Map<Class<? extends Object>, Map<String, Object>> settersMaps = new HashMap<Class<? extends Object>, Map<String, Object>>();
27
 
28
        private static Map<Class<? extends Object>, Map<String, Object>> fieldsMaps = new HashMap<Class<? extends Object>, Map<String, Object>>();
29
 
30
        public static void prepareForInjection(Class<? extends Object> klass,
31
                        Map<String, Object> setters, Map<String, Object> fields) {
32
 
33
                StringBuffer sb = new StringBuffer(32);
34
 
35
                Method[] methods = klass.getMethods();
36
 
37
                for (int i = 0; i < methods.length; i++) {
38
 
39
                        Method m = methods[i];
40
 
41
                        String name = m.getName();
42
 
43
                        Class[] types = m.getParameterTypes();
44
 
45
                        if (name.startsWith("set") && name.length() > 3
46
                                        && types.length == 1) {
47
 
48
                                String var = name.substring(3);
49
 
50
                                if (var.length() > 1) {
51
 
52
                                        sb.delete(0, sb.length());
53
 
54
                                        sb.append(var.substring(0, 1).toLowerCase());
55
 
56
                                        sb.append(var.substring(1));
57
 
58
                                        var = sb.toString();
59
 
60
                                } else {
61
 
62
                                        var = var.toLowerCase();
63
                                }
64
 
65
                                m.setAccessible(true);
66
 
67
                                if (setters.containsKey(var)) {
68
 
69
                                        Object obj = setters.get(var);
70
 
71
                                        if (obj instanceof List) {
72
 
73
                                                List<Method> list = (List<Method>) obj;
74
 
75
                                                list.add(m);
76
 
77
                                        } else if (obj instanceof Method) {
78
 
79
                                                List<Method> list = new ArrayList<Method>();
80
 
81
                                                list.add((Method) obj);
82
 
83
                                                list.add(m);
84
 
85
                                                setters.put(var, list);
86
 
87
                                        }
88
 
89
                                } else {
90
 
91
                                        setters.put(var, m);
92
 
93
                                }
94
                        }
95
                }
96
 
97
                if (fields == null)
98
                        return;
99
 
100
                Field[] f = klass.getDeclaredFields();
101
 
102
                for (int i = 0; i < f.length; i++) {
103
 
104
                        Field field = f[i];
105
 
106
                        field.setAccessible(true);
107
 
108
                        String name = field.getName();
109
 
110
                        if (setters.containsKey(name)) {
111
 
112
                                Object obj = setters.get(name);
113
 
114
                                if (obj instanceof Method) {
115
 
116
                                        Method m = (Method) obj;
117
 
118
                                        Class[] types = m.getParameterTypes();
119
 
120
                                        Class type = field.getType();
121
 
122
                                        if (type.isAssignableFrom(types[0]))
123
                                                continue; // don't choose a field when we already have
124
                                                                        // a method...
125
 
126
                                } else if (obj instanceof List) {
127
 
128
                                        List<Method> list = (List<Method>) obj;
129
 
130
                                        Iterator<Method> iter = list.iterator();
131
 
132
                                        boolean found = false;
133
 
134
                                        while (iter.hasNext()) {
135
 
136
                                                Method m = iter.next();
137
 
138
                                                Class[] types = m.getParameterTypes();
139
 
140
                                                Class type = field.getType();
141
 
142
                                                if (type.isAssignableFrom(types[0])) {
143
 
144
                                                        found = true;
145
 
146
                                                        break;
147
                                                }
148
                                        }
149
 
150
                                        if (found)
151
                                                continue; // don't choose a field when we already have
152
                                                                        // a method...
153
 
154
                                }
155
                        }
156
 
157
                        fields.put(name, field);
158
 
159
                }
160
        }
161
 
162
        public static boolean checkPrimitives(Class target,
163
                        Class<? extends Object> source) {
164
 
165
                if (target.equals(int.class) && source.equals(Integer.class))
166
                        return true;
167
 
168
                if (target.equals(boolean.class) && source.equals(Boolean.class))
169
                        return true;
170
 
171
                if (target.equals(byte.class) && source.equals(Byte.class))
172
                        return true;
173
 
174
                if (target.equals(short.class) && source.equals(Short.class))
175
                        return true;
176
 
177
                if (target.equals(char.class) && source.equals(Character.class))
178
                        return true;
179
 
180
                if (target.equals(long.class) && source.equals(Long.class))
181
                        return true;
182
 
183
                if (target.equals(float.class) && source.equals(Float.class))
184
                        return true;
185
 
186
                if (target.equals(double.class) && source.equals(Double.class))
187
                        return true;
188
 
189
                return false;
190
 
191
        }
192
 
193
        public static Object tryToConvert(Object source, Class targetType,
194
                        Locale loc) {
195
 
196
                return tryToConvert(source, targetType, loc, false);
197
        }
198
 
199
        public static Object tryToConvert(Object source, Class targetType,
200
                        Locale loc, boolean tryNumber) {
201
 
202
                String value = null;
203
 
204
                if (source instanceof String) {
205
 
206
                        value = (String) source;
207
 
208
                } else if (tryNumber && source instanceof Number) {
209
 
210
                        value = source.toString();
211
 
212
                } else {
213
 
214
                        return null;
215
                }
216
 
217
                Object newValue = null;
218
 
219
                String className = targetType.getName();
220
 
221
                if (className.equals("int") || className.equals("java.lang.Integer")) {
222
                        int x = -1;
223
                        try {
224
                                x = Integer.parseInt(value);
225
                        } catch (Exception e) {
226
                                return null;
227
                        }
228
                        newValue = new Integer(x);
229
                } else if (className.equals("short")
230
                                || className.equals("java.lang.Short")) {
231
                        short x = -1;
232
                        try {
233
                                x = Short.parseShort(value);
234
                        } catch (Exception e) {
235
                                return null;
236
                        }
237
                        newValue = new Short(x);
238
 
239
                } else if (className.equals("char")
240
                                || className.equals("java.lang.Character")) {
241
 
242
                        if (value.length() != 1) {
243
                                return null;
244
                        }
245
 
246
                        newValue = new Character(value.charAt(0));
247
 
248
                } else if (className.equals("long")
249
                                || className.equals("java.lang.Long")) {
250
                        long x = -1;
251
                        try {
252
                                x = Long.parseLong(value);
253
                        } catch (Exception e) {
254
                                return null;
255
                        }
256
                        newValue = new Long(x);
257
                } else if (className.equals("float")
258
                                || className.equals("java.lang.Float")) {
259
                        float x = -1;
260
                        try {
261
                                x = Float.parseFloat(value);
262
                        } catch (Exception e) {
263
                                return null;
264
                        }
265
                        newValue = new Float(x);
266
                } else if (className.equals("double")
267
                                || className.equals("java.lang.Double")) {
268
                        double x = -1;
269
                        try {
270
                                x = Double.parseDouble(value);
271
                        } catch (Exception e) {
272
                                return null;
273
                        }
274
                        newValue = new Double(x);
275
                } else if (className.equals("boolean")
276
                                || className.equals("java.lang.Boolean")) {
277
                        try {
278
                                int x = Integer.parseInt(value);
279
                                if (x == 1) {
280
                                        newValue = Boolean.TRUE;
281
                                } else if (x == 0) {
282
                                        newValue = Boolean.FALSE;
283
                                } else {
284
                                        return null;
285
                                }
286
                        } catch (Exception e) {
287
                                if (value.equalsIgnoreCase("true") || value.equals("on")) {
288
                                        newValue = Boolean.TRUE;
289
                                } else if (value.equalsIgnoreCase("false")) {
290
                                        newValue = Boolean.FALSE;
291
                                } else {
292
                                        return null;
293
                                }
294
                        }
295
                } else if (className.equals("java.util.Date") && loc != null) {
296
                        DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, loc); // change
297
                        // this.
298
                        df.setLenient(false);
299
                        try {
300
                                newValue = df.parse(value);
301
                        } catch (Exception e) {
302
                                return null;
303
                        }
304
                } else if (targetType.isEnum()) {
305
 
306
                        try {
307
 
308
                                newValue = Enum.valueOf(targetType, value);
309
 
310
                        } catch (Exception e) {
311
 
312
                                return null;
313
                        }
314
 
315
                }
316
 
317
                return newValue;
318
 
319
        }
320
 
321
        public static Object shouldConvertToNull(Object value,
322
                        Class<? extends Object> targetType) {
323
 
324
                if (targetType.equals(String.class)) {
325
 
326
                        return value;
327
 
328
                } else if (targetType.isPrimitive()) {
329
 
330
                        return value;
331
                }
332
 
333
                return null;
334
        }
335
 
336
        public static Class getPrimitiveFrom(Object w) {
337
                if (w instanceof Boolean) {
338
                        return Boolean.TYPE;
339
                } else if (w instanceof Byte) {
340
                        return Byte.TYPE;
341
                } else if (w instanceof Short) {
342
                        return Short.TYPE;
343
                } else if (w instanceof Character) {
344
                        return Character.TYPE;
345
                } else if (w instanceof Integer) {
346
                        return Integer.TYPE;
347
                } else if (w instanceof Long) {
348
                        return Long.TYPE;
349
                } else if (w instanceof Float) {
350
                        return Float.TYPE;
351
                } else if (w instanceof Double) {
352
                        return Double.TYPE;
353
                }
354
                return null;
355
        }
356
 
357
        public static Class getPrimitiveFrom(Class klass) {
358
 
359
                String s = klass.getName();
360
 
361
                if (s.equals("java.lang.Boolean")) {
362
                        return Boolean.TYPE;
363
                } else if (s.equals("java.lang.Byte")) {
364
                        return Byte.TYPE;
365
                } else if (s.equals("java.lang.Short")) {
366
                        return Short.TYPE;
367
                } else if (s.equals("java.lang.Character")) {
368
                        return Character.TYPE;
369
                } else if (s.equals("java.lang.Integer")) {
370
                        return Integer.TYPE;
371
                } else if (s.equals("java.lang.Long")) {
372
                        return Long.TYPE;
373
                } else if (s.equals("java.lang.Float")) {
374
                        return Float.TYPE;
375
                } else if (s.equals("java.lang.Double")) {
376
                        return Double.TYPE;
377
                }
378
                return null;
379
        }
380
 
381
        public static Field getField(Object target, String name) {
382
                return getField(target.getClass(), name);
383
        }
384
 
385
        public static Field getField(Class<? extends Object> target, String name) {
386
                Field fields[] = target.getDeclaredFields();
387
                for (int i = 0; i < fields.length; i++) {
388
                        if (name.equals(fields[i].getName())) {
389
                                return fields[i];
390
                        }
391
                }
392
                return null;
393
        }
394
 
395
        public static Method findMethodToGet(Class<? extends Object> target,
396
                        String name) {
397
 
398
                StringBuffer sb = new StringBuffer(128);
399
 
400
                sb.append("get").append(name.substring(0, 1).toUpperCase());
401
 
402
                if (name.length() > 1)
403
                        sb.append(name.substring(1));
404
 
405
                try {
406
 
407
                        return target.getMethod(sb.toString(), (Class[]) null);
408
 
409
                } catch (Exception e) {
410
 
411
                }
412
 
413
                sb.setLength(0);
414
 
415
                sb.append("is").append(name.substring(0, 1).toUpperCase());
416
 
417
                if (name.length() > 1) {
418
 
419
                        sb.append(name.substring(1));
420
                }
421
 
422
                try {
423
 
424
                        return target.getMethod(sb.toString(), (Class[]) null);
425
 
426
                } catch (Exception e) {
427
 
428
                }
429
 
430
                return null;
431
        }
432
 
433
        public static Method findMethodToInject(Class<? extends Object> target,
434
                        String name, Class source) {
435
 
436
                StringBuffer sb = new StringBuffer(128);
437
 
438
                sb.append("set").append(name.substring(0, 1).toUpperCase());
439
 
440
                if (name.length() > 1)
441
                        sb.append(name.substring(1));
442
 
443
                String methodName = sb.toString();
444
 
445
                Method m = null;
446
 
447
                try {
448
 
449
                        m = FindMethod
450
                                        .getMethod(target, methodName, new Class[] { source });
451
 
452
                } catch (Exception e) {
453
                }
454
 
455
                if (m == null) {
456
 
457
                        Class primitive = getPrimitiveFrom(source);
458
 
459
                        if (primitive != null) {
460
 
461
                                try {
462
 
463
                                        m = target.getMethod(methodName, new Class[] { primitive });
464
 
465
                                } catch (Exception e) {
466
                                }
467
 
468
                        }
469
                }
470
 
471
                if (m != null) {
472
                        m.setAccessible(true);
473
                }
474
 
475
                return m;
476
 
477
        }
478
 
479
        public static Field findFieldToInject(Class<? extends Object> target,
480
                        String name, Class<? extends Object> source) {
481
 
482
                Field f = getField(target, name);
483
 
484
                if (f != null) {
485
 
486
                        Class<?> type = f.getType();
487
 
488
                        if (type.isAssignableFrom(source) || checkPrimitives(type, source)) {
489
 
490
                                f.setAccessible(true);
491
 
492
                                return f;
493
                        }
494
 
495
                }
496
 
497
                return null;
498
        }
499
 
500
        private static final boolean isBlank(Object value) {
501
 
502
                if (value != null && value instanceof String) {
503
 
504
                        String s = ((String) value).trim();
505
 
506
                        if (s.length() == 0)
507
                                return true;
508
                }
509
 
510
                return false;
511
        }
512
 
513
        public static boolean inject(Method m, Object target, Object value,
514
                        Locale loc, boolean tryToConvert, boolean tryingToConvertBoolean)
515
                        throws Exception {
516
 
517
                Class<?> type = m.getParameterTypes()[0];
518
 
519
                if (tryingToConvertBoolean) {
520
 
521
                        if (value == null && (type.equals(Boolean.class) || type.equals(boolean.class))) {
522
 
523
                                value = Boolean.FALSE;
524
 
525
                        } else {
526
 
527
                                // if trying to convert boolean, convert or don't do anything...
528
 
529
                                return false;
530
 
531
                        }
532
                }
533
 
534
                if (value == null
535
                                || (type.isAssignableFrom(value.getClass())
536
                                                || checkPrimitives(type, value.getClass()) || (tryToConvert && ((isBlank(value) && (value = shouldConvertToNull(
537
                                                value, type)) == null) || (value = tryToConvert(value,
538
                                                type, loc)) != null)))) {
539
 
540
                        try {
541
 
542
                                m.invoke(target, new Object[] { value });
543
 
544
                                return true;
545
 
546
                        } catch (Exception e) {
547
 
548
                                System.err.println("Error injecting by method: " + value
549
                                                + " in " + target + " thru " + m);
550
 
551
                                e.printStackTrace();
552
 
553
                                throw e;
554
 
555
                        }
556
                }
557
 
558
                return false;
559
 
560
        }
561
 
562
        public static boolean hasDefaultConstructor(Class<? extends Object> klass) {
563
 
564
                try {
565
 
566
                        return klass.getConstructor((Class[]) null) != null;
567
 
568
                } catch (Exception e) {
569
 
570
                        return false;
571
                }
572
        }
573
 
574
        /*
575
         * This method takes setUsername and returns username.
576
         *
577
         * If we have a prefix, then it returns prefix.username.
578
         */
579
        private static String adjustName(String name, String prefix) {
580
 
581
                StringBuilder sb;
582
 
583
                if (name.length() >= 4
584
                                && (name.startsWith("get") || name.startsWith("set"))) {
585
 
586
                        sb = new StringBuilder(name.length() - 3);
587
                        sb.append(name.substring(3, 4).toLowerCase());
588
                        if (name.length() > 4)
589
                                sb.append(name.substring(4, name.length()));
590
 
591
                } else if (name.length() >= 3 && name.startsWith("is")) {
592
 
593
                        sb = new StringBuilder(name.length() - 2);
594
                        sb.append(name.substring(2, 3).toLowerCase());
595
                        if (name.length() > 3)
596
                                sb.append(name.substring(3, name.length()));
597
 
598
                } else {
599
 
600
                        throw new IllegalArgumentException("Cannot adjust method: " + name);
601
                }
602
 
603
                if (prefix != null) {
604
 
605
                        StringBuffer sb2 = new StringBuffer(128);
606
 
607
                        return sb2.append(prefix).append(PREFIX_SEPARATOR).append(
608
                                        sb.toString()).toString();
609
 
610
                }
611
 
612
                return sb.toString();
613
        }
614
 
615
        /**
616
         * Extract the value of a property of a bean!
617
         *
618
         * @param bean
619
         *            the target bean
620
         * @param nameProperty
621
         *            the property name
622
         * @return they value as String. The method toString is always called to
623
         *         every property!
624
         * @throws Exception
625
         */
626
        public static String getProperty(Object bean, String nameProperty)
627
                        throws Exception {
628
 
629
                if (nameProperty == null || nameProperty.equals(""))
630
                        return null;
631
 
632
                String methodName = getter(nameProperty);
633
 
634
                Class<? extends Object> clazz = bean.getClass();
635
                Method[] methods = clazz.getMethods();
636
                for (Method method : methods) {
637
                        if (method.getName().equals(methodName)
638
                                        && method.getParameterTypes().length == 0) {
639
                                Object value = method.invoke(bean, (Object[]) null);
640
                                if (value == null)
641
                                        return null;
642
                                return value.toString();
643
                        }
644
                }
645
 
646
                Field[] fields = clazz.getDeclaredFields();
647
                for (Field field : fields) {
648
                        field.setAccessible(true);
649
                        if (field.getName().equals(nameProperty)) {
650
                                Object value = field.get(bean);
651
                                if (value == null)
652
                                        return null;
653
                                return value.toString();
654
                        }
655
                }
656
 
657
                return null;
658
        }
659
 
660
        private static String getter(String name) {
661
                StringBuilder sb = new StringBuilder(name.length() + 3);
662
 
663
                sb.append("get").append(name.substring(0, 1).toUpperCase());
664
 
665
                if (name.length() > 1)
666
                        sb.append(name.substring(1));
667
                return sb.toString();
668
        }
669
 
670
        public static void beanToMap(Object bean, Map<String, String> map)
671
                        throws IllegalArgumentException, IllegalAccessException,
672
                        InvocationTargetException {
673
                if (bean != null) {
674
 
675
                        for (Method method : bean.getClass().getMethods()) {
676
                                String name = method.getName();
677
 
678
                                if (name.length() > 3 && name.startsWith("get")
679
                                                && !name.equals("getClass")
680
                                                && method.getParameterTypes().length == 0) {
681
 
682
                                        method.setAccessible(true);
683
                                        Object value = method.invoke(bean, new Object[0]);
684
                                        map.put(name, value.toString());
685
                                }
686
                        }
687
                }
688
        }
689
 
690
}