mirror of
https://github.com/wahyd4/Elk.git
synced 2026-08-09 04:56:14 +10:00
initial project
This commit is contained in:
-1
Submodule Elk-ioc deleted from 32d3cbf057
@@ -0,0 +1,3 @@
|
||||
.idea
|
||||
Elk-ioc.iml
|
||||
target/
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
+15
@@ -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()));
|
||||
|
||||
}
|
||||
}
|
||||
+30
@@ -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>
|
||||
Reference in New Issue
Block a user