MentaContainer

Compare Revisions

Ignore whitespace Rev 20 → Rev 19

/trunk/src/main/java/org/mentacontainer/impl/MentaContainer.java
6,156 → 6,166
import java.util.Map;
import java.util.Set;
 
import org.mentacontainer.Component;
import org.mentacontainer.Container;
import org.mentacontainer.Dependency;
import org.mentacontainer.util.InjectionUtils;
 
/**
* The implementation of the IoC container.
*
* @author sergio.oliveira.jr@gmail.com
*/
public class MentaContainer implements Container {
 
private Map<String, Component> beans = new HashMap<String, Component>();
private Map<String, Component> beans = new HashMap<String, Component>();
 
private Map<String, Object> singletons = new HashMap<String, Object>();
private Map<String, Object> singletons = new HashMap<String, Object>();
 
private Set<Dependency> dependencies = new HashSet<Dependency>();
private Set<Dependency> dependencies = new HashSet<Dependency>();
 
public Object get(String key) {
public Object get(String key) {
 
if (!beans.containsKey(key)) throw new RuntimeException("Container does not have this bean set: " + key);
if (!beans.containsKey(key)) throw new RuntimeException("Container does not have this bean set: " + key);
 
Component c = beans.get(key);
Component c = beans.get(key);
 
Object target = null;
Object target = null;
 
try {
try {
 
if (c.isSingleton()) {
if (c.isSingleton()) {
 
if (singletons.containsKey(key)) {
if (singletons.containsKey(key)) {
 
target = singletons.get(key);
target = singletons.get(key);
 
return target;
return target;
 
} else {
} else {
 
target = c.getInstance();
target = c.getInstance();
 
singletons.put(key, target);
}
singletons.put(key, target);
}
 
} else {
} else {
 
target = c.getInstance();
target = c.getInstance();
 
}
}
 
if (target != null) {
if (target != null) {
 
for (Dependency d : dependencies) {
for (Dependency d : dependencies) {
 
// has dependency ?
Method m = d.check(target.getClass());
// has dependency ?
Method m = d.getMethod(target.getClass());
 
if (m != null) {
if (m != null) {
 
String sourceKey = d.getSource();
String sourceKey = d.getSource();
 
if (sourceKey.equals(key)) {
if (sourceKey.equals(key)) {
 
// cannot depend on itself... also avoid recursive StackOverflow...
// cannot depend on itself...
// also avoid recursive StackOverflow...
 
continue;
continue;
 
}
}
 
Object source = get(sourceKey);
Object source = get(sourceKey);
 
boolean isAssignable = source != null && d.getType().isAssignableFrom(source.getClass());
boolean isAssignable = source != null && d.getDependencyClass().isAssignableFrom(source.getClass());
 
// check if we can find the dependency and if it is
// assignable to the target dependency
if (isAssignable) {
// check if we can find the dependency and if it is
// assignable to the target dependency
if (isAssignable) {
 
try {
try {
 
// inject
m.invoke(target, source);
// inject
m.invoke(target, source);
 
} catch (Exception e) {
} catch (Exception e) {
 
throw new RuntimeException("Cannot inject dependency: method = " + (m != null ? m.getName() : "NULL") + " / source = "
+ (source != null ? source : "NULL") + " / target = " + target, e);
throw new RuntimeException("Cannot inject dependency: method = " + (m != null ? m.getName() : "NULL") + " / source = "
+ (source != null ? source : "NULL") + " / target = " + target, e);
 
}
}
 
}
}
}
}
}
}
}
 
return target; // return target nicely with all the dependencies
return target; // return target nicely with all the dependencies
// injected
 
} catch (Exception e) {
} catch (Exception e) {
 
throw new RuntimeException(e);
}
throw new RuntimeException(e);
}
}
 
public Component ioc(Component component) {
String key = component.getName();
public Container ioc(String key, Class<? extends Object> klass, boolean singleton) {
 
if (beans.containsKey(key)) throw new RuntimeException("Container already set for the bean key: " + key);
if (beans.containsKey(key)) throw new RuntimeException("Container already set for the bean key: " + key);
 
beans.put(key, component);
Component c = new Component(klass, singleton);
 
return component;
}
public Component ioc(String key, Class<? extends Object> klass) {
return ioc(new MentaComponent(key, klass));
}
public Component ioc(String key, Class<? extends Object> klass, boolean singleton) {
return ioc(new MentaComponent(key, klass, singleton));
}
beans.put(key, c);
 
public Dependency autowire(Dependency d) {
return this;
}
 
if (dependencies.contains(d)) throw new RuntimeException("Dependency is already set: " + d.getTarget());
public Container ioc(String key, Class<? extends Object> klass) {
 
dependencies.add(d);
return ioc(key, klass, false);
}
 
return d;
}
public Container autowire(String property, Class<? extends Object> klass, String source) {
 
public Dependency autowire(String property, Class<? extends Object> klass) {
return autowire(property, klass, property);
}
Dependency d = new Dependency(property, klass, source);
 
if (dependencies.contains(d)) throw new RuntimeException("Dependency is already set: " + property);
public Dependency autowire(String property, Class<? extends Object> klass, String source) {
return autowire(new MentaDependency(property, klass, source));
}
if (!klass.isInterface()) throw new RuntimeException("Dependency must be an interface!");
 
public Container populate(Object bean) throws Exception {
dependencies.add(d);
 
InjectionUtils.getObject(bean, this, false, null, true, false, true);
return this;
}
 
return this;
}
public Container autowire(String property, Class<? extends Object> klass) {
return autowire(property, klass, property);
}
 
public boolean contains(String key) {
public Container init(String key, Object value) {
 
return beans.containsKey(key);
}
if (!beans.containsKey(key)) throw new RuntimeException("Container does not have this bean set: " + key);
 
Component c = beans.get(key);
 
c.addInitValue(value);
 
return this;
}
 
public Container set(String key, String name, Object value) {
 
if (!beans.containsKey(key)) throw new RuntimeException("Container does not have this bean set: " + key);
 
Component c = beans.get(key);
 
c.addProperty(name, value);
 
return this;
}
 
public Container populate(Object bean) throws Exception {
 
InjectionUtils.getObject(bean, this, false, null, true, false, true);
return this;
}
public boolean contains(String key) {
return beans.containsKey(key);
}
}