MentaContainer

Rev

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