Rev 39 |
Rev 41 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
package org.mentacontainer.impl;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
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;
import org.mentacontainer.util.InjectionUtils.Provider;
/**
* 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,
Object> singletons =
new HashMap<String,
Object>();
private Set<Dependency
> dependencies =
new HashSet<Dependency
>();
public Object get
(String key
) {
if (!beans.
containsKey(key
)) throw new RuntimeException("Container does not have this bean set: " + key
);
Component c = beans.
get(key
);
Object target =
null;
try {
if (c.
isSingleton()) {
if (singletons.
containsKey(key
)) {
target = singletons.
get(key
);
return target
;
} else {
target = c.
getInstance();
singletons.
put(key, target
);
}
} else {
target = c.
getInstance();
}
if (target
!=
null) {
for (Dependency d : dependencies
) {
// has dependency ?
Method m = d.
check(target.
getClass());
if (m
!=
null) {
String sourceKey = d.
getSource();
if (sourceKey.
equals(key
)) {
// cannot depend on itself... also avoid recursive StackOverflow...
continue;
}
Object source = get
(sourceKey
);
boolean isAssignable = source
!=
null && d.
getType().
isAssignableFrom(source.
getClass());
// check if we can find the dependency and if it is
// assignable to the target dependency
if (isAssignable
) {
try {
// inject
m.
invoke(target, source
);
} catch (Exception 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
} catch (Exception e
) {
throw new RuntimeException(e
);
}
}
public Component ioc
(String key,
Component component
) {
if (beans.
containsKey(key
)) throw new RuntimeException("Container already set for the bean key: " + key
);
beans.
put(key, component
);
return component
;
}
public Component ioc
(String key,
Class<? extends Object> klass
) {
return ioc
(key,
new MentaComponent
(klass
));
}
public Component ioc
(String key,
Class<? extends Object> klass,
boolean singleton
) {
return ioc
(key,
new MentaComponent
(klass, singleton
));
}
public Dependency autowire
(Dependency d
) {
if (dependencies.
contains(d
)) throw new RuntimeException("Dependency is already set: " + d.
getTarget());
dependencies.
add(d
);
return d
;
}
public Dependency autowire
(String property,
Class<? extends Object> klass
) {
return autowire
(property, klass, property
);
}
public Dependency autowire
(String property,
Class<? extends Object> klass,
String source
) {
return autowire
(new MentaDependency
(property, klass, source
));
}
public Container populate
(Object bean
) {
Provider p =
new Provider() {
public Object get
(String key
) {
return MentaContainer.
this.
get(key
);
}
public boolean contains
(String key
) {
return MentaContainer.
this.
contains(key
);
}
};
try {
InjectionUtils.
getObject(bean, p,
false,
null,
true,
false,
true);
} catch(Exception e
) {
throw new RuntimeException("Error populating bean: " + bean, e
);
}
return this;
}
public boolean contains
(String key
) {
return beans.
containsKey(key
);
}
}