MentaContainer

Rev

Rev 4 | Go to most recent revision | 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.Method;
4
import java.util.HashMap;
5
import java.util.HashSet;
6
import java.util.Map;
7
import java.util.Set;
8
 
9
import org.mentacontainer.Container;
10
 
11
public class MentaContainer implements Container {
12
 
13
        private Map<String, Component> beans = new HashMap<String, Component>();
14
 
15
        private Map<String, Object> singletons = new HashMap<String, Object>();
16
 
17
        private Set<Dependency> dependencies = new HashSet<Dependency>();
18
 
19
        public Object get(String key) {
20
 
21
                if (!beans.containsKey(key)) throw new RuntimeException("Container does not have this bean set: " + key);
22
 
23
                Component c = beans.get(key);
24
 
25
                Object target = null;
26
 
27
                try {
28
 
29
                        if (c.isSingleton()) {
30
 
31
                                if (singletons.containsKey(key)) {
32
 
33
                                        target = singletons.get(key);
34
 
35
                                        return target;
36
 
37
                                } else {
38
 
39
                                        target = c.getInstance();
40
 
41
                                        singletons.put(key, target);
42
                                }
43
 
44
                        } else {
45
 
46
                                target = c.getInstance();
47
 
48
                        }
49
 
50
                        if (target != null) {
51
 
52
                                for(Dependency d : dependencies) {
53
 
54
                                    // has dependency ?
55
                                    Method m = d.getMethod(target.getClass());
56
 
57
                                    if (m != null) {
58
 
59
                                        boolean hasAlreadyReceived = d.hasAlreadyReceived(target);
60
 
61
                                        // has already received the dependency?
62
                                        if (!hasAlreadyReceived) {
63
 
64
                                                String sourceKey = d.getSource();
65
 
66
                                                // get dependency from action input
67
 
68
                                                if (sourceKey.equals(key)) {
69
 
70
                                                        // cannot depend on itself...
71
                                                        // also avoid recusive StackOverflow...
72
 
73
                                                        continue;
74
 
75
                                                }
76
 
77
                                                Object source = get(sourceKey);
78
 
79
                                                boolean isAssignable = source != null && d.getDependencyClass().isAssignableFrom(source.getClass());
80
 
81
 
82
                                            // check if we can find the dependency and if it is assignable to the target dependency
83
                                            if (isAssignable) {
84
 
85
                                                    try {
86
 
87
 
88
                                                        // inject
89
                                                        m.invoke(target, source);
90
 
91
                                                        // flag it has received
92
                                                        d.setAlreadyReceived(target);
93
 
94
 
95
                                                    } catch(Exception e) {
96
 
97
 
98
                                                        throw new RuntimeException("AutoWiringFilter cannot inject dependency: method = " + (m != null ? m.getName() : "NULL") + " / source = " + (source != null ? source : "NULL") + " / target = " + target, e);
99
 
100
                                                    }
101
 
102
                                            }
103
                                        }
104
                                    }
105
                                }
106
                        }
107
 
108
                        return target; // return target nicely with all the dependencies injected
109
 
110
 
111
 
112
 
113
 
114
                } catch(Exception e) {
115
 
116
                        throw new RuntimeException(e);
117
                }
118
        }
119
 
120
        public Container ioc(String key, Class<? extends Object> klass, boolean singleton) {
121
 
122
                if (beans.containsKey(key)) throw new RuntimeException("Container already set for the bean key: " + key);
123
 
124
                Component c = new Component(klass, singleton);
125
 
126
                beans.put(key, c);
127
 
128
                return this;
129
        }
130
 
131
        public Container ioc(String key, Class<? extends Object> klass) {
132
 
133
                return ioc(key, klass, false);
134
        }
135
 
136
        public Container autowire(String property, Class<? extends Object> klass, String source) {
137
 
138
                Dependency d = new Dependency(property, klass, source);
139
 
140
                if (dependencies.contains(d)) throw new RuntimeException("Dependency is already set: " + property);
141
 
142
                dependencies.add(d);
143
 
144
                return this;
145
        }
146
 
147
        public Container autowire(String property, Class<? extends Object> klass) {
148
                return autowire(property, klass, property);
149
        }
150
 
151
        public Container init(String key, Object value) {
152
 
153
                if (!beans.containsKey(key)) throw new RuntimeException("Container does not have this bean set: " + key);
154
 
155
                Component c = beans.get(key);
156
 
157
                c.addInitValue(value);
158
 
159
                return this;
160
        }
161
 
162
        public Container set(String key, String name, Object value) {
163
 
164
                if (!beans.containsKey(key)) throw new RuntimeException("Container does not have this bean set: " + key);
165
 
166
                Component c = beans.get(key);
167
 
168
                c.addProperty(name, value);
169
 
170
                return this;
171
        }
172
 
173
        public Container populate(Object bean) {
174
                // TODO Auto-generated method stub
175
                return null;
176
        }
177
}