Skip to content

Commit

Permalink
First commit - of version 3.2.0 - no changes in code. Two minor test …
Browse files Browse the repository at this point in the history
…errors I need to look at. Will be updated soon.
  • Loading branch information
jjenkov committed Nov 24, 2015
1 parent 4a414ff commit c9eed51
Show file tree
Hide file tree
Showing 107 changed files with 8,683 additions and 0 deletions.
36 changes: 36 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<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.jenkov</groupId>
<artifactId>butterfly-di-container</artifactId>
<version>3.2.0</version>

<dependencies>


<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>

</project>
102 changes: 102 additions & 0 deletions src/main/java/com/jenkov/container/Container.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.jenkov.container;

import com.jenkov.container.impl.factory.*;
import com.jenkov.container.itf.factory.IGlobalFactory;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
* @author Jakob Jenkov - Copyright 2005 Jenkov Development
*/
public class Container implements IContainer {

protected Map<String, IGlobalFactory> factories = null;

public Container() {
this.factories = new ConcurrentHashMap<String, IGlobalFactory>();
}

public Container(Map<String, IGlobalFactory> factories) {
this.factories = factories;
}


public void addFactory(String name, IGlobalFactory factory) {
if(this.factories.containsKey(name)) throw
new ContainerException(
"Container", "FACTORY_ALREADY_EXISTS",
"Container already contains a factory with this name: " + name);
this.factories.put(name, new GlobalFactoryProxy(factory));
}

public void addValueFactory(String id, Object value){
GlobalFactoryBase factory = new GlobalNewInstanceFactory();
factory.setLocalInstantiationFactory(new ValueFactory(value));
this.factories.put(id, new GlobalFactoryProxy(factory));
}

public IGlobalFactory replaceFactory(String name, IGlobalFactory newFactory){
GlobalFactoryProxy factoryProxy = (GlobalFactoryProxy) this.factories.get(name);
if(factoryProxy == null) {
addFactory(name, newFactory);
return null;
} else {
return factoryProxy.setDelegateFactory(newFactory);
}
}

public void removeFactory(String id) {
this.factories.remove(id);
}

public IGlobalFactory getFactory(String id) {
IGlobalFactory factory = this.factories.get(id);
//if(factory == null) throw new ContainerException("Unknown Factory: " + id);
return factory;
}

public Map<String, IGlobalFactory> getFactories() {
return this.factories;
}

public Object instance(String id, Object ... parameters){
IGlobalFactory factory = this.factories.get(id);
if(factory == null) throw new ContainerException(
"Container", "UNKNOWN_FACTORY",
"Unknown Factory: " + id);
return factory.instance(parameters);
}

public void init(){
for(String key : this.factories.keySet()){
Object factory = this.factories.get(key);

if(factory instanceof GlobalFactoryProxy){
factory = ((GlobalFactoryProxy) factory).getDelegateFactory();
if(factory instanceof GlobalSingletonFactory){
((GlobalSingletonFactory) factory).instance();
}
}
}
}

public void dispose(){
execPhase("dispose");
}

public void execPhase(String phase) {
for(String key : this.factories.keySet()){
execPhase(phase, key);
}
}

public void execPhase(String phase, String factoryName) {
Object factory = this.factories.get(factoryName);
if(factory instanceof GlobalFactoryProxy){
((GlobalFactoryProxy) factory).execPhase(phase);
}
}


}
109 changes: 109 additions & 0 deletions src/main/java/com/jenkov/container/ContainerException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package com.jenkov.container;

import java.util.List;
import java.util.ArrayList;

/**
* @author Jakob Jenkov - Copyright 2004-2006 Jenkov Development
*/
public class ContainerException extends RuntimeException {

public static final long serialVersionUID = -1;

protected List<InfoItem> infoItems =
new ArrayList<InfoItem>();

public static class InfoItem{
public String errorContext = null;
public String errorCode = null;
public String errorText = null;
public InfoItem(String contextCode, String errorCode,
String errorText){

this.errorContext = contextCode;
this.errorCode = errorCode;
this.errorText = errorText;
}
}


public ContainerException(String errorContext, String errorCode, String errorMessage){
super(errorMessage);
addInfo(errorContext, errorCode, errorMessage);
}

public ContainerException(String errorContext, String errorCode, String errorMessage, Throwable cause){
super(errorMessage, cause);
addInfo(errorContext, errorCode, errorMessage);
}

public ContainerException addInfo(String errorContext, String errorCode, String errorText){
this.infoItems.add(
new InfoItem(errorContext, errorCode, errorText));
return this;
}

public List<InfoItem> getInfoItems() {
return infoItems;
}

public String getCode(){
StringBuilder builder = new StringBuilder();

for(int i = this.infoItems.size()-1 ; i >=0; i--){
InfoItem info =
this.infoItems.get(i);
builder.append('[');
builder.append(info.errorContext);
builder.append(':');
builder.append(info.errorCode);
builder.append(']');
}

return builder.toString();
}

public String toString(){
StringBuilder builder = new StringBuilder();

builder.append("Error Code : " + getCode());
builder.append('\n');


//append additional context information.
for(int i = this.infoItems.size()-1 ; i >=0; i--){
InfoItem info =
this.infoItems.get(i);
builder.append("Context Info: ");
builder.append('[');
builder.append(info.errorContext);
builder.append(':');
builder.append(info.errorCode);
builder.append(']');
builder.append(" : ");
builder.append(info.errorText);
if(i>0) builder.append('\n');
}

//append root causes and text from this exception first.
if(getMessage() != null) {
builder.append('\n');
if(getCause() == null){
builder.append(getMessage());
} else if(!getMessage().equals(getCause().toString())){
builder.append(getMessage());
}
}
appendException(builder, getCause());

return builder.toString();
}

private void appendException(
StringBuilder builder, Throwable throwable){
if(throwable == null) return;
appendException(builder, throwable.getCause());
builder.append(throwable.toString());
builder.append('\n');
}
}
94 changes: 94 additions & 0 deletions src/main/java/com/jenkov/container/IContainer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package com.jenkov.container;

import com.jenkov.container.itf.factory.IGlobalFactory;

import java.util.Map;

/**
* The factory manager can keep track of the factories in the application.
* You can register factories, unregister factories and other stuff.
*
* @author Jakob Jenkov - Copyright 2005 Jenkov Development
*/
public interface IContainer {

/**
* Adds a factory to the container using the given name.
* @param name A name to identify the factory by.
* @param factory A factory producing some component.
*/
public void addFactory(String name, IGlobalFactory factory);

/**
* Adds a value factory to the container using the given name.
* A value factory just returns the value passed in the value parameter.
* Thus the value object becomes a singleton.
* Value factories can be used to add constants or configuration parameters to the container,
* though these can also be added in scripts.
*
* @param name The name to identify the factory by.
* @param value The value the value factory is to return (as a singleton).
*/
public void addValueFactory(String name, Object value);

/**
* Replaces the existing factory with the given name, with the new factory passed as parameter.
* All factories referencing the old factory will hereafter reference the new factory.
* @param name The name of the factory to replace.
* @param newFactory The new factory that is to replace the old.
* @return The old factory - the one that was replaced.
*/
public IGlobalFactory replaceFactory(String name, IGlobalFactory newFactory);

/**
* Removes the factory identified by the given name from the container.
* @param name The name identifying the factory to remove.
*/
public void removeFactory(String name);

/**
* Returns the factory identified by the given name.
* @param name The name identifying the factory to return.
* @return The factory identified by the given name.
*/
public IGlobalFactory getFactory(String name);

/**
* Returns a Map containing all the factories in this container.
* @return A Map containing all the factories in this container.
*/
public Map<String, IGlobalFactory> getFactories();

/**
* Returns instance of whatever component the factory identified by the given
* name produces.
* @param name The name of the factory to obtain an instance from.
* @param parameters Any parameters needed by the factory to produce the component instance.
* @return An instance of the component the factory identified by the given name produces.
*/
public Object instance(String name, Object ... parameters);

/**
* Initializes the container. Currently this means creating all singletons and other cached instances.
*/
public void init();

/**
* Executes the given life cycle phase on all factories in the container.
* @param phase The name of the life cycle phase to execute ("config", "dipose" etc.)
*/
public void execPhase(String phase);

/**
* Executes the given life cycle phase on the factory identified by the given name.
* @param phase The name of the life cycle phase to execute ("config", "dispose" etc.)
* @param name The name of the factory to execute the life cycle phase on.
*/
public void execPhase(String phase, String name);

/**
* Executes the "dispose" life cycle phase on all factories in the container.
*/
public void dispose();

}
Loading

0 comments on commit c9eed51

Please sign in to comment.