MentaContainer

Rev

Details | 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
 
11
import org.mentacontainer.util.FindMethod;
12
 
13
class Component {
14
 
15
            private Class<? extends Object> klass;
16
 
17
            private Map<String, Object> props = null;
18
 
19
            private List<Object> initValues = null;
20
 
21
            private Constructor<? extends Object> constructor = null;
22
 
23
            private Map<String, Method> cache = null;
24
 
25
            private final boolean singleton;
26
 
27
            public Component(Class<? extends Object> klass, boolean singleton) {
28
 
29
                this.klass = klass;
30
 
31
                this.singleton = singleton;
32
            }
33
 
34
            public boolean isSingleton() { return singleton; }
35
 
36
            public void addProperty(String name, Object value) {
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);
46
            }
47
 
48
            public void addInitValue(Object value) {
49
 
50
                if (initValues == null) {
51
 
52
                    initValues = new LinkedList<Object>();
53
                }
54
 
55
                initValues.add(value);
56
            }
57
 
58
            private Class<? extends Object>[] getClasses(List<Object> values) {
59
 
60
                Class<? extends Object>[] types = (Class<? extends Object>[]) new Class[values.size()];
61
 
62
                Iterator<Object> iter = values.iterator();
63
 
64
                int index = 0;
65
 
66
                while(iter.hasNext()) {
67
 
68
                    Object value = iter.next();
69
 
70
                    if (value != null) {
71
 
72
                        types[index++] = value.getClass();
73
 
74
                    } else {
75
 
76
                        types[index++] = null;
77
                    }
78
                }
79
 
80
                return types;
81
            }
82
 
83
            private Object [] getValues(List<Object> values) throws InstantiationException {
84
 
85
                Object [] array = new Object[values.size()];
86
 
87
                int index = 0;
88
 
89
                Iterator<Object> iter = values.iterator();
90
 
91
                while(iter.hasNext()) {
92
 
93
                        Object obj = iter.next();
94
 
95
                        array[index++] = obj;
96
                }
97
 
98
                return array;
99
            }
100
 
101
                /*
102
                 * Use reflection to set a property in the bean
103
                 */
104
                private void setValue(Object bean, String name, Object value) throws InstantiationException {
105
 
106
                        try {
107
                                StringBuffer sb = new StringBuffer(30);
108
                                sb.append("set");
109
                                sb.append(name.substring(0,1).toUpperCase());
110
                                if (name.length() > 1) sb.append(name.substring(1));
111
 
112
                    String methodName = sb.toString();
113
 
114
                    if (!cache.containsKey(name)) {
115
                        Method m = null;
116
                        try {
117
                            m = FindMethod.getMethod(klass, methodName, new Class[] { value.getClass() });
118
                        } catch(Exception e) {
119
                            // try primitive...
120
                            Class<? extends Object> primitive = getPrimitiveFrom(value);
121
                            if (primitive != null) {
122
                                try {
123
                                    m = klass.getMethod(methodName, new Class[] { primitive });
124
                                } catch(Exception ex) {
125
                                        // not found!
126
                                }
127
                            }
128
 
129
                            if (m == null) {
130
                                throw new InstantiationException("Cannot find method or field for property: " + name);
131
                            }
132
                        }
133
 
134
                        if (m != null) {
135
                            cache.put(name, m);
136
                            m.setAccessible(true);
137
                        }
138
                    }    
139
 
140
                    Method m = cache.get(name);
141
                    if (m != null) {
142
                        m.invoke(bean, new Object[] { value });
143
                    }                
144
                        } catch(Exception e) {
145
                                throw new InstantiationException("Error trying to set a property with reflection: " + name);
146
                        }
147
                }
148
 
149
            private static Class<? extends Object> getPrimitiveFrom(Object w) {
150
                if (w instanceof Boolean) { return Boolean.TYPE; }
151
                else if (w instanceof Byte) { return Byte.TYPE; }
152
                else if (w instanceof Short) { return Short.TYPE; }
153
                else if (w instanceof Character) { return Character.TYPE; }
154
                else if (w instanceof Integer) { return Integer.TYPE; }
155
                else if (w instanceof Long) { return Long.TYPE; }
156
                else if (w instanceof Float) { return Float.TYPE; }
157
                else if (w instanceof Double) { return Double.TYPE; }
158
                return null;
159
            }  
160
 
161
            public Object getInstance() throws InstantiationException {
162
                Object obj = null;
163
                if (initValues != null && initValues.size() > 0) {
164
                    if (constructor == null) {
165
                        try {
166
                            constructor = klass.getConstructor(getClasses(initValues));
167
                        } catch(Exception e) {
168
                            throw new InstantiationException("Cannot find a constructor for class: " + klass);
169
                        }
170
                    }
171
                    try {
172
                        obj = constructor.newInstance(getValues(initValues));
173
                    } catch(Exception e) {
174
                        throw new InstantiationException("Cannot create instance from constructor: " + constructor);
175
                    }
176
                } else {
177
                    try {
178
                        obj = klass.newInstance();
179
                    } catch(Exception e) {
180
                        throw new InstantiationException("Cannot create instance from class: " + klass);
181
                    }
182
                }
183
                if (props != null && props.size() > 0) {
184
                    Iterator<String> iter = props.keySet().iterator();
185
                    while(iter.hasNext()) {
186
                        String name = iter.next();
187
                        Object value = props.get(name);
188
                        setValue(obj, name, value);
189
                    }
190
                }
191
                return obj;
192
            }
193
        }