MentaContainer

Rev

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

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