MentaContainer

Compare Revisions

Ignore whitespace Rev 90 → Rev 91

/trunk/src/test/java/org/mentacontainer/impl/GenericFactoryTest.java
27,7 → 27,7
Container c = new MentaContainer();
// giveMeSomething => method that will be called to return object
Factory generic = new GenericFactory(factory, "giveMeSomething");
Factory generic = new GenericFactory(factory, "giveMeSomething", String.class);
c.ioc("myFactory", generic);
/trunk/src/test/java/org/mentacontainer/impl/MentaContainerTest.java
266,7 → 266,7
c.ioc("myDAO", JdbcMyDAO.class);
c.ioc("aDependency", SomeDependency.class, Scope.SINGLETON).addProperty("name", "A super dependency!");
c.ioc("aDependency", SomeDependency.class, Scope.SINGLETON).addPropertyValue("name", "A super dependency!");
c.ioc("connection", Connection.class).addInitValue("A super JDBC connection!");
365,6 → 365,12
}
@Override
public Class<? extends Object> getType() {
return SomeObject.class;
}
@Override
public void onCleared(SomeObject obj) {
obj.clear();
/trunk/src/test/java/org/mentacontainer/impl/ClassFactoryTest.java
3,6 → 3,7
import junit.framework.Assert;
 
import org.junit.Test;
import org.mentacontainer.Container;
import org.mentacontainer.Factory;
 
public class ClassFactoryTest {
27,11 → 28,11
}
@Test
public void testComponent() {
public void testFactory() {
Factory c1 = new ClassFactory(User.class).addInitValue("saoj");
Factory c2 = new ClassFactory(User.class).addProperty("username", "soliveira");
Factory c2 = new ClassFactory(User.class).addPropertyValue("username", "soliveira");
User u1 = c1.getInstance();
41,4 → 42,193
Assert.assertTrue(!u1.getUsername().equals(u2.getUsername()));
}
private static class TestObj1 {
String s;
int i;
long l;
User u;
public TestObj1(String s, int i, long l, User u) {
this.s = s;
this.i = i;
this.l = l;
this.u = u;
}
}
@Test
public void testDependable1() {
Container c = new MentaContainer();
c.ioc("myString", String.class).addInitValue("hello");
Factory c1 = new ClassFactory(c, TestObj1.class).addInitDependency("myString").addInitValue(20).addInitValue(30000L)
.addInitValue(new User("saoj"));
TestObj1 o = c1.getInstance();
Assert.assertEquals("hello", o.s);
Assert.assertEquals(20, o.i);
Assert.assertEquals(30000L, o.l);
Assert.assertEquals("saoj", o.u.getUsername());
}
private static class TestObj1_1 {
String s;
int i;
public TestObj1_1() { }
public void setS(String s) { this.s = s; }
public void setI(int i) { this.i = i; }
}
 
@Test
public void testDependable2() {
Container c = new MentaContainer();
c.ioc("myString", String.class).addInitValue("hello");
Factory c1 = new ClassFactory(c, TestObj1_1.class).addPropertyDependency("s", "myString").addPropertyValue("i", 30);
TestObj1_1 o = c1.getInstance();
Assert.assertEquals("hello", o.s);
Assert.assertEquals(30, o.i);
}
private static class TestObj2 {
int x;
public TestObj2() { }
public void setInteger(int x) {
this.x = x;
}
}
@Test
public void testPrimitivePropertyValue1() {
Factory f = new ClassFactory(TestObj2.class).addPropertyValue("integer", 20);
TestObj2 o = f.getInstance();
Assert.assertEquals(20, o.x);
}
@Test
public void testPrimitivePropertyValue2() {
Factory f = new ClassFactory(TestObj2.class).addPropertyValue("integer", new Integer(20));
TestObj2 o = f.getInstance();
Assert.assertEquals(20, o.x);
}
private static class TestObj2_1 {
int x;
public TestObj2_1() { }
public void setInteger(Integer x) {
this.x = x;
}
}
@Test
public void testPrimitivePropertyValue3() {
Factory f = new ClassFactory(TestObj2_1.class).addPropertyValue("integer", 20);
TestObj2_1 o = f.getInstance();
Assert.assertEquals(20, o.x);
}
@Test
public void testPrimitivePropertyValue4() {
Factory f = new ClassFactory(TestObj2_1.class).addPropertyValue("integer", new Integer(20));
TestObj2_1 o = f.getInstance();
Assert.assertEquals(20, o.x);
}
private static class TestObj3 {
int x;
public TestObj3(int x) {
this.x = x;
}
}
@Test
public void testPrimitiveInitValue1() {
Factory f = new ClassFactory(TestObj3.class).addInitValue(20);
TestObj3 o = f.getInstance();
Assert.assertEquals(20, o.x);
}
private static class TestObj3_1 {
int x;
public TestObj3_1(Integer x) {
this.x = x;
}
}
@Test
public void testPrimitiveInitValue2() {
Factory f = new ClassFactory(TestObj3_1.class).addInitValue(new Integer(20));
TestObj3_1 o = f.getInstance();
Assert.assertEquals(20, o.x);
}
private static class TestObj4 {
int x;
String s;
Long l1;
long l2;
public TestObj4(int x, String s, Long l1, long l2) {
this.x = x;
this.s = s;
this.l1 = l1;
this.l2 = l2;
}
}
@Test
public void testMixInitValues() {
Factory f = new ClassFactory(TestObj4.class).addInitValue(20).addInitValue("hello").addInitValue(new Long(20)).addInitValue(20L);
TestObj4 o = f.getInstance();
Assert.assertEquals(20, o.x);
Assert.assertEquals("hello", o.s);
Assert.assertEquals(new Long(20), o.l1);
Assert.assertEquals(20, o.l2);
}
}
/trunk/src/main/java/org/mentacontainer/impl/GenericFactory.java
11,10 → 11,14
private final Method method;
public GenericFactory(Object factory, String methodName) {
private final Class<? extends Object> type;
public GenericFactory(Object factory, String methodName, Class<? extends Object> type) {
this.factory = factory;
this.type = type;
try {
this.method = FindMethod.getMethod(factory.getClass(), methodName, new Class[] { });
40,4 → 44,9
}
}
@Override
public Class<? extends Object> getType() {
return type;
}
}
/trunk/src/main/java/org/mentacontainer/impl/MentaContainer.java
25,17 → 25,30
*/
public class MentaContainer implements Container {
 
private Map<String, Factory> beans = new Hashtable<String, Factory>();
private Map<String, Factory> factoriesByName = new Hashtable<String, Factory>();
private Map<Class<? extends Object>, List<String>> factoryKeysByType = new Hashtable<Class<? extends Object>, List<String>>();
private Map<String, Scope> scopes = new Hashtable<String, Scope>();
private Map<String, Object> singletonsCache = new Hashtable<String, Object>();
private Map<String, ThreadLocal<Object>> threadLocalsCache = new Hashtable<String, ThreadLocal<Object>>();
 
private Set<Dependency> dependencies = Collections.synchronizedSet(new HashSet<Dependency>());
@Override
public Class<? extends Object> getType(String key) {
Factory factory = factoriesByName.get(key);
if (factory == null) return null;
return factory.getType();
}
@Override
public void clear(Scope scope) {
if (scope == Scope.SINGLETON) {
46,7 → 59,7
for(String key : singletonsCache.keySet()) {
Factory comp = beans.get(key);
Factory comp = factoriesByName.get(key);
if (comp instanceof Interceptable) {
73,7 → 86,7
for(String key : threadLocalsCache.keySet()) {
Factory comp = beans.get(key);
Factory comp = factoriesByName.get(key);
if (comp instanceof Interceptable) {
102,7 → 115,7
@Override
public <T> T clear(String key) {
if (!beans.containsKey(key)) return null;
if (!factoriesByName.containsKey(key)) return null;
Scope scope = scopes.get(key);
118,7 → 131,7
if (value != null) {
Factory comp = beans.get(key);
Factory comp = factoriesByName.get(key);
if (comp instanceof Interceptable) {
149,7 → 162,7
if (o != null) {
Factory comp = beans.get(key);
Factory comp = factoriesByName.get(key);
if (comp instanceof Interceptable) {
182,9 → 195,9
@Override
public <T> T get(String key) {
 
if (!beans.containsKey(key)) return null;
if (!factoriesByName.containsKey(key)) return null;
 
Factory c = beans.get(key);
Factory c = factoriesByName.get(key);
Scope scope = scopes.get(key);
355,19 → 368,40
((Interceptable) f).onCreated(value);
}
}
private void mapeTypeToKeys(String key, Factory factory) {
Class<? extends Object> type = factory.getType();
synchronized(factoryKeysByType) {
List<String> list = factoryKeysByType.get(type);
if (list == null) {
list = new LinkedList<String>();
factoryKeysByType.put(type, list);
}
list.add(key);
}
}
 
@Override
public Factory ioc(String key, Factory component, Scope scope) {
public Factory ioc(String key, Factory factory, Scope scope) {
beans.put(key, component);
factoriesByName.put(key, factory);
mapeTypeToKeys(key, factory);
singletonsCache.remove(key); // just in case we are overriding a previous singleton bean...
threadLocalsCache.remove(key); // just in case we are overriding a previous thread local...
scopes.put(key, scope);
return component;
return factory;
}
@Override
379,7 → 413,7
@Override
public ConfigurableFactory ioc(String key, Class<? extends Object> klass) {
ConfigurableFactory cc = new ClassFactory(klass);
ConfigurableFactory cc = new ClassFactory(this, klass);
ioc(key, cc);
389,7 → 423,7
@Override
public ConfigurableFactory ioc(String key, Class<? extends Object> klass, Scope scope) {
ConfigurableFactory cc = new ClassFactory(klass);
ConfigurableFactory cc = new ClassFactory(this, klass);
ioc(key, cc, scope);
450,7 → 484,7
@Override
public synchronized boolean check(String key) {
if (!beans.containsKey(key)) return false;
if (!factoriesByName.containsKey(key)) return false;
Scope scope = scopes.get(key);
/trunk/src/main/java/org/mentacontainer/impl/WrapperFactory.java
6,10 → 6,14
private final Object instance;
private final Class<? extends Object> type;
public WrapperFactory(Object instance) {
 
this.instance = instance;
this.type = instance.getClass();
}
@Override
17,4 → 21,10
return (T) instance;
}
@Override
public Class<? extends Object> getType() {
return type;
}
}
/trunk/src/main/java/org/mentacontainer/impl/ClassFactory.java
9,6 → 9,7
import java.util.Map;
 
import org.mentacontainer.ConfigurableFactory;
import org.mentacontainer.Container;
import org.mentacontainer.util.FindMethod;
 
/**
18,23 → 19,34
*/
public class ClassFactory implements ConfigurableFactory {
private final Container container;
private final Class<? extends Object> klass;
private Map<String, Object> props = null;
private List<Object> initValues = null;
private List<Class<? extends Object>> initTypes = null;
private Constructor<? extends Object> constructor = null;
private Map<String, Method> cache = null;
public ClassFactory(Class<? extends Object> klass) {
this(null, klass);
}
public ClassFactory(Container container, Class<? extends Object> klass) {
this.container = container;
this.klass = klass;
}
@Override
public ConfigurableFactory addProperty(String name, Object value) {
public ConfigurableFactory addPropertyValue(String name, Object value) {
if (props == null) {
49,41 → 61,97
}
@Override
public ConfigurableFactory addInitValue(Object value) {
public ConfigurableFactory addPropertyDependency(String property, String key) {
if (container == null) throw new IllegalStateException("Cannot set property dependency because factory does not have container!");
return addPropertyValue(property, new DependencyKey(key));
}
@Override
public ConfigurableFactory addInitDependency(String key) {
if (container == null) throw new IllegalStateException("Cannot set constructor dependency because factory does not have container!");
return addInitValue(new DependencyKey(key), container.getType(key));
}
private ConfigurableFactory addInitValue(Object value, Class<? extends Object> type) {
if (initValues == null) {
initValues = new LinkedList<Object>();
initTypes = new LinkedList<Class<? extends Object>>();
}
initValues.add(value);
initTypes.add(type);
return this;
}
 
private Class<? extends Object>[] getClasses(List<Object> values) {
@Override
public ConfigurableFactory addInitValue(Object value) {
return addInitValue(value, value.getClass());
}
@Override
public ConfigurableFactory addInitValue(int x) {
return addInitValue(x, int.class);
}
@Override
public ConfigurableFactory addInitValue(boolean b) {
return addInitValue(b, boolean.class);
}
@Override
public ConfigurableFactory addInitValue(long l) {
return addInitValue(l, long.class);
}
@Override
public ConfigurableFactory addInitValue(double d) {
return addInitValue(d, double.class);
}
 
@Override
public ConfigurableFactory addInitValue(float f) {
return addInitValue(f, float.class);
}
 
@Override
public ConfigurableFactory addInitValue(byte b) {
return addInitValue(b, byte.class);
}
 
@Override
public ConfigurableFactory addInitValue(short s) {
return addInitValue(s, short.class);
}
 
@Override
public ConfigurableFactory addInitValue(char c) {
return addInitValue(c, char.class);
}
private Class<? extends Object>[] getClasses(List<Class<? extends Object>> values) {
Class<? extends Object>[] types = (Class<? extends Object>[]) new Class[values.size()];
Iterator<Object> iter = values.iterator();
int index = 0;
while(iter.hasNext()) {
Object value = iter.next();
if (value != null) {
types[index++] = value.getClass();
} else {
types[index++] = null;
}
}
return types;
return values.toArray(types);
}
private Object [] getValues(List<Object> values) throws InstantiationException {
97,8 → 165,17
while(iter.hasNext()) {
Object obj = iter.next();
if (obj instanceof DependencyKey) {
DependencyKey dk = (DependencyKey) obj;
array[index++] = container.get(dk.getKey());
} else {
array[index++] = obj;
array[index++] = obj;
}
}
return array;
146,7 → 223,7
if (m == null) {
throw new InstantiationException("Cannot find method or field for property: " + name);
throw new InstantiationException("Cannot find method for property: " + name);
}
}
194,7 → 271,7
try {
constructor = klass.getConstructor(getClasses(initValues));
constructor = klass.getConstructor(getClasses(initTypes));
} catch(Exception e) {
233,10 → 310,31
Object value = props.get(name);
if (value instanceof DependencyKey) {
DependencyKey dk = (DependencyKey) value;
value = container.get(dk.getKey());
}
setValue(obj, name, value);
}
}
return (T) obj;
}
private static class DependencyKey {
private String key;
public DependencyKey(String key) { this.key = key; }
private String getKey() { return key; }
}
@Override
public Class<? extends Object> getType() {
return klass;
}
}
/trunk/src/main/java/org/mentacontainer/Container.java
29,6 → 29,8
*/
public <T> T get(String key);
public Class<? extends Object> getType(String key);
/**
* Configure a bean to be returned with the given implementation when {@link #get(String)} is called.
*
/trunk/src/main/java/org/mentacontainer/Factory.java
13,4 → 13,6
* @return The instantiated bean based on the container configuration.
*/
public <T> T getInstance();
public Class<? extends Object> getType();
}
/trunk/src/main/java/org/mentacontainer/ConfigurableFactory.java
20,6 → 20,15
*/
public ConfigurableFactory addInitValue(Object value);
public ConfigurableFactory addInitValue(int x);
public ConfigurableFactory addInitValue(boolean b);
public ConfigurableFactory addInitValue(long l);
public ConfigurableFactory addInitValue(float f);
public ConfigurableFactory addInitValue(short s);
public ConfigurableFactory addInitValue(double d);
public ConfigurableFactory addInitValue(byte b);
public ConfigurableFactory addInitValue(char c);
 
/**
* Add a property to be injected through a setter when the component is instantiated.
*
27,5 → 36,9
* @param value The property value.
* @return The component itself. (Fluent API)
*/
public ConfigurableFactory addProperty(String name, Object value);
public ConfigurableFactory addPropertyValue(String name, Object value);
public ConfigurableFactory addInitDependency(String key);
public ConfigurableFactory addPropertyDependency(String property, String key);
}
/trunk/src/main/java/org/mentacontainer/example/BasicOperations.java
32,9 → 32,9
System.out.println(myString2); // ==> "saoj" ==> constructor new String("saoj") was used
c.ioc("myDate1", Date.class).addProperty("hours", 15) // setHours(15)
.addProperty("minutes", 10) // setMinutes(10)
.addProperty("seconds", 45); // setSeconds(45)
c.ioc("myDate1", Date.class).addPropertyValue("hours", 15) // setHours(15)
.addPropertyValue("minutes", 10) // setMinutes(10)
.addPropertyValue("seconds", 45); // setSeconds(45)
Date myDate1 = c.get("myDate1");