MentaContainer

Rev

Rev 44 | Rev 51 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 44 Rev 45
1
package org.mentacontainer.impl;
1
package org.mentacontainer.impl;
2
2
3
import java.lang.reflect.Method;
3
import java.lang.reflect.Method;
4
import java.util.HashMap;
4
import java.util.HashMap;
5
import java.util.HashSet;
5
import java.util.HashSet;
6
import java.util.Map;
6
import java.util.Map;
7
import java.util.Set;
7
import java.util.Set;
8
8
9
import org.mentacontainer.Component;
9
import org.mentacontainer.Component;
-
 
10
import org.mentacontainer.ConfigurableComponent;
10
import org.mentacontainer.Container;
11
import org.mentacontainer.Container;
11
import org.mentacontainer.Dependency;
12
import org.mentacontainer.Dependency;
12
import org.mentacontainer.util.InjectionUtils;
13
import org.mentacontainer.util.InjectionUtils;
13
import org.mentacontainer.util.InjectionUtils.Provider;
14
import org.mentacontainer.util.InjectionUtils.Provider;
14
15
15
/**
16
/**
16
 * The implementation of the IoC container.
17
 * The implementation of the IoC container.
17
 *
18
 *
18
 * @author sergio.oliveira.jr@gmail.com
19
 * @author sergio.oliveira.jr@gmail.com
19
 */
20
 */
20
public class MentaContainer implements Container {
21
public class MentaContainer implements Container {
21
22
22
        private Map<String, Component> beans = new HashMap<String, Component>();
23
        private Map<String, Component> beans = new HashMap<String, Component>();
23
24
24
        private Map<String, Object> singletons = new HashMap<String, Object>();
25
        private Map<String, Object> singletons = new HashMap<String, Object>();
25
26
26
        private Set<Dependency> dependencies = new HashSet<Dependency>();
27
        private Set<Dependency> dependencies = new HashSet<Dependency>();
27
28
28
        public <T> T get(String key) {
29
        public <T> T get(String key) {
29
30
30
                if (!beans.containsKey(key)) return null;
31
                if (!beans.containsKey(key)) return null;
31
32
32
                Component c = beans.get(key);
33
                Component c = beans.get(key);
33
34
34
                Object target = null;
35
                Object target = null;
35
36
36
                try {
37
                try {
37
38
38
                        if (c.isSingleton()) {
39
                        if (c.isSingleton()) {
39
40
40
                                if (singletons.containsKey(key)) {
41
                                if (singletons.containsKey(key)) {
41
42
42
                                        target = singletons.get(key);
43
                                        target = singletons.get(key);
43
44
44
                                        return (T) target;
45
                                        return (T) target;
45
46
46
                                } else {
47
                                } else {
47
48
48
                                        target = c.getInstance();
49
                                        target = c.getInstance();
49
50
50
                                        singletons.put(key, target);
51
                                        singletons.put(key, target);
51
                                }
52
                                }
52
53
53
                        } else {
54
                        } else {
54
55
55
                                target = c.getInstance();
56
                                target = c.getInstance();
56
57
57
                        }
58
                        }
58
59
59
                        if (target != null) {
60
                        if (target != null) {
60
61
61
                                for (Dependency d : dependencies) {
62
                                for (Dependency d : dependencies) {
62
63
63
                                        // has dependency ?
64
                                        // has dependency ?
64
                                        Method m = d.check(target.getClass());
65
                                        Method m = d.check(target.getClass());
65
66
66
                                        if (m != null) {
67
                                        if (m != null) {
67
68
68
                                                String sourceKey = d.getSource();
69
                                                String sourceKey = d.getSource();
69
70
70
                                                if (sourceKey.equals(key)) {
71
                                                if (sourceKey.equals(key)) {
71
72
72
                                                        // cannot depend on itself... also avoid recursive StackOverflow...
73
                                                        // cannot depend on itself... also avoid recursive StackOverflow...
73
74
74
                                                        continue;
75
                                                        continue;
75
76
76
                                                }
77
                                                }
77
78
78
                                                Object source = get(sourceKey);
79
                                                Object source = get(sourceKey);
79
80
80
                                                boolean isAssignable = source != null && d.getType().isAssignableFrom(source.getClass());
81
                                                boolean isAssignable = source != null && d.getType().isAssignableFrom(source.getClass());
81
82
82
                                                // check if we can find the dependency and if it is
83
                                                // check if we can find the dependency and if it is
83
                                                // assignable to the target dependency
84
                                                // assignable to the target dependency
84
                                                if (isAssignable) {
85
                                                if (isAssignable) {
85
86
86
                                                        try {
87
                                                        try {
87
88
88
                                                                // inject
89
                                                                // inject
89
                                                                m.invoke(target, source);
90
                                                                m.invoke(target, source);
90
91
91
                                                        } catch (Exception e) {
92
                                                        } catch (Exception e) {
92
93
93
                                                                throw new RuntimeException("Cannot inject dependency: method = " + (m != null ? m.getName() : "NULL") + " / source = "
94
                                                                throw new RuntimeException("Cannot inject dependency: method = " + (m != null ? m.getName() : "NULL") + " / source = "
94
                                                                        + (source != null ? source : "NULL") + " / target = " + target, e);
95
                                                                        + (source != null ? source : "NULL") + " / target = " + target, e);
95
96
96
                                                        }
97
                                                        }
97
98
98
                                                }
99
                                                }
99
                                        }
100
                                        }
100
                                }
101
                                }
101
                        }
102
                        }
102
103
103
                        return (T) target; // return target nicely with all the dependencies
104
                        return (T) target; // return target nicely with all the dependencies
104
105
105
                } catch (Exception e) {
106
                } catch (Exception e) {
106
107
107
                        throw new RuntimeException(e);
108
                        throw new RuntimeException(e);
108
                }
109
                }
109
        }
110
        }
110
111
111
        public Component ioc(String key, Component component) {
112
        public Component ioc(String key, Component component) {
112
               
113
               
113
                beans.put(key, component);
114
                beans.put(key, component);
114
               
115
               
115
                // clear the singleton cache in case of adding again...
116
                // clear the singleton cache in case of adding again...
116
                singletons.remove(key);
117
                singletons.remove(key);
117
118
118
                return component;
119
                return component;
119
        }
120
        }
120
       
121
       
121
        public Component ioc(String key, Class<? extends Object> klass) {
-
 
-
 
122
        public ConfigurableComponent ioc(String key, Class<? extends Object> klass) {
122
               
123
               
123
                return ioc(key, new MentaComponent(klass));
-
 
-
 
124
                ConfigurableComponent cc = new MentaComponent(klass);
-
 
125
               
-
 
126
                ioc(key, cc);
-
 
127
               
-
 
128
                return cc;
124
        }
129
        }
125
       
130
       
126
        public Component ioc(String key, Class<? extends Object> klass, boolean singleton) {
-
 
-
 
131
        public ConfigurableComponent ioc(String key, Class<? extends Object> klass, boolean singleton) {
-
 
132
               
-
 
133
                ConfigurableComponent cc = new MentaComponent(klass, singleton);
-
 
134
               
-
 
135
                ioc(key, cc);
127
               
136
               
128
                return ioc(key, new MentaComponent(klass, singleton));
-
 
-
 
137
                return cc;
129
        }
138
        }
130
139
131
        public Dependency autowire(Dependency d) {
140
        public Dependency autowire(Dependency d) {
132
141
133
                dependencies.add(d);
142
                dependencies.add(d);
134
143
135
                return d;
144
                return d;
136
        }
145
        }
137
146
138
        public Dependency autowire(String property, Class<? extends Object> klass) {
147
        public Dependency autowire(String property, Class<? extends Object> klass) {
139
               
148
               
140
                return autowire(property, klass, property);
149
                return autowire(property, klass, property);
141
        }
150
        }
142
       
151
       
143
        public Dependency autowire(String property, Class<? extends Object> klass, String source) {
152
        public Dependency autowire(String property, Class<? extends Object> klass, String source) {
144
               
153
               
145
                return autowire(new MentaDependency(property, klass, source));
154
                return autowire(new MentaDependency(property, klass, source));
146
        }
155
        }
147
156
148
        public Container populate(Object bean) {
157
        public Container populate(Object bean) {
149
               
158
               
150
                Provider p = new Provider() {
159
                Provider p = new Provider() {
151
                       
160
                       
152
                        public Object get(String key) {
161
                        public Object get(String key) {
153
                               
162
                               
154
                                return MentaContainer.this.get(key);
163
                                return MentaContainer.this.get(key);
155
                        }
164
                        }
156
                       
165
                       
157
                        public boolean contains(String key) {
166
                        public boolean contains(String key) {
158
                               
167
                               
159
                                return MentaContainer.this.contains(key);
168
                                return MentaContainer.this.contains(key);
160
                        }
169
                        }
161
                       
170
                       
162
                };
171
                };
163
               
172
               
164
                try {
173
                try {
165
174
166
                        InjectionUtils.getObject(bean, p, false, null, true, false, true);
175
                        InjectionUtils.getObject(bean, p, false, null, true, false, true);
167
                       
176
                       
168
                } catch(Exception e) {
177
                } catch(Exception e) {
169
                       
178
                       
170
                        throw new RuntimeException("Error populating bean: " + bean, e);
179
                        throw new RuntimeException("Error populating bean: " + bean, e);
171
                }
180
                }
172
181
173
                return this;
182
                return this;
174
        }
183
        }
175
184
176
        public boolean contains(String key) {
185
        public boolean contains(String key) {
177
186
178
                return beans.containsKey(key);
187
                return beans.containsKey(key);
179
        }
188
        }
180
}
189
}