MentaContainer

Compare Revisions

Ignore whitespace Rev 93 → Rev 94

/trunk/src/test/java/org/mentacontainer/impl/MentaContainerTest.java
270,12 → 270,10
c.ioc("connection", Connection.class).addInitValue("A super JDBC connection!");
c.wire("conn" /* the property name that will receive the dependency */,
Connection.class /* the type of the property that will receive the dependency */,
c.autowireBySetter("conn" /* the property name that will receive the dependency */,
"connection" /* the source inside the container */);
c.wire("myDep" /* notice this is the setter of the Connection class */,
SomeDependency.class /* the type - it could be an interface for better decoupling */,
c.autowireBySetter("myDep" /* notice this is the setter of the Connection class */,
"aDependency" /* again this is the name of the bean/component inside the container */);
return c;
/trunk/src/test/java/org/mentacontainer/DependencyTest.java
5,13 → 5,14
import junit.framework.Assert;
 
import org.junit.Test;
import org.mentacontainer.Dependency;
import org.mentacontainer.SetterDependency;
 
public class DependencyTest {
private static class User {
private String username;
private String something;
public User() { }
26,17 → 27,31
public void setUsername(String username) {
this.username = username;
}
public void setSomething(String s) {
this.something = "STRING: " + s;
}
public void setSomething(Object s) {
this.something = "OBJECT: " + s;
}
public String getSomething() {
return something;
}
public void setElse(Object s) {
}
}
@Test
public void testDependency() {
Dependency d = new Dependency("username", String.class, "theUsername");
SetterDependency d = new SetterDependency("username", "theUsername", String.class);
Assert.assertEquals("username", d.getTarget());
Assert.assertEquals(String.class, d.getType());
Assert.assertEquals("theUsername", d.getSource());
Method m = d.check(User.class);
46,5 → 61,21
Assert.assertEquals("setUsername", m.getName());
Assert.assertEquals(String.class, m.getParameterTypes()[0]);
d = new SetterDependency("something", "theSomething", String.class);
m = d.check(User.class);
Assert.assertEquals("setSomething", m.getName());
Assert.assertEquals(String.class, m.getParameterTypes()[0]);
d = new SetterDependency("else", "theElse", String.class);
m = d.check(User.class);
Assert.assertEquals("setElse", m.getName());
Assert.assertEquals(Object.class, m.getParameterTypes()[0]);
}
}
/trunk/src/main/java/org/mentacontainer/Dependency.java
File deleted
/trunk/src/main/java/org/mentacontainer/impl/MentaContainer.java
9,12 → 9,12
import java.util.Map;
import java.util.Set;
 
import org.mentacontainer.Interceptable;
import org.mentacontainer.Factory;
import org.mentacontainer.ConfigurableFactory;
import org.mentacontainer.Container;
import org.mentacontainer.Dependency;
import org.mentacontainer.Factory;
import org.mentacontainer.Interceptable;
import org.mentacontainer.Scope;
import org.mentacontainer.SetterDependency;
import org.mentacontainer.util.InjectionUtils;
import org.mentacontainer.util.InjectionUtils.Provider;
 
35,10 → 35,9
private Map<String, ThreadLocal<Object>> threadLocalsCache = new Hashtable<String, ThreadLocal<Object>>();
private Set<Dependency> dependencies = Collections.synchronizedSet(new HashSet<Dependency>());
private Set<SetterDependency> dependencies = Collections.synchronizedSet(new HashSet<SetterDependency>());
@Override
public Class<? extends Object> getType(String key) {
Factory factory = factoriesByName.get(key);
309,7 → 308,7
 
if (target != null) {
 
for (Dependency d : dependencies) {
for (SetterDependency d : dependencies) {
 
// has dependency ?
Method m = d.check(target.getClass());
328,24 → 327,16
 
Object source = get(sourceKey);
 
boolean isAssignable = source != null && d.getType().isAssignableFrom(source.getClass());
try {
 
// check if we can find the dependency and if it is
// assignable to the target dependency
if (isAssignable) {
// inject
m.invoke(target, source);
 
try {
} catch (Exception e) {
 
// inject
m.invoke(target, source);
throw new RuntimeException("Cannot inject dependency: method = " + (m != null ? m.getName() : "NULL") + " / source = "
+ (source != null ? source : "NULL") + " / target = " + target, e);
 
} catch (Exception e) {
 
throw new RuntimeException("Cannot inject dependency: method = " + (m != null ? m.getName() : "NULL") + " / source = "
+ (source != null ? source : "NULL") + " / target = " + target, e);
 
}
 
}
}
}
431,23 → 422,21
}
 
@Override
public Dependency wire(Dependency d) {
public SetterDependency autowireBySetter(String targetProperty, String sourceFromContainer) {
Class<? extends Object> sourceType = getType(sourceFromContainer);
 
SetterDependency d = new SetterDependency(targetProperty, sourceFromContainer, sourceType);
dependencies.add(d);
 
return d;
}
 
@Override
public Dependency wire(String property, Class<? extends Object> klass) {
return wire(property, klass, property);
}
@Override
public Dependency wire(String property, Class<? extends Object> klass, String source) {
public SetterDependency autowireBySetter(String targetProperty) {
return wire(new Dependency(property, klass, source));
return autowireBySetter(targetProperty, targetProperty);
}
 
@Override
/trunk/src/main/java/org/mentacontainer/impl/ClassFactory.java
322,6 → 322,40
return (T) obj;
}
/*
private Constructor<? extends Object> findConstructor() {
LinkedList<Class<? extends Object>> copy = new LinkedList<Class<? extends Object>>(initTypes);
Constructor<? extends Object>[] constructors = klass.getConstructors();
Constructor<? extends Object> found = null;
for(Constructor<? extends Object> c : constructors) {
Class<? extends Object>[] params = c.getParameterTypes();
if (params == null || params.length == 0) continue; // skip default constructor for now...
for(Class<? extends Object> p : params) {
// first see if it was given...
Class<? extends Object> given = copy.isEmpty() ? null : copy.get(0);
if (p.equals(given)) {
continue; // found param, let's check the other one...
} else {
// check auto-wiring...
}
}
}
}
*/
private static class DependencyKey {
private String key;
/trunk/src/main/java/org/mentacontainer/Container.java
90,7 → 90,7
* @param source The dependency itself, coming from the container as well, in other words, the bean that will be injected in the original bean
* @return The container itself. (Fluent API)
*/
public Dependency wire(String property, Class<? extends Object> klass, String source);
public SetterDependency autowireBySetter(String property);
/**
* Same as {@link #wire(String, Class, String)} except that it assumes that the property name will be the source name, in other words,
100,7 → 100,7
* @param klass
* @return The container itself. (Fluent API)
*/
public Dependency wire(String property, Class<? extends Object> klass);
public SetterDependency autowireBySetter(String property, String source);
/**
* Setup a dependency.
109,7 → 109,7
* @return The dependency itself. (Fluent API)
* @see Dependency
*/
public Dependency wire(Dependency dependency);
//public Dependency autowireByConstructor(Class<? extends Object> type, String source);
/**
* Take a given bean and populate its properties with other beans coming from this container. Perhaps you can call this auto-wiring.
/trunk/src/main/java/org/mentacontainer/SetterDependency.java
New file
0,0 → 1,141
package org.mentacontainer;
 
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
 
import org.mentacontainer.util.InjectionUtils;
 
/**
* A simple implementation of the Dependency interface.
*
* @author sergio.oliveira.jr@gmail.com
*/
public class SetterDependency {
private final String targetProperty;
private final String sourceFromContainer;
private final Class<? extends Object> sourceType;
private Map<String, Method> cache = new HashMap<String, Method>();
public SetterDependency(String targetProperty, String sourceFromContainer, Class<? extends Object> sourceType) {
this.targetProperty = targetProperty;
this.sourceFromContainer = sourceFromContainer;
this.sourceType = sourceType;
}
public String getTarget() {
return targetProperty;
}
public String getSource() {
return sourceFromContainer;
}
@Override
public int hashCode() {
return targetProperty.hashCode() * 31 + sourceFromContainer.hashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof SetterDependency)) return false;
SetterDependency d = (SetterDependency) obj;
if (!d.targetProperty.equals(this.targetProperty)) return false;
if (!d.sourceFromContainer.equals(this.sourceFromContainer)) return false;
return true;
}
public Method check(Class<? extends Object> targetClass) {
 
String className = targetClass.getName();
 
// first check cache...
Method m = null;
synchronized(cache) {
m = cache.get(className);
}
if (m == null && cache.containsKey(className)) return null; // it is null...
 
if (m != null) return m;
 
m = InjectionUtils.findMethodToInject(targetClass, targetProperty, sourceType);
/*
try {
Method[] methods = targetClass.getMethods();
StringBuilder sb = new StringBuilder(128);
sb.append("set");
sb.append(targetProperty.substring(0, 1).toUpperCase());
if (targetProperty.length() > 1) sb.append(targetProperty.substring(1));
String methodName = sb.toString();
for(Method theMethod : methods) {
if (theMethod.getName().equals(methodName)) {
// check type...
Class<? extends Object>[] params = theMethod.getParameterTypes();
if (params == null || params.length != 1) continue;
if (params[0].isAssignableFrom(sourceType)) {
m = theMethod;
break;
}
}
}
} catch(Exception e) {
e.printStackTrace();
}
*/
if (m != null) {
synchronized(cache) {
 
cache.put(className, m);
}
return m;
}
synchronized(cache) {
// save null to indicate there is no method here... (so you don't do again to find null !!!
cache.put(className, null);
}
 
return null;
}
}
/trunk/src/main/java/org/mentacontainer/example/BasicOperations.java
95,7 → 95,7
// "conn" = the name of the property
// Connection.class = the type of the property
// "connection" = the source from where the dependency will come from
c.wire("conn", Connection.class, "connection");
c.autowireBySetter("conn", "connection");
UserDAO userDAO = c.get("userDAO");
127,7 → 127,7
c.ioc("connection", Connection.class);
c.wire("conn", Connection.class, "connection");
c.autowireBySetter("conn", "connection");
SomeService service = new SomeService();