MentaContainer

Rev

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