MentaContainer

Rev

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