MentaContainer

Rev

Rev 45 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 soliveira 1
package org.mentacontainer.impl;
2
 
3
import java.lang.reflect.Constructor;
4
import java.lang.reflect.Method;
5
import java.util.HashMap;
6
import java.util.Iterator;
7
import java.util.LinkedList;
8
import java.util.List;
9
import java.util.Map;
10
 
45 soliveira 11
import org.mentacontainer.ConfigurableComponent;
2 soliveira 12
import org.mentacontainer.util.FindMethod;
13
 
20 soliveira 14
/**
15
 * A simple implementation of the Component interface.
16
 *
17
 * @author sergio.oliveira.jr@gmail.com
18
 */
45 soliveira 19
public class MentaComponent implements ConfigurableComponent {
20 soliveira 20
 
21
            private final Class<? extends Object> klass;
2 soliveira 22
 
23
            private Map<String, Object> props = null;
24
 
25
            private List<Object> initValues = null;
26
 
27
            private Constructor<? extends Object> constructor = null;
28
 
29
            private Map<String, Method> cache = null;
30
 
51 soliveira 31
            public MentaComponent(Class<? extends Object> klass) {
20 soliveira 32
 
2 soliveira 33
                this.klass = klass;
34
            }
35
 
45 soliveira 36
            public ConfigurableComponent addProperty(String name, Object value) {
2 soliveira 37
 
38
                if (props == null) {
39
 
40
                    props = new HashMap<String, Object>();
41
 
42
                    cache = new HashMap<String, Method>();
43
                }
44
 
45
                props.put(name, value);
20 soliveira 46
 
47
                return this;
2 soliveira 48
            }
49
 
45 soliveira 50
            public ConfigurableComponent addInitValue(Object value) {
2 soliveira 51
 
52
                if (initValues == null) {
53
 
54
                    initValues = new LinkedList<Object>();
55
                }
56
 
57
                initValues.add(value);
20 soliveira 58
 
59
                return this;
2 soliveira 60
            }
61
 
62
            private Class<? extends Object>[] getClasses(List<Object> values) {
63
 
64
                Class<? extends Object>[] types = (Class<? extends Object>[]) new Class[values.size()];
65
 
66
                Iterator<Object> iter = values.iterator();
67
 
68
                int index = 0;
69
 
70
                while(iter.hasNext()) {
71
 
72
                    Object value = iter.next();
73
 
74
                    if (value != null) {
75
 
76
                        types[index++] = value.getClass();
77
 
78
                    } else {
79
 
80
                        types[index++] = null;
81
                    }
82
                }
83
 
84
                return types;
85
            }
86
 
87
            private Object [] getValues(List<Object> values) throws InstantiationException {
88
 
89
                Object [] array = new Object[values.size()];
90
 
91
                int index = 0;
92
 
93
                Iterator<Object> iter = values.iterator();
94
 
95
                while(iter.hasNext()) {
96
 
97
                        Object obj = iter.next();
98
 
99
                        array[index++] = obj;
100
                }
101
 
102
                return array;
103
            }
104
 
105
                /*
106
                 * Use reflection to set a property in the bean
107
                 */
40 soliveira 108
                private void setValue(Object bean, String name, Object value) {
2 soliveira 109
 
110
                        try {
20 soliveira 111
 
2 soliveira 112
                                StringBuffer sb = new StringBuffer(30);
113
                                sb.append("set");
114
                                sb.append(name.substring(0,1).toUpperCase());
20 soliveira 115
 
2 soliveira 116
                                if (name.length() > 1) sb.append(name.substring(1));
117
 
118
                    String methodName = sb.toString();
119
 
120
                    if (!cache.containsKey(name)) {
20 soliveira 121
 
2 soliveira 122
                        Method m = null;
20 soliveira 123
 
2 soliveira 124
                        try {
20 soliveira 125
 
2 soliveira 126
                            m = FindMethod.getMethod(klass, methodName, new Class[] { value.getClass() });
20 soliveira 127
 
2 soliveira 128
                        } catch(Exception e) {
20 soliveira 129
 
2 soliveira 130
                            // try primitive...
20 soliveira 131
 
2 soliveira 132
                            Class<? extends Object> primitive = getPrimitiveFrom(value);
20 soliveira 133
 
2 soliveira 134
                            if (primitive != null) {
20 soliveira 135
 
2 soliveira 136
                                try {
20 soliveira 137
 
2 soliveira 138
                                    m = klass.getMethod(methodName, new Class[] { primitive });
20 soliveira 139
 
2 soliveira 140
                                } catch(Exception ex) {
141
                                        // not found!
142
                                }
143
                            }
144
 
145
                            if (m == null) {
20 soliveira 146
 
2 soliveira 147
                                throw new InstantiationException("Cannot find method or field for property: " + name);
148
                            }
149
                        }
150
 
151
                        if (m != null) {
20 soliveira 152
 
2 soliveira 153
                            cache.put(name, m);
20 soliveira 154
 
2 soliveira 155
                            m.setAccessible(true);
156
                        }
157
                    }    
158
 
159
                    Method m = cache.get(name);
20 soliveira 160
 
2 soliveira 161
                    if (m != null) {
20 soliveira 162
 
2 soliveira 163
                        m.invoke(bean, new Object[] { value });
164
                    }                
20 soliveira 165
 
2 soliveira 166
                        } catch(Exception e) {
20 soliveira 167
 
40 soliveira 168
                                throw new RuntimeException("Error trying to set a property with reflection: " + name, e);
2 soliveira 169
                        }
170
                }
171
 
172
            private static Class<? extends Object> getPrimitiveFrom(Object w) {
173
                if (w instanceof Boolean) { return Boolean.TYPE; }
174
                else if (w instanceof Byte) { return Byte.TYPE; }
175
                else if (w instanceof Short) { return Short.TYPE; }
176
                else if (w instanceof Character) { return Character.TYPE; }
177
                else if (w instanceof Integer) { return Integer.TYPE; }
178
                else if (w instanceof Long) { return Long.TYPE; }
179
                else if (w instanceof Float) { return Float.TYPE; }
180
                else if (w instanceof Double) { return Double.TYPE; }
181
                return null;
182
            }  
183
 
41 soliveira 184
            public <T> T getInstance()  {
20 soliveira 185
 
2 soliveira 186
                Object obj = null;
20 soliveira 187
 
2 soliveira 188
                if (initValues != null && initValues.size() > 0) {
20 soliveira 189
 
2 soliveira 190
                    if (constructor == null) {
20 soliveira 191
 
2 soliveira 192
                        try {
20 soliveira 193
 
2 soliveira 194
                            constructor = klass.getConstructor(getClasses(initValues));
20 soliveira 195
 
2 soliveira 196
                        } catch(Exception e) {
20 soliveira 197
 
40 soliveira 198
                            throw new RuntimeException("Cannot find a constructor for class: " + klass, e);
2 soliveira 199
                        }
200
                    }
20 soliveira 201
 
2 soliveira 202
                    try {
20 soliveira 203
 
2 soliveira 204
                        obj = constructor.newInstance(getValues(initValues));
20 soliveira 205
 
2 soliveira 206
                    } catch(Exception e) {
20 soliveira 207
 
40 soliveira 208
                        throw new RuntimeException("Cannot create instance from constructor: " + constructor, e);
2 soliveira 209
                    }
20 soliveira 210
 
2 soliveira 211
                } else {
20 soliveira 212
 
2 soliveira 213
                    try {
20 soliveira 214
 
2 soliveira 215
                        obj = klass.newInstance();
20 soliveira 216
 
2 soliveira 217
                    } catch(Exception e) {
20 soliveira 218
 
40 soliveira 219
                        throw new RuntimeException("Cannot create instance from class: " + klass, e);
2 soliveira 220
                    }
221
                }
20 soliveira 222
 
2 soliveira 223
                if (props != null && props.size() > 0) {
20 soliveira 224
 
2 soliveira 225
                    Iterator<String> iter = props.keySet().iterator();
20 soliveira 226
 
2 soliveira 227
                    while(iter.hasNext()) {
20 soliveira 228
 
2 soliveira 229
                        String name = iter.next();
20 soliveira 230
 
2 soliveira 231
                        Object value = props.get(name);
20 soliveira 232
 
2 soliveira 233
                        setValue(obj, name, value);
234
                    }
235
                }
20 soliveira 236
 
41 soliveira 237
                return (T) obj;
2 soliveira 238
            }
239
        }