initial project

This commit is contained in:
2013-05-06 14:25:45 +08:00
parent 780af2d128
commit af1db31e5a
34 changed files with 1080 additions and 1 deletions
Submodule Elk-ioc deleted from 32d3cbf057
+3
View File
@@ -0,0 +1,3 @@
.idea
Elk-ioc.iml
target/
+16
View File
@@ -0,0 +1,16 @@
Elk
===
TODO List
- [X] implement constructor injection
- [ ] more tests for container
- [ ] refactor code (Xiaolong)
- [ ] add some exception handlers (Junv)
- [X] implement setter injection
- [ ] implement scoped container
- [ ] Option:implement factory injection
- [ ] Option:implement annotation
License
====
MIT License
+126
View File
@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.toozhao</groupId>
<artifactId>Elk-ioc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Elk IOC container</name>
<packaging>jar</packaging>
<description>Yet another Ioc container</description>
<url>https://github.com/szpyxlwoni/Elk</url>
<parent>
<groupId>com.toozhao</groupId>
<artifactId>Elk</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<licenses>
<license>
<name>MIT Licence</name>
<url>MIT Licence</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<url>https://github.com/szpyxlwoni/Elk.git</url>
<connection>git@github.com:szpyxlwoni/Elk.git</connection>
</scm>
<developers>
<developer>
<id>junv</id>
<name>Junv</name>
<email>wahyd4@gmail.com</email>
</developer>
<developer>
<id>szpyxlwoni</id>
<name>szpyxlwoni</name>
<email>szpyxlwoni@gmail.com</email>
</developer>
</developers>
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>14.0</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>2.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9</version>
<configuration>
<show>private</show>
<nohelp>true</nohelp>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<distributionManagement>
<snapshotRepository>
<id>nexus-oss</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
</project>
@@ -0,0 +1,43 @@
package com.thoughtworks.elk.container;
import com.thoughtworks.elk.container.exception.ElkParseException;
import com.thoughtworks.elk.injection.ConstructorInjection;
import com.thoughtworks.elk.injection.Injection;
import com.thoughtworks.elk.injection.SetterInjection;
import java.util.HashSet;
import java.util.Scanner;
import static com.google.common.collect.Sets.newHashSet;
public class ConfigFileParser {
private String injection;
private final Scanner scanner;
public ConfigFileParser(String configFilePath) {
scanner = new Scanner(this.getClass().getClassLoader().getResourceAsStream(configFilePath));
if (scanner.hasNext()) {
injection = scanner.next();
}
}
public Injection getInjection() {
if (injection.equals("constructor")) {
return new ConstructorInjection();
}
return new SetterInjection();
}
public HashSet<Class> getClassList() {
HashSet<Class> classes = newHashSet();
while (scanner.hasNext()) {
try {
classes.add(Class.forName(scanner.next()));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return classes;
}
}
@@ -0,0 +1,108 @@
package com.thoughtworks.elk.container;
import com.google.common.base.Function;
import javax.annotation.Nullable;
import com.thoughtworks.elk.container.exception.ElkContainerException;
import com.thoughtworks.elk.container.exception.ElkParseException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Lists.transform;
public class ConfigXmlParser {
private Document doc;
public ConfigXmlParser(String configFilePath) throws ElkParseException {
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(configFilePath);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
doc = dBuilder.parse(resourceAsStream);
} catch (Exception e) {
throw new ElkParseException(e.getMessage());
}
}
public Node getNode(String beanId) {
NodeList nodeList = doc.getElementsByTagName("bean");
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node.getAttributes().getNamedItem("id").getNodeValue().equals(beanId)) {
return node;
}
}
return null;
}
public ArrayList<Node> getChildNodes(String parentId, String childName) {
NodeList nodeList = getNode(parentId).getChildNodes();
ArrayList<Node> nodeArrayList = newArrayList();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node.getNodeName().equals(childName)) {
nodeArrayList.add(node);
}
}
return nodeArrayList;
}
private String getAttribute(String beanId, String attributeName) {
return getNode(beanId).getAttributes().getNamedItem(attributeName).getNodeValue();
}
public String getBeanClass(String beanId) {
return getAttribute(beanId, "class");
}
public List getConstructorDependenciesClass(String beanId) {
return getChildNodeAttribute(beanId, "constructor-arg", "type");
}
public List getConstructorDependenciesName(String beanId) {
return getChildNodeAttribute(beanId, "constructor-arg", "ref");
}
private List getChildNodeAttribute(String beanId, String childName, final String attribute) {
ArrayList<Node> childNodes = getChildNodes(beanId, childName);
return transform(childNodes, new Function<Node, Object>() {
@Override
public Object apply(@Nullable Node node) {
return node.getAttributes().getNamedItem(attribute).getNodeValue();
}
});
}
public List getProperties(String beanId) {
List<String> propertyName = getChildNodeAttribute(beanId, "property", "name");
List<String> propertyRef = getChildNodeAttribute(beanId, "property", "ref");
List<String> propertyType = getChildNodeAttribute(beanId, "property", "type");
List<Property> properties = newArrayList();
for (int i = 0; i < propertyName.size(); i++) {
properties.add(new Property(propertyName.get(i), propertyRef.get(i), propertyType.get(i)));
}
return properties;
}
Class[] getDependenciesClass(List dependencies) {
return (Class[]) transform(dependencies, new Function<Object, Object>() {
@Override
public Object apply(@Nullable Object o) {
try {
return Class.forName((String) o);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
}).toArray(new Class[0]);
}
}
@@ -0,0 +1,172 @@
package com.thoughtworks.elk.container;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import javax.annotation.Nullable;
import com.thoughtworks.elk.container.exception.ElkContainerException;
import com.thoughtworks.elk.container.exception.ElkParseException;
import com.thoughtworks.elk.injection.ConstructorInjection;
import com.thoughtworks.elk.injection.Injection;
import com.thoughtworks.elk.injection.SetterInjection;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import static com.google.common.collect.Lists.transform;
import static com.google.common.collect.Maps.newHashMap;
import static com.google.common.collect.Sets.filter;
import static com.google.common.collect.Sets.newHashSet;
public class ElkContainer {
private final ConfigFileParser configParser;
private final Injection injection;
private final HashSet<Class> classList;
private HashMap beanList = newHashMap();
private HashSet<ElkContainer> children = null;
private ElkContainer parent = null;
public ElkContainer(Injection injection) {
this.injection = injection;
configParser = null;
classList = newHashSet();
}
public ElkContainer(String configFilePath) {
configParser = new ConfigFileParser(configFilePath);
injection = configParser.getInjection();
classList = configParser.getClassList();
}
public void register(Class clazz) {
classList.add(clazz);
}
public <T> T getBean(final Class<T> clazz) throws ElkContainerException, IllegalAccessException, InvocationTargetException, InstantiationException {
if (!validScope(clazz)) return null;
if (clazz.isInterface()) return (T) getBean(findOneImplementClass(clazz));
if (beanList.get(clazz) == null) {
T instance = injection.buildBeanWithDependencies(clazz, this);
beanList.put(clazz, instance);
return instance;
}
return (T) beanList.get(clazz);
}
public Class findOneImplementClass(final Class clazz) {
return visit(this, new ContainerVisitor<Class>() {
@Override
public boolean isAppropriateContainer(ElkContainer container) {
return isImplementHaveBeenContained(clazz, container.classList);
}
@Override
public Class returnWhenAppropriateContainerFound(ElkContainer container) {
return (Class) findImplementClasses(clazz, container.classList).toArray()[0];
}
@Override
public Class returnWhenNoMoreParentContainer() {
return null;
}
});
}
private boolean isImplementHaveBeenContained(Class clazz, HashSet currentList) {
return findImplementClasses(clazz, currentList).size() == 1;
}
private Set<Class> findImplementClasses(final Class clazz, HashSet<Class> currentList) {
return filter(currentList, new Predicate<Class>() {
@Override
public boolean apply(@Nullable Class clazzInContainer) {
return Arrays.asList(clazzInContainer.getInterfaces()).contains(clazz);
}
});
}
public boolean isParameterAllInClassList(Class<?>[] parameterTypes) {
for (int i = 0; i < parameterTypes.length; i++) {
if (!validScope(parameterTypes[i])) {
return false;
}
}
return true;
}
public boolean validScope(final Class clazz) {
return visit(this, new ContainerVisitor<Boolean>() {
@Override
public boolean isAppropriateContainer(ElkContainer container) {
return isClassHaveBeenContained(clazz, container.classList)
|| isImplementHaveBeenContained(clazz, container.classList);
}
@Override
public Boolean returnWhenAppropriateContainerFound(ElkContainer container) {
return true;
}
@Override
public Boolean returnWhenNoMoreParentContainer() {
return false;
}
});
}
private <T> T visit(ElkContainer container, ContainerVisitor<T> visitor) {
ElkContainer currentContainer = container;
while (currentContainer != null) {
if (visitor.isAppropriateContainer(currentContainer)) {
return visitor.returnWhenAppropriateContainerFound(currentContainer);
}
if (currentContainer.parent == null) {
return visitor.returnWhenNoMoreParentContainer();
}
currentContainer = currentContainer.parent;
}
return visitor.returnWhenNoMoreParentContainer();
}
interface ContainerVisitor<RETURN_TYPE> {
boolean isAppropriateContainer(ElkContainer container);
RETURN_TYPE returnWhenAppropriateContainerFound(ElkContainer container);
RETURN_TYPE returnWhenNoMoreParentContainer();
}
private boolean isClassHaveBeenContained(final Class clazz, HashSet currentList) {
return filter(currentList, new Predicate<Class>() {
@Override
public boolean apply(@Nullable Class clazzInContainer) {
return clazzInContainer == clazz;
}
}).size() == 1;
}
public Object[] getDependenciesObject(Class<?>[] classes) {
return transform(Arrays.asList(classes), new Function<Object, Object>() {
@Override
public Object apply(@Nullable Object o) {
try {
return getBean((Class<Object>) o);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}).toArray();
}
public void addChildContainer(ElkContainer childContainer) {
if (children == null) {
children = new HashSet<ElkContainer>();
}
children.add(childContainer);
childContainer.parent = this;
}
}
@@ -0,0 +1,25 @@
package com.thoughtworks.elk.container;
public class Property {
private String name;
private String ref;
private String type;
public Property(String name, String ref, String type) {
this.name = name;
this.ref = ref;
this.type = type;
}
public String getName() {
return name;
}
public String getRef() {
return ref;
}
public String getType() {
return type;
}
}
@@ -0,0 +1,15 @@
package com.thoughtworks.elk.container.exception;
public class ElkContainerException extends Exception {
private String messgae;
public ElkContainerException(String message) {
this.messgae = message;
}
@Override
public String toString() {
return super.toString();
}
}
@@ -0,0 +1,14 @@
package com.thoughtworks.elk.container.exception;
public class ElkParseException extends Exception {
private String message;
public ElkParseException() {
}
public ElkParseException(String message) {
this.message = message;
}
}
@@ -0,0 +1,19 @@
package com.thoughtworks.elk.injection;
import com.thoughtworks.elk.container.ElkContainer;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class ConstructorInjection implements Injection {
public <T> T buildBeanWithDependencies(Class<T> clazz, ElkContainer elkContainer)
throws InstantiationException, IllegalAccessException, InvocationTargetException {
Constructor<?>[] constructors = clazz.getConstructors();
for (int i = 0; i < constructors.length; i++) {
if (elkContainer.isParameterAllInClassList(constructors[i].getParameterTypes())) {
return (T) constructors[i].newInstance(elkContainer.getDependenciesObject(constructors[i].getParameterTypes()));
}
}
return null;
}
}
@@ -0,0 +1,10 @@
package com.thoughtworks.elk.injection;
import com.thoughtworks.elk.container.ElkContainer;
import java.lang.reflect.InvocationTargetException;
public interface Injection {
public <T> T buildBeanWithDependencies(Class<T> clazz, ElkContainer elkContainer)
throws InstantiationException, IllegalAccessException, InvocationTargetException;
}
@@ -0,0 +1,26 @@
package com.thoughtworks.elk.injection;
import com.thoughtworks.elk.container.ElkContainer;
import com.thoughtworks.elk.container.exception.ElkContainerException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class SetterInjection implements Injection {
@Override
public <T> T buildBeanWithDependencies(Class<T> clazz, ElkContainer elkContainer)
throws InstantiationException, IllegalAccessException, InvocationTargetException {
Method[] methods = clazz.getMethods();
T instance = clazz.newInstance();
for (int i = 0; i < methods.length; i++) {
if (methods[i].getName().startsWith("set") && elkContainer.isParameterAllInClassList(methods[i].getParameterTypes())) {
try {
methods[i].invoke(instance, elkContainer.getBean(methods[i].getParameterTypes()[0]));
} catch (ElkContainerException e) {
e.printStackTrace();
}
}
}
return instance;
}
}
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
</beans>
@@ -0,0 +1,21 @@
package com.thoughtworks.elk.container.test;
import com.thoughtworks.elk.container.ConfigFileParser;
import com.thoughtworks.elk.injection.ConstructorInjection;
import com.thoughtworks.elk.injection.Injection;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
public class ConfigFileParserTest {
@Test
public void should_get_injection() {
ConfigFileParser configFileParser = new ConfigFileParser("testConstructorInjection.property");
Injection injection = configFileParser.getInjection();
assertThat(injection, is(instanceOf(ConstructorInjection.class)));
}
}
@@ -0,0 +1,81 @@
package com.thoughtworks.elk.container.test;
import com.thoughtworks.elk.container.ConfigXmlParser;
import com.thoughtworks.elk.container.Property;
import com.thoughtworks.elk.container.exception.ElkParseException;
import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Node;
import java.util.ArrayList;
import java.util.List;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
public class ConfigXmlParserTest {
private ConfigXmlParser configConstructorXmlParser;
private ConfigXmlParser configSetterXmlParser;
@Before
public void setUp() throws Exception, ElkParseException {
configConstructorXmlParser = new ConfigXmlParser("testConstructorInjection.xml");
configSetterXmlParser = new ConfigXmlParser("testSetterInjection.xml");
}
@Test(expected = ElkParseException.class)
public void shouldSThrowElkParseException() throws ElkParseException {
new ConfigXmlParser("fake_file.xml");
}
@Test
public void should_return_a_node_given_bean_id() {
Node company = configConstructorXmlParser.getNode("company");
assertThat(company, notNullValue());
assertThat(company.getNodeName(), is("bean"));
}
@Test
public void should_return_a_node_given_parent_bean_id_and_child_node_name() {
ArrayList<Node> nodeArrayList = configConstructorXmlParser.getChildNodes("company", "description");
assertThat(nodeArrayList.size(), is(1));
assertThat(nodeArrayList.get(0).getChildNodes().item(0).getNodeValue(), is("test"));
}
@Test
public void should_get_class_name_given_a_bean_id() {
String attribute = configConstructorXmlParser.getBeanClass("company");
assertThat(attribute, is("com.thoughtworks.elk.movie.Hollywood"));
}
@Test
public void should_get_constructor_dependencies_class_given_a_bean_id() {
List<String> constructorDependencies = configConstructorXmlParser.getConstructorDependenciesClass("director");
assertThat(constructorDependencies.get(0), is("com.thoughtworks.elk.movie.Movie"));
assertThat(constructorDependencies.size(), is(2));
}
@Test
public void should_get_constructor_dependencies_name_given_a_bean_id() {
List<String> constructorDependencies = configConstructorXmlParser.getConstructorDependenciesName("director");
assertThat(constructorDependencies.get(0), is("movie"));
assertThat(constructorDependencies.size(), is(2));
}
@Test
public void should_get_properties_name_given_a_bean_id() {
List<Property> properties = configSetterXmlParser.getProperties("director");
assertThat(properties.get(0).getName(), is("movie"));
assertThat(properties.get(0).getRef(), is("movie"));
assertThat(properties.get(0).getType(), is("com.thoughtworks.elk.movie.Movie"));
assertThat(properties.size(), is(1));
}
}
@@ -0,0 +1,146 @@
package com.thoughtworks.elk.container.test;
import com.thoughtworks.elk.container.ElkContainer;
import com.thoughtworks.elk.container.exception.ElkContainerException;
import com.thoughtworks.elk.injection.ConstructorInjection;
import com.thoughtworks.elk.injection.SetterInjection;
import com.thoughtworks.elk.movie.*;
import com.thoughtworks.elk.movie.test.Hero;
import org.junit.Before;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.notNullValue;
public class ElkContainerTest {
private ElkContainer elkContainer;
private ElkContainer elkContainerSetter;
@Before
public void setUp() throws Exception {
elkContainer = new ElkContainer(new ConstructorInjection());
elkContainerSetter = new ElkContainer(new SetterInjection());
elkContainer.register(Hollywood.class);
elkContainer.register(Director.class);
elkContainerSetter.register(Titanic.class);
elkContainerSetter.register(Director.class);
}
@Test
public void should_add_bean_and_get_bean_through_class() throws Exception {
Hollywood hollywood = elkContainer.getBean(Hollywood.class);
Titanic titanic = elkContainerSetter.getBean(Titanic.class);
assertThat(hollywood, notNullValue());
assertThat(titanic, notNullValue());
}
@Test
public void should_get_bean_added_all_dependencies() throws Exception {
elkContainer.register(Titanic.class);
Director director = elkContainer.getBean(Director.class);
assertThat(director, notNullValue());
}
@Test
public void should_find_implement_class_in_current_container() throws InvocationTargetException, ElkContainerException, InstantiationException, IllegalAccessException {
elkContainer.register(Titanic.class);
assertThat(elkContainer.getBean(Movie.class), instanceOf(Movie.class));
assertThat(elkContainer.getBean(Movie.class), notNullValue());
assertThat(elkContainerSetter.getBean(Movie.class), notNullValue());
}
@Test
public void should_find_implement_class_in_parent_container() throws InvocationTargetException, ElkContainerException, InstantiationException, IllegalAccessException {
elkContainer.register(Titanic.class);
ElkContainer childContainer = new ElkContainer(new ConstructorInjection());
elkContainer.addChildContainer(childContainer);
assertThat(childContainer.getBean(Movie.class), instanceOf(Movie.class));
assertThat(childContainer.getBean(Movie.class), notNullValue());
}
@Test
public void should_parameter_can_not_be_found_given_not_enough_bean() throws Exception {
boolean parameterAllInBeanList = elkContainer.isParameterAllInClassList(Director.class.getConstructor(Movie.class, Company.class).getParameterTypes());
assertFalse(parameterAllInBeanList);
}
@Test
public void should_parameter_can_be_found_given_enough_bean() throws Exception {
elkContainer.register(Titanic.class);
boolean parameterAllInBeanList = elkContainer.isParameterAllInClassList(Director.class.getConstructor(Movie.class, Company.class).getParameterTypes());
assertTrue(parameterAllInBeanList);
}
@Test
public void should_get_implement_class_given_interface() throws Exception {
Class implementClass = elkContainer.findOneImplementClass(Company.class);
assertThat(implementClass.toString(), is("class com.thoughtworks.elk.movie.Hollywood"));
}
@Test
public void should_not_get_duplicate_bean() throws InvocationTargetException, ElkContainerException, InstantiationException, IllegalAccessException {
elkContainer.register(Titanic.class);
Movie movie = elkContainer.getBean(Movie.class);
Director director = elkContainer.getBean(Director.class);
assertThat(movie, notNullValue());
assertThat(director.getMovie(), is(movie));
}
@Test
public void should_add_bean_through_property_file() throws InvocationTargetException, ElkContainerException, InstantiationException, IllegalAccessException {
ElkContainer aElkContainer = new ElkContainer("testConstructorInjection.property");
ElkContainer aElkContainerSetter = new ElkContainer("testSetterInjection.property");
assertThat(aElkContainer.getBean(Movie.class), notNullValue());
assertThat(aElkContainerSetter.getBean(Movie.class), notNullValue());
}
@Test
public void should_get_bean_with_dependencies_through_property_file() throws InvocationTargetException, ElkContainerException, InstantiationException, IllegalAccessException {
ElkContainer aElkContainer = new ElkContainer("testConstructorInjection.property");
ElkContainer aElkContainerSetter = new ElkContainer("testSetterInjection.property");
assertThat(aElkContainer.getBean(Movie.class), notNullValue());
assertThat(aElkContainer.getBean(Director.class), notNullValue());
assertThat(aElkContainer.getBean(Director.class).getMovie(), notNullValue());
assertThat(aElkContainerSetter.getBean(DirectorSetter.class), notNullValue());
assertThat(aElkContainerSetter.getBean(DirectorSetter.class).getMovie(), notNullValue());
}
@Test
public void shouldNotGetABeanWithoutAdded() throws InvocationTargetException, InstantiationException, IllegalAccessException, ElkContainerException {
elkContainer.register(Titanic.class);
assertThat(elkContainer.getBean(Titanic.class), is(instanceOf(Titanic.class)));
assertThat(elkContainer.getBean(Hero.class), is(nullValue()));
}
@Test
public void parentShouldContainsHero() {
ElkContainer container = new ElkContainer(new ConstructorInjection());
container.register(Hero.class);
ElkContainer childContainer = new ElkContainer(new ConstructorInjection());
container.addChildContainer(childContainer);
ElkContainer grandsonContainer = new ElkContainer(new ConstructorInjection());
childContainer.addChildContainer(grandsonContainer);
assertThat(grandsonContainer.validScope(Hero.class), is(true));
}
}
@@ -0,0 +1,55 @@
package com.thoughtworks.elk.container.test;
import com.thoughtworks.elk.container.ElkContainer;
import com.thoughtworks.elk.container.exception.ElkContainerException;
import com.thoughtworks.elk.injection.ConstructorInjection;
import com.thoughtworks.elk.movie.Company;
import com.thoughtworks.elk.movie.Hollywood;
import com.thoughtworks.elk.movie.Titanic;
import com.thoughtworks.elk.movie.test.Hero;
import org.hamcrest.core.IsInstanceOf;
import org.junit.Before;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.hamcrest.core.IsNull.nullValue;
import static org.junit.Assert.assertThat;
public class ScopedContainerTest {
private ElkContainer elkContainer;
private ElkContainer childContainer;
@Before
public void before() {
elkContainer = new ElkContainer(new ConstructorInjection());
childContainer = new ElkContainer(new ConstructorInjection());
}
@Test
public void shouldGenerateChildContainer() throws InvocationTargetException, ElkContainerException, InstantiationException, IllegalAccessException {
elkContainer.register(Titanic.class);
elkContainer.addChildContainer(childContainer);
childContainer.register(Hero.class);
assertThat(childContainer.getBean(Titanic.class), is(IsInstanceOf.instanceOf(Titanic.class)));
assertThat(elkContainer.getBean(Hero.class), nullValue());
}
@Test
public void testAddChildContainer() throws InvocationTargetException, ElkContainerException, InstantiationException, IllegalAccessException {
ElkContainer parentContainer = new ElkContainer(new ConstructorInjection());
ElkContainer childContainer = new ElkContainer(new ConstructorInjection());
parentContainer.addChildContainer(childContainer);
parentContainer.register(Hollywood.class);
parentContainer.register(Company.class);
childContainer.register(Hero.class);
assertThat(childContainer.validScope(Company.class),is(true));
assertThat(childContainer.getBean(Company.class), notNullValue());
assertThat(parentContainer.getBean(Hero.class), is(nullValue()));
}
}
@@ -0,0 +1,30 @@
package com.thoughtworks.elk.injection.test;
import com.thoughtworks.elk.container.ElkContainer;
import com.thoughtworks.elk.injection.Injection;
import com.thoughtworks.elk.injection.ConstructorInjection;
import com.thoughtworks.elk.movie.Director;
import com.thoughtworks.elk.movie.Hollywood;
import com.thoughtworks.elk.movie.Titanic;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.junit.Assert.assertThat;
public class ConstructorInjectionTest {
@Test
public void should_build_a_bean_with_dependencies()
throws IllegalAccessException, InstantiationException, InvocationTargetException {
Injection injection = new ConstructorInjection();
ElkContainer elkContainer = new ElkContainer(injection);
elkContainer.register(Titanic.class);
elkContainer.register(Hollywood.class);
elkContainer.register(Director.class);
Director director = injection.buildBeanWithDependencies(Director.class, elkContainer);
assertThat(director, notNullValue());
}
}
@@ -0,0 +1,31 @@
package com.thoughtworks.elk.injection.test;
import com.thoughtworks.elk.container.ElkContainer;
import com.thoughtworks.elk.injection.Injection;
import com.thoughtworks.elk.injection.SetterInjection;
import com.thoughtworks.elk.movie.DirectorSetter;
import com.thoughtworks.elk.movie.Hollywood;
import com.thoughtworks.elk.movie.Titanic;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.junit.Assert.assertThat;
public class SetterInjectionTest {
@Test
public void should_build_a_bean_with_dependencies()
throws IllegalAccessException, InvocationTargetException, InstantiationException {
Injection injection = new SetterInjection();
ElkContainer elkContainer = new ElkContainer(injection);
elkContainer.register(Titanic.class);
elkContainer.register(Hollywood.class);
elkContainer.register(DirectorSetter.class);
DirectorSetter director = injection.buildBeanWithDependencies(DirectorSetter.class, elkContainer);
assertThat(director, notNullValue());
assertThat(director.getMovie(), notNullValue());
}
}
@@ -0,0 +1,4 @@
package com.thoughtworks.elk.movie;
public interface Company {
}
@@ -0,0 +1,14 @@
package com.thoughtworks.elk.movie;
public class Director {
private Movie movie;
public Director(Movie movie, Company company) {
this.movie = movie;
}
public Movie getMovie() {
return movie;
}
}
@@ -0,0 +1,14 @@
package com.thoughtworks.elk.movie;
public class DirectorSetter {
private Movie movie;
public void setMovie(Movie movie) {
this.movie = movie;
}
public Movie getMovie() {
return movie;
}
}
@@ -0,0 +1,4 @@
package com.thoughtworks.elk.movie;
public class Hollywood implements Company {
}
@@ -0,0 +1,4 @@
package com.thoughtworks.elk.movie;
public interface Movie {
}
@@ -0,0 +1,4 @@
package com.thoughtworks.elk.movie;
public class Titanic implements Movie {
}
@@ -0,0 +1,20 @@
package com.thoughtworks.elk.movie.test;
import com.thoughtworks.elk.movie.DirectorSetter;
import com.thoughtworks.elk.movie.Titanic;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsNull.notNullValue;
public class DirectorSetterTest {
@Test
public void should_get_movie() {
DirectorSetter directorSetter = new DirectorSetter();
directorSetter.setMovie(new Titanic());
assertThat(directorSetter.getMovie(), notNullValue());
}
}
@@ -0,0 +1,19 @@
package com.thoughtworks.elk.movie.test;
import com.thoughtworks.elk.movie.Director;
import com.thoughtworks.elk.movie.Hollywood;
import com.thoughtworks.elk.movie.Movie;
import com.thoughtworks.elk.movie.Titanic;
import org.junit.Test;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.junit.Assert.assertThat;
public class DirectorTest {
@Test
public void should_get_his_movie() {
Director director = new Director(new Titanic(), new Hollywood());
Movie movie = director.getMovie();
assertThat(movie, notNullValue());
}
}
@@ -0,0 +1,8 @@
package com.thoughtworks.elk.movie.test;
import com.thoughtworks.elk.movie.Movie;
public class Hero implements Movie {
}
@@ -0,0 +1,4 @@
constructor
com.thoughtworks.elk.movie.Titanic
com.thoughtworks.elk.movie.Hollywood
com.thoughtworks.elk.movie.Director
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="company" class="com.thoughtworks.elk.movie.Hollywood">
<description>test</description>
</bean>
<bean id="movie"
class="com.thoughtworks.elk.movie.Titanic">
</bean>
<bean id="director" class="com.thoughtworks.elk.movie.Director">
<constructor-arg ref="movie" type="com.thoughtworks.elk.movie.Movie"/>
<constructor-arg ref="company" type="com.thoughtworks.elk.movie.Company"/>
</bean>
</beans>
@@ -0,0 +1,3 @@
setter
com.thoughtworks.elk.movie.Titanic
com.thoughtworks.elk.movie.DirectorSetter
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="company" class="com.thoughtworks.elk.movie.Hollywood">
<description>test</description>
</bean>
<bean id="movie"
class="com.thoughtworks.elk.movie.Titanic">
</bean>
<bean id="director" class="com.thoughtworks.elk.movie.DirectorSetter">
<property name="movie" ref="movie" type="com.thoughtworks.elk.movie.Movie"></property>
</bean>
</beans>