MentaContainer

Rev

Rev 45 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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