MentaContainer

Rev

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