summaryrefslogtreecommitdiff
path: root/israfil-foundation-container
diff options
context:
space:
mode:
Diffstat (limited to 'israfil-foundation-container')
-rw-r--r--israfil-foundation-container/pom.xml21
-rw-r--r--israfil-foundation-container/src/main/java/net/israfil/foundation/container/AbstractContainer.java98
-rw-r--r--israfil-foundation-container/src/main/java/net/israfil/foundation/container/AbstractStartable.java55
-rw-r--r--israfil-foundation-container/src/main/java/net/israfil/foundation/container/AutoWiringAdaptableContainer.java64
-rw-r--r--israfil-foundation-container/src/main/java/net/israfil/foundation/container/AutoWiringAdapter.java69
-rw-r--r--israfil-foundation-container/src/main/java/net/israfil/foundation/container/Container.java80
-rw-r--r--israfil-foundation-container/src/main/java/net/israfil/foundation/container/DefaultAutoWiringAdaptableContainer.java63
-rw-r--r--israfil-foundation-container/src/main/java/net/israfil/foundation/container/DefaultContainer.java216
-rw-r--r--israfil-foundation-container/src/main/java/net/israfil/foundation/container/Startable.java57
-rw-r--r--israfil-foundation-container/src/main/java/net/israfil/foundation/container/adapters/AbstractAutoWiringAdapter.java62
-rw-r--r--israfil-foundation-container/src/main/java/net/israfil/foundation/container/adapters/IndependentAutoWiringAdapter.java64
-rw-r--r--israfil-foundation-container/src/main/java/net/israfil/foundation/container/error/ComponentAlreadyRegisteredError.java48
-rw-r--r--israfil-foundation-container/src/main/java/net/israfil/foundation/container/error/CouldNotCreateComponentError.java58
-rw-r--r--israfil-foundation-container/src/main/java/net/israfil/foundation/container/error/CyclicalDependencyError.java48
-rw-r--r--israfil-foundation-container/src/main/java/net/israfil/foundation/container/error/UnsatisfiedDependencyError.java48
-rw-r--r--israfil-foundation-container/src/main/java/net/israfil/foundation/container/util/CyclicalReferenceDetectionUtil.java62
-rw-r--r--israfil-foundation-container/src/main/java/net/israfil/foundation/container/util/NonDuplicateStack.java55
-rwxr-xr-xisrafil-foundation-container/src/site/apt/index.apt45
-rw-r--r--israfil-foundation-container/src/site/apt/lifecycle.apt111
-rw-r--r--israfil-foundation-container/src/site/apt/usage.apt106
-rw-r--r--israfil-foundation-container/src/site/site.xml20
-rw-r--r--israfil-foundation-container/src/test/java/net/israfil/foundation/container/ContainerTest.java150
-rw-r--r--israfil-foundation-container/src/test/java/net/israfil/foundation/container/DefaultContainerTest.java263
-rw-r--r--israfil-foundation-container/src/test/java/net/israfil/foundation/container/LegacyContainerTest.java52
-rw-r--r--israfil-foundation-container/src/test/java/net/israfil/foundation/container/LifecycleTest.java154
-rw-r--r--israfil-foundation-container/src/test/java/net/israfil/foundation/container/MultiThreadedAutoWiringContainerTest.java104
-rw-r--r--israfil-foundation-container/src/test/java/net/israfil/foundation/container/adapters/AdaptersTest.java79
-rw-r--r--israfil-foundation-container/src/test/java/net/israfil/foundation/container/error/ComponentAlreadyRegisteredErrorTest.java54
-rw-r--r--israfil-foundation-container/src/test/java/net/israfil/foundation/container/error/CouldNotCreateComponentTest.java71
-rw-r--r--israfil-foundation-container/src/test/java/net/israfil/foundation/container/error/CyclicalDependencyErrorTest.java54
-rw-r--r--israfil-foundation-container/src/test/java/net/israfil/foundation/container/error/UnsatisfiedDependencyErrorTest.java54
-rw-r--r--israfil-foundation-container/src/test/java/net/israfil/foundation/container/util/CyclicalDependencyDetectionTest.java94
-rw-r--r--israfil-foundation-container/src/test/java/net/israfil/foundation/container/util/NonDuplicateStackTest.java83
33 files changed, 2662 insertions, 0 deletions
diff --git a/israfil-foundation-container/pom.xml b/israfil-foundation-container/pom.xml
new file mode 100644
index 0000000..742064d
--- /dev/null
+++ b/israfil-foundation-container/pom.xml
@@ -0,0 +1,21 @@
+<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/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>net.israfil.foundation</groupId>
+ <artifactId>israfil-foundation-all</artifactId>
+ <version>5-SNAPSHOT</version>
+ </parent>
+ <artifactId>israfil-foundation-container</artifactId>
+ <name>Israfil Foundation Trivial IoC Container</name>
+ <version>1.0.0-SNAPSHOT</version>
+ <url>http://www.israfil.net/projects/foundation/${artifactId}</url>
+ <inceptionYear>2008</inceptionYear>
+ <licenses>
+ <license>
+ <name>BSD</name>
+ <distribution>repo</distribution>
+ <url>http://www.israfil.net/israfil-license-bsd.txt</url>
+ <comments>A simple open-source license with minimal restrictions</comments>
+ </license>
+ </licenses>
+</project> \ No newline at end of file
diff --git a/israfil-foundation-container/src/main/java/net/israfil/foundation/container/AbstractContainer.java b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/AbstractContainer.java
new file mode 100644
index 0000000..fe6a978
--- /dev/null
+++ b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/AbstractContainer.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import net.israfil.foundation.container.error.ComponentAlreadyRegisteredError;
+
+/**
+ * A convenience abstract class that implements basic component storage and
+ * lookup, as well as basic component instance assignment.
+ *
+ * @author <a href="mailto:cgruber@israfil.net">Christian Edward Gruber </a>
+ *
+ */
+public abstract class AbstractContainer implements Container {
+
+ private final Map components = new HashMap();
+
+ private final Container parent;
+
+ private boolean running = false;
+
+ public AbstractContainer() {
+ parent = null;
+ }
+
+ public AbstractContainer(Container parent) {
+ this.parent = parent;
+ }
+
+ protected boolean isStored(Object key) {
+ return components.containsKey(key);
+ }
+
+ public boolean hasComponent(Object key) {
+ return components.containsKey(key) || (parent != null && parent.hasComponent(key));
+ }
+
+ public boolean isRunning() {
+ return this.running;
+ }
+
+ public void start() {
+ this.running = true;
+ }
+
+ protected Container getParent() { return parent; }
+
+ protected Object getStoredComponent(Object key) {
+ Object result = components.get(key);
+ if (result == null && parent != null)
+ result = parent.getComponent(key);
+ return result;
+ }
+
+ protected void store(Object key, Object component) {
+ if (hasComponent(key)) {
+ if (getComponent(key) == component) return;
+ throw new ComponentAlreadyRegisteredError("Object already registered for key: " + key);
+ }
+ components.put(key, component);
+ }
+
+}
diff --git a/israfil-foundation-container/src/main/java/net/israfil/foundation/container/AbstractStartable.java b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/AbstractStartable.java
new file mode 100644
index 0000000..c4047f1
--- /dev/null
+++ b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/AbstractStartable.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container;
+
+/**
+ * A convenience implementation of Startable
+ */
+public abstract class AbstractStartable implements Startable {
+
+ private boolean started = false;
+
+ /**
+ * @see Startable.start();
+ */
+ public void start() {
+ this.started = true;
+ }
+
+ /**
+ * @see Startable.isRunning();
+ */
+ public boolean isRunning() { return started; }
+
+}
diff --git a/israfil-foundation-container/src/main/java/net/israfil/foundation/container/AutoWiringAdaptableContainer.java b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/AutoWiringAdaptableContainer.java
new file mode 100644
index 0000000..623851b
--- /dev/null
+++ b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/AutoWiringAdaptableContainer.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container;
+
+/**
+ * A Container that uses an AutoWiringAdapter to ensure that
+ * components can be created appropriately with their dependencies
+ * satisfied automatically.
+ *
+ */
+public interface AutoWiringAdaptableContainer extends Container {
+
+ public void start();
+
+ /**
+ * Register a component. The component's class must satisfy the
+ * test <code>Injectable.class.isAssignableFrom(type);</code>
+ * to ensure that the provided component implements the lifecycle
+ * mechanisms necessary to auto-wire.
+ *
+ */
+ public void registerType(Object key, AutoWiringAdapter componentAdapter);
+
+ /**
+ * Register an independent component. This is a convenience registry
+ * method for those components without dependencies, and which
+ * have a default constructor. Only classes which fit these
+ * criteria should be used in this method.
+ *
+ */
+ public void registerType(Object key, Class<?> implementation);
+
+}
diff --git a/israfil-foundation-container/src/main/java/net/israfil/foundation/container/AutoWiringAdapter.java b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/AutoWiringAdapter.java
new file mode 100644
index 0000000..56436a5
--- /dev/null
+++ b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/AutoWiringAdapter.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container;
+
+/**
+ * An adapter interface that's used in the "AutoWiringContainer"
+ * to allow the user to specify a component's dependencies upon registration.
+ * This is not ideal, in that it's not auto-discovered constructor-based
+ * dependency injection, but since dynamic reflection is not available in the
+ * J2ME CLDC 1.1 spec, an alternate and generic injection mechanism
+ * is necessary. Implementors of this interface should be CLDC safe.
+ *
+ * @author <a href="mailto:cgruber@israfil.net">Christian Edward Gruber </a>
+ */
+public interface AutoWiringAdapter {
+
+ /**
+ * This method should return a list of keys defining the dependencies
+ * this object requires to operate, in the order expected by the
+ * create(Object[]) method.
+ */
+ public Object[] dependencies();
+
+ /**
+ * Returns the type that this adapter will create. This should be the
+ * most concrete (narrowest) common type this adapter will create, if
+ * there is more than one possibility.
+ */
+ public Class getType();
+
+ /**
+ * A method that implementors use to create a component given a set of
+ * parameters. Callers must return the parameters in the order provided
+ * by the dependencies() method.
+ */
+ public Object create(Object[] parameters) throws IllegalAccessException, InstantiationException;
+
+}
diff --git a/israfil-foundation-container/src/main/java/net/israfil/foundation/container/Container.java b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/Container.java
new file mode 100644
index 0000000..0bc0982
--- /dev/null
+++ b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/Container.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container;
+
+/**
+ * A container for components that will satisfy requests if the
+ * component is available. How these component requests are satisfied
+ * are implementation dependent, as well as how inter-component
+ * dependencies are resolved.
+ *
+ * @author <a href="mailto:cgruber@israfil.net">Christian Edward Gruber </a>
+ *
+ */
+public interface Container {
+
+ /**
+ * Returns true if the Component is available and prepared.
+ * It throws a ContainerNotStarted runtime exception if the this method
+ * is used before the container is started.
+ *
+ * This method must be implemented by implementors of Container in a
+ * thread-safe and reentrant way.
+ */
+ public boolean hasComponent(Object key);
+
+ /**
+ * Returns the component named by the key if it is available, or null if no
+ * such component is available. It throws a ContainerNotStarted runtime
+ * exception if this method is used before the container is started.
+ *
+ * This method must be implemented by implementors of Container in a
+ * thread-safe and reentrant way.
+ */
+ public Object getComponent(Object key);
+
+ /**
+ * Begin the lifecycle of the container, after which components should be
+ * accessible. Implementors should stop any component registration as of
+ * the start() call. Subsequent start() calls should be ignored.
+ */
+ public void start();
+
+ /**
+ * Returns true if the container has been started, and false if it has
+ * not been started.
+ */
+ public boolean isRunning();
+
+}
diff --git a/israfil-foundation-container/src/main/java/net/israfil/foundation/container/DefaultAutoWiringAdaptableContainer.java b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/DefaultAutoWiringAdaptableContainer.java
new file mode 100644
index 0000000..89d3b11
--- /dev/null
+++ b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/DefaultAutoWiringAdaptableContainer.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2008-2009 Israfil Consulting Services Corporation
+ * Copyright (c) 2008-2009 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container;
+
+
+
+/**
+ * A deprecated class that was the old name for DefaultContainer.
+ * Maintained to reduce API breakage.
+ * @Deprecated Class renamed to DefaultContainer.
+ */
+public class DefaultAutoWiringAdaptableContainer extends DefaultContainer {
+
+ public DefaultAutoWiringAdaptableContainer() {
+ super();
+ }
+
+ public DefaultAutoWiringAdaptableContainer(boolean failEarly) {
+ super(failEarly);
+ }
+
+ public DefaultAutoWiringAdaptableContainer(Container parent,
+ boolean failEarly) {
+ super(parent, failEarly);
+ }
+
+ public DefaultAutoWiringAdaptableContainer(Container parent) {
+ super(parent);
+ }
+
+
+}
diff --git a/israfil-foundation-container/src/main/java/net/israfil/foundation/container/DefaultContainer.java b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/DefaultContainer.java
new file mode 100644
index 0000000..f11dc47
--- /dev/null
+++ b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/DefaultContainer.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.israfil.foundation.container.adapters.IndependentAutoWiringAdapter;
+import net.israfil.foundation.container.error.ComponentAlreadyRegisteredError;
+import net.israfil.foundation.container.error.CouldNotCreateComponentError;
+import net.israfil.foundation.container.error.UnsatisfiedDependencyError;
+import net.israfil.foundation.container.util.CyclicalReferenceDetectionUtil;
+import net.israfil.foundation.container.util.NonDuplicateStack;
+
+
+/**
+ * A default implementation of AutoWiringAdaptableContainer, a Container
+ * that uses an AutoWiringAdapter to ensure that components can be
+ * created appropriately with their dependencies satisfied automatically.
+ *
+ * This adapter is intended for constructor injection, but relies on the
+ * adapter to perform such. No reflection is used by this class itself.
+ *
+ */
+public class DefaultContainer extends AbstractContainer implements AutoWiringAdaptableContainer {
+
+ private Map<Object,Object> registry = new HashMap<Object,Object>();
+
+ private final boolean failEarly;
+
+ private boolean starting = false;
+
+ private final Object CREATION_MUTEX = new Object();
+
+ /**
+ * A default constructor that will throw errors regarding circular
+ * dependencies at registration time, throw missing dependency errors
+ * at wire-up (getComponent()) time, and has no parent.
+ *
+ * @param failEarly A boolean to indicate that this container should detect missing or circular dependencies at start() time.
+ */
+ public DefaultContainer() {
+ super();
+ this.failEarly = false;
+ }
+
+ /**
+ * Construct this container such that it detects missing dependencies
+ * upon invocation of start(). Otherwise, it will fail at wire time,
+ * rather than at registration time. Circular references will give errors
+ * at registration time.
+ *
+ * @param failEarly A boolean to indicate that this container should detect missing or circular dependencies at start() time.
+ */
+ public DefaultContainer(boolean failEarly) {
+ super();
+ this.failEarly = failEarly;
+ }
+
+ /**
+ * This method constructs a DefaultAutoWiringAdaptableContainer that
+ * has a parent container for backup resolution. The parent container
+ * can be of any type of Container.
+ *
+ * @param parent The parent container (optional)
+ */
+ public DefaultContainer(Container parent) {
+ super(parent);
+ this.failEarly = false;
+ }
+
+ /**
+ * Construct this container such that it detects missing dependencies
+ * upon invocation of start(). Otherwise, it will fail at wire time,
+ * rather than at registration time. Circular references will give errors
+ * at registration time. This method also provides for a parent container.
+ * The parent container can be of any type of Container.
+ *
+ * @param failEarly A boolean to indicate that this container should detect missing or circular dependencies at start() time.
+ * @param parent The parent Container (optional)
+ */
+ public DefaultContainer(Container parent, boolean failEarly) {
+ super(parent);
+ this.failEarly = failEarly;
+ }
+
+ public synchronized void start() {
+ if (isRunning() ||
+ starting) return;
+ if (getParent() != null && !getParent().isRunning()) throw new RuntimeException("Parent container is not started.");
+ this.starting = true;
+ if (failEarly) {
+ for (Object key : registry.keySet()) {
+ // force get each component, forcing all wiring.
+ Object ignore = getComponent(key);
+ if (false) ignore.hashCode(); // cover warning - compiler should remove
+ }
+ }
+ super.start();
+ starting = false;
+ }
+
+ public void registerType(Object key, Class<?> componentType) {
+ registerType(key,componentType, 0);
+ }
+
+ protected void registerType(Object key, Class<?> componentType, long timeout) {
+ registerType(key,new IndependentAutoWiringAdapter(componentType), timeout);
+ }
+
+ public void registerType(Object key, AutoWiringAdapter componentAdapter) {
+ registerType(key,componentAdapter,0);
+ }
+
+ /**
+ * Registers a component for later instantiation and (optionally) startup.
+ *
+ * @param key the key by which this component will be identified in the system
+ * @param componentAdapter an AutoWiringAdapter for creating this component and listing its dependencies
+ * @param timeout an (optional) timeout applied to any startup lifecycle
+ */
+ protected void registerType(Object key, AutoWiringAdapter componentAdapter, long timeout) {
+ if (this.isRunning()) throw new RuntimeException("Cannot register when container is started.");
+ // FIXME: Figure out whether to support parent registry checking. Probably can't do it.
+
+ if (registry.containsKey(key)) throw new ComponentAlreadyRegisteredError("Component already registered for " + key);
+ detectCircularDependencies(key,componentAdapter);
+ registry.put(key, componentAdapter);
+ }
+
+ private void detectCircularDependencies(Object key,AutoWiringAdapter componentAdapter) {
+ NonDuplicateStack nds = new NonDuplicateStack();
+ nds.push(key);
+ CyclicalReferenceDetectionUtil.detectCircularDependencies(this.registry, nds, componentAdapter);
+ }
+
+ /**
+ * This method wires the object up with its dependencies, providing said
+ * dependencies to the object's adapter. It also starts the object if its
+ * startable
+ * @param originalKey
+ * @param adapter
+ * @return
+ */
+ private Object wireObject(Object originalKey, AutoWiringAdapter adapter) {
+ Object[] dependencies = adapter.dependencies();
+ Object[] parameters = new Object[dependencies.length];
+ for (int depn = 0; depn < dependencies.length; depn++ ) {
+ Object key = adapter.dependencies()[depn];
+ parameters[depn] = getComponent(key);
+ if (parameters[depn] == null) throw new UnsatisfiedDependencyError("Could not materialize dependency for key " + key);
+ }
+ try {
+ Object o = adapter.create(parameters);
+ if (o == null) throw new InstantiationException("Could not create a non-null object. Adapter " + adapter.getClass().getName() + " returned null.");
+ else {
+ try {
+ Startable s = ((Startable)o);
+ if (!s.isRunning()) s.start();
+ } catch (ClassCastException e) {}
+ return o;
+ }
+ } catch (IllegalAccessException e) {
+ throw new CouldNotCreateComponentError("Could not create component " + originalKey + " of type " + adapter.getType(),e);
+ } catch (InstantiationException e) {
+ throw new CouldNotCreateComponentError("Could not create component " + originalKey + " of type " + adapter.getType(),e);
+ } catch (Throwable e) {
+ throw new CouldNotCreateComponentError("Could not create component " + originalKey + " of type " + adapter.getType(),e);
+ }
+ }
+
+ public Object getComponent(Object key) {
+ Object component = super.getStoredComponent(key);
+ if (component == null && registry.containsKey(key)) {
+ synchronized (CREATION_MUTEX) {
+ if (component == null) { // in case following thread gets in just after storage.
+ component = wireObject(key,(AutoWiringAdapter)registry.get(key));
+ store(key, component);
+ }
+ }
+ }
+ return component;
+ }
+
+}
diff --git a/israfil-foundation-container/src/main/java/net/israfil/foundation/container/Startable.java b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/Startable.java
new file mode 100644
index 0000000..34b0399
--- /dev/null
+++ b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/Startable.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container;
+
+/**
+ * A simple interface that, if implemented, allows a component
+ * to participate in a startup phase of lifecycle.
+ */
+public interface Startable {
+
+ /**
+ * Begin the lifecycle of the component, after which it should be
+ * usable. This component should only act on its own startup
+ * lifecycle, and should assume that any components that are
+ * provided through dependency injection are already started
+ * before this command is executed.
+ */
+ public void start();
+
+ /**
+ * Returns true if the container has been started, and false if it has
+ * not been started.
+ */
+ public boolean isRunning();
+
+}
diff --git a/israfil-foundation-container/src/main/java/net/israfil/foundation/container/adapters/AbstractAutoWiringAdapter.java b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/adapters/AbstractAutoWiringAdapter.java
new file mode 100644
index 0000000..6500275
--- /dev/null
+++ b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/adapters/AbstractAutoWiringAdapter.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container.adapters;
+
+import net.israfil.foundation.container.AutoWiringAdapter;
+
+/**
+ * A convenience implementation of AutoWiringAdapter which can be used
+ * for those clases that have no dependencies and have a default constructor.
+ *
+ * @author <a href="mailto:cgruber@israfil.net">Christian Edward Gruber </a>
+ */
+public abstract class AbstractAutoWiringAdapter implements AutoWiringAdapter{
+
+ private final Object[] dependencies;
+
+ private final Class type;
+
+ public AbstractAutoWiringAdapter(Class type, Object[] dependencies) {
+ if (type == null)
+ throw new IllegalArgumentException("An independent component must have a type.");
+ this.type = type;
+ this.dependencies = dependencies;
+ }
+
+ public Object[] dependencies() { return dependencies; }
+
+ public Class getType() { return type; }
+
+
+}
diff --git a/israfil-foundation-container/src/main/java/net/israfil/foundation/container/adapters/IndependentAutoWiringAdapter.java b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/adapters/IndependentAutoWiringAdapter.java
new file mode 100644
index 0000000..ff945a8
--- /dev/null
+++ b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/adapters/IndependentAutoWiringAdapter.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container.adapters;
+
+import java.util.Map;
+
+/**
+ * A convenience implementation of AutoWiringAdapter which can be used
+ * for those clases that have no dependencies and have a default constructor.
+ *
+ * @author <a href="mailto:cgruber@israfil.net">Christian Edward Gruber </a>
+ */
+public class IndependentAutoWiringAdapter extends AbstractAutoWiringAdapter{
+
+ private static final Object[] NO_DEPENDENCIES = {};
+
+ public IndependentAutoWiringAdapter(Class type) {
+ super(type, NO_DEPENDENCIES);
+ }
+
+ /**
+ * This method implements AutoWiringAdapter.create() but throws
+ * a runtime exception if any parameters are passed, and uses
+ * the default (no parameter) constructor via Class.newInstance();
+ * to generate the new instance.
+ */
+ public Object create(Object[] parameters) throws IllegalAccessException, InstantiationException {
+ if (parameters != null && parameters.length > 0)
+ throw new IllegalArgumentException("Cannot pass any parameters to the creation of an independent component.");
+ return getType().newInstance();
+ }
+
+}
diff --git a/israfil-foundation-container/src/main/java/net/israfil/foundation/container/error/ComponentAlreadyRegisteredError.java b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/error/ComponentAlreadyRegisteredError.java
new file mode 100644
index 0000000..a065d81
--- /dev/null
+++ b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/error/ComponentAlreadyRegisteredError.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container.error;
+
+public class ComponentAlreadyRegisteredError extends RuntimeException {
+
+ private static final long serialVersionUID = 7557424125890830358L;
+
+ public ComponentAlreadyRegisteredError() {
+ super();
+ }
+
+ public ComponentAlreadyRegisteredError(String message) {
+ super(message);
+ }
+
+}
diff --git a/israfil-foundation-container/src/main/java/net/israfil/foundation/container/error/CouldNotCreateComponentError.java b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/error/CouldNotCreateComponentError.java
new file mode 100644
index 0000000..f8f9563
--- /dev/null
+++ b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/error/CouldNotCreateComponentError.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container.error;
+
+
+public class CouldNotCreateComponentError
+ extends RuntimeException {
+
+ private static final long serialVersionUID = 398473685547742652L;
+
+ public CouldNotCreateComponentError() {
+ super();
+ }
+
+ public CouldNotCreateComponentError(Throwable t) {
+ super(t);
+ }
+
+ public CouldNotCreateComponentError(String message) {
+ super(message);
+ }
+
+ public CouldNotCreateComponentError(String message, Throwable t) {
+ super(message,t);
+ }
+
+}
diff --git a/israfil-foundation-container/src/main/java/net/israfil/foundation/container/error/CyclicalDependencyError.java b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/error/CyclicalDependencyError.java
new file mode 100644
index 0000000..067e364
--- /dev/null
+++ b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/error/CyclicalDependencyError.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container.error;
+
+public class CyclicalDependencyError extends RuntimeException {
+
+ private static final long serialVersionUID = 2260997982445143566L;
+
+ public CyclicalDependencyError() {
+ super();
+ }
+
+ public CyclicalDependencyError(String message) {
+ super(message);
+ }
+
+}
diff --git a/israfil-foundation-container/src/main/java/net/israfil/foundation/container/error/UnsatisfiedDependencyError.java b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/error/UnsatisfiedDependencyError.java
new file mode 100644
index 0000000..3110fb9
--- /dev/null
+++ b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/error/UnsatisfiedDependencyError.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container.error;
+
+public class UnsatisfiedDependencyError extends RuntimeException {
+
+ private static final long serialVersionUID = 502309807798988770L;
+
+ public UnsatisfiedDependencyError() {
+ super();
+ }
+
+ public UnsatisfiedDependencyError(String message) {
+ super(message);
+ }
+
+}
diff --git a/israfil-foundation-container/src/main/java/net/israfil/foundation/container/util/CyclicalReferenceDetectionUtil.java b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/util/CyclicalReferenceDetectionUtil.java
new file mode 100644
index 0000000..eb9f25c
--- /dev/null
+++ b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/util/CyclicalReferenceDetectionUtil.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container.util;
+
+import java.util.Map;
+
+import net.israfil.foundation.container.AutoWiringAdapter;
+import net.israfil.foundation.container.error.CyclicalDependencyError;
+
+/**
+ * A utility class that provides convenience methods for circular
+ * reference detection.
+ *
+ * @author <a href="mailto:cgruber@israfil.net">Christian Edward Gruber </a>
+ */
+public class CyclicalReferenceDetectionUtil {
+ public static void detectCircularDependencies(Map registry, NonDuplicateStack nds, AutoWiringAdapter componentAdapter) {
+ Object[] deps = componentAdapter.dependencies();
+ for (int i = 0; i < deps.length; i++) {
+ if (registry.containsKey(deps[i])) {
+ try {
+ nds.push(deps[i]);
+ } catch (IllegalArgumentException e) {
+ throw new CyclicalDependencyError("Item " + deps[i] + " is involved in a cyclic dependency. The full path is: " + nds);
+ }
+ detectCircularDependencies(registry, nds, (AutoWiringAdapter)registry.get(deps[i]));
+ nds.pop();
+ }
+ }
+ }
+}
diff --git a/israfil-foundation-container/src/main/java/net/israfil/foundation/container/util/NonDuplicateStack.java b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/util/NonDuplicateStack.java
new file mode 100644
index 0000000..d253024
--- /dev/null
+++ b/israfil-foundation-container/src/main/java/net/israfil/foundation/container/util/NonDuplicateStack.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container.util;
+
+import java.util.Stack;
+
+/**
+ * A simple stack object which throws an IllegalArgumentException if an
+ * attempt is made to push an object already contained within the stack.
+ *
+ * Primarily used for circular reference detection.
+ *
+ * @author <a href="mailto:cgruber@israfil.net">Christian Edward Gruber </a>
+ */
+public class NonDuplicateStack<T> extends Stack<T> {
+
+ private static final long serialVersionUID = -5777711467165769847L;
+
+ public T push(T item) {
+ if (contains(item)) throw new IllegalArgumentException("Duplicate item.");
+ return super.push(item);
+ }
+
+}
diff --git a/israfil-foundation-container/src/site/apt/index.apt b/israfil-foundation-container/src/site/apt/index.apt
new file mode 100755
index 0000000..10a0281
--- /dev/null
+++ b/israfil-foundation-container/src/site/apt/index.apt
@@ -0,0 +1,45 @@
+ ------
+ Israfil Micro-Container
+ ------
+ Christian Edward Gruber
+ ------
+ May 2, 2007
+
+Overview
+
+ The micro-container is an extremely lightweight IoC container supporting
+ dependency injection. It is built with the principles in mind that
+ spawned {{{http://www.picocontainer.org/} pico-container}} but with the
+ explicit constraints to which J2ME applications centered around the
+ CLDC 1.1 are bound. This includes a complete absence of any constructor
+ or method lookup (reflection) or dynamic proxy support.
+
+ Like pico-container, Israfil's micro-container only handles the
+ registration and vending of components, not additional services such as
+ persistence, and the like.
+
+Isn't Micro bigger than Pico?
+
+ Yes, but micro-container wasn't as taken, and israfil-micro is a placeholder
+ for any further frameworks that might be developed in the J2ME footprint.
+ I briefly considered femto-container, but it was too obscure even for me.
+
+Can I use this in commercial or other software?
+
+ Yes. The micro-container, as with all Israfil Micro and Foundation libraries
+ are licensed under the terms of the BSD license, which provides you with a
+ license to distribute with or without modification, and to prepare derivative
+ works, with the sole exception that you retain the notice (specific terms
+ are available in the license page linked from the menu.) The short answer
+ is yes, go for it, it won't cost you a penny, and you won't be obliged to
+ show anyone your code.
+
+How do I use it?
+
+ I recommend looking at pico-container's site for really good theoretical
+ presentations of this kind of software. Tapestry5 also contains an ioc
+ framework par-excellence, and it has some ok docs. Some specific usage
+ documentation for this framework (around staging the container and getting
+ things set up in a practical application) are available in the usage page
+ linked from the menu.
+ \ No newline at end of file
diff --git a/israfil-foundation-container/src/site/apt/lifecycle.apt b/israfil-foundation-container/src/site/apt/lifecycle.apt
new file mode 100644
index 0000000..3a62be5
--- /dev/null
+++ b/israfil-foundation-container/src/site/apt/lifecycle.apt
@@ -0,0 +1,111 @@
+ ------
+ Israfil Micro-Container : Component Lifecycle
+ ------
+ Christian Edward Gruber
+ ------
+ May 2, 2007
+
+
+ Since one bad pattern in java is to engage in all sorts of side behaviours
+ during construction, components can separate construction from initialization
+ by implementing the Startable interface. Startable components are started
+ before they are provided to any caller.
+
+%{toc}
+
+The Startable interface
+
+ The Startable interface is quite simple:
+
+-------------------
+
+package net.israfil.micro.container;
+
+public interface Startable {
+
+ public void start();
+
+ public boolean isRunning();
+
+}
+
+-------------------
+
+ Implementors should start whatever they need to in order to be ready to
+ accept calls, including marshalling any resources necessary, etc.
+
+ Care should be taken to time-out appropriately, as the container offers
+ its thread to the component during this initialization, and faulty
+ initialization can lock the container.
+
+Registering components with dependencies
+
+ Registration of components with dependencies is a bit more complicated, as it
+ requires an adapter:
+
+-------------------
+
+public void registerType(Object key, AutoWiringAdapter componentAdapter);
+
+-------------------
+
+ AutoWiringAdapters can be created on the fly, for instance by using an anonymous
+ inner class that implements AutoWiringAdapter or extending AbstractAutoWiringAdapter:
+
+-------------------
+
+container.registerType(ComponentThree.class,new AbstractAutoWiringAdapter(
+ ComponentThree.class, new Object[] {ComponentOne.class}
+ ) {
+ public Object create(Object[] params) throws IllegalAccessException, InstantiationException {
+ return new ComponentThreeImpl((ComponentOne)params[0]);
+ }
+});
+
+-------------------
+
+ Another option is to create a constant adapter on the component itself
+
+-------------------
+
+public class ComponentThreeImpl implements ComponentThree {
+ public static final AutoWiringAdapter adapter = new AbstractAutoWiringAdapter(
+ ComponentThree.class, new Object[] {ComponentOne.class}
+ ) {
+ public Object create(Object[] params) throws IllegalAccessException, InstantiationException {
+ return new ComponentThreeImpl((ComponentOne)params[0]);
+ }
+ });
+
+ private final ComponentOne one;
+
+ public ComponentThreeImpl(ComponentOne one) {
+ this.one = one;
+ }
+
+ public void doStuff() { one.whatever(); }
+}
+
+-------------------
+
+ Having created this adapter constant, you can then more easily register the
+ component in the following way:
+
+-------------------
+
+container.registerType(ComponentThree.class,ComponentThreeImpl.adapter);
+
+-------------------
+
+Retrieving components
+
+ Retrieving components is quite simple, using the getComponent method.
+
+-------------------
+
+ComponentThree three = (ComponentThree)container.getComponent(ComponentThree.class);
+three.doStuff();
+
+-------------------
+
+
diff --git a/israfil-foundation-container/src/site/apt/usage.apt b/israfil-foundation-container/src/site/apt/usage.apt
new file mode 100644
index 0000000..54ce418
--- /dev/null
+++ b/israfil-foundation-container/src/site/apt/usage.apt
@@ -0,0 +1,106 @@
+ ------
+ Israfil Micro-Container : Usage
+ ------
+ Christian Edward Gruber
+ ------
+ May 2, 2007
+
+
+ The default container is an auto-wiring container which allows for registration
+ of components quite simply, if they have no dependencies. Components with
+ dependencies require the use of an adapter which explicitly declares the
+ dependencies, and provides a builder method which receives the dependencies and
+ explicitly constructs the component, avoiding any use of reflection, which is
+ not supported in the CLDC 1.1 profile.
+
+%{toc}
+
+Setting up the auto-wiring container.
+
+ Setting up the container should be done early in your entry-point code.
+ The default container auto-wires components on first use of the component,
+ unless configured to pre-initialize them. This allows for early creation
+ of the container and registration of components without incurring the
+ up-front performance cost.
+
+ Registration for independent components works quite simply:
+
+-------------------
+
+AutoWiringAdaptableContainer container = new DefaultAutoWiringAdaptablecContainer();
+container.registerType(ComponentOne.class,ComponentOneImpl.class);
+container.registerType(ComponentTwo.class,ComponentTwoImpl.class);
+
+-------------------
+
+Registering components with dependencies
+
+ Registration of components with dependencies is a bit more complicated, as it
+ requires an adapter:
+
+-------------------
+
+public void registerType(Object key, AutoWiringAdapter componentAdapter);
+
+-------------------
+
+ AutoWiringAdapters can be created on the fly, for instance by using an anonymous
+ inner class that implements AutoWiringAdapter or extending AbstractAutoWiringAdapter:
+
+-------------------
+
+container.registerType(ComponentThree.class,new AbstractAutoWiringAdapter(
+ ComponentThree.class, new Object[] {ComponentOne.class}
+ ) {
+ public Object create(Object[] params) throws IllegalAccessException, InstantiationException {
+ return new ComponentThreeImpl((ComponentOne)params[0]);
+ }
+});
+
+-------------------
+
+ Another option is to create a constant adapter on the component itself
+
+-------------------
+
+public class ComponentThreeImpl implements ComponentThree {
+ public static final AutoWiringAdapter adapter = new AbstractAutoWiringAdapter(
+ ComponentThree.class, new Object[] {ComponentOne.class}
+ ) {
+ public Object create(Object[] params) throws IllegalAccessException, InstantiationException {
+ return new ComponentThreeImpl((ComponentOne)params[0]);
+ }
+ });
+
+ private final ComponentOne one;
+
+ public ComponentThreeImpl(ComponentOne one) {
+ this.one = one;
+ }
+
+ public void doStuff() { one.whatever(); }
+}
+
+-------------------
+
+ Having created this adapter constant, you can then more easily register the
+ component in the following way:
+
+-------------------
+
+container.registerType(ComponentThree.class,ComponentThreeImpl.adapter);
+
+-------------------
+
+Retrieving components
+
+ Retrieving components is quite simple, using the getComponent method.
+
+-------------------
+
+ComponentThree three = (ComponentThree)container.getComponent(ComponentThree.class);
+three.doStuff();
+
+-------------------
+
+
diff --git a/israfil-foundation-container/src/site/site.xml b/israfil-foundation-container/src/site/site.xml
new file mode 100644
index 0000000..d580c65
--- /dev/null
+++ b/israfil-foundation-container/src/site/site.xml
@@ -0,0 +1,20 @@
+<project>
+ <body>
+ <menu name="Parent">
+ <item name="${parent.name}" href="../index.html"/>
+ </menu>
+ <menu name="Overview">
+ <item name="Introduction" href="index.html"/>
+ <item name="Usage" href="usage.html"/>
+ <item name="Lifecycle" href="lifecycle.html"/>
+ <!-- <item name="FAQ" href="faq.html"/> -->
+ </menu>
+ <!--
+ <menu name="Examples">
+ <item name="Simple Flex app in a WAR project" href="examples/simple_war_project.html"/>
+ <item name="Flex app with extra params" href="examples/extra_parameters_project.html"/>
+ </menu>
+ -->
+ ${reports}
+ </body>
+</project> \ No newline at end of file
diff --git a/israfil-foundation-container/src/test/java/net/israfil/foundation/container/ContainerTest.java b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/ContainerTest.java
new file mode 100644
index 0000000..ab0e624
--- /dev/null
+++ b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/ContainerTest.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container;
+
+import net.israfil.foundation.container.error.ComponentAlreadyRegisteredError;
+
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class ContainerTest {
+
+ AbstractContainer container = null;
+ AbstractContainer child = null;
+
+
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() {
+ container = new AbstractContainer() {
+ public void start() { }
+ public Object getComponent(Object key) { return getStoredComponent(key); }
+ };
+ child = new AbstractContainer(container) {
+ public void start() { }
+ public Object getComponent(Object key) { return getStoredComponent(key); }
+ };
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() {
+ child = null;
+ container = null;
+ }
+
+ @Test
+ public void testContainerWithSingleComponent() {
+ FakeComponent component = new FakeComponent1();
+ container.store(FakeComponent.class, component);
+ Assert.assertSame(container.getComponent(FakeComponent.class), component);
+ }
+
+ @Test
+ public void testContainerWithMultipleComponents() {
+ FakeComponent component = new FakeComponent1();
+ FakeDependentComponent component2 = new FakeDependentComponent(component);
+ container.store(FakeComponent.class, component);
+ container.store(FakeDependentComponent.class, component2);
+ Assert.assertSame(container.getComponent(FakeComponent.class), component);
+ Assert.assertSame(container.getComponent(FakeDependentComponent.class), component2);
+ }
+
+ @Test(expectedExceptions=ComponentAlreadyRegisteredError.class)
+ public void testContainerWithDuplicateComponents() {
+ FakeComponent component1 = new FakeComponent1();
+ FakeComponent component2 = new FakeComponent2();
+ container.store(FakeComponent.class,component1);
+ container.store(FakeComponent.class,component2);
+ }
+
+ @Test
+ public void testContainerWithRepeatedRegistrationsOfTheSameComponent() {
+ FakeComponent component1 = new FakeComponent1();
+ container.store(FakeComponent.class,component1);
+ container.store(FakeComponent.class,component1);
+ }
+
+ @Test
+ public void testContainerWithParent() {
+ FakeComponent component1 = new FakeComponent1();
+ container.store(FakeComponent.class,component1);
+ Assert.assertTrue(child.hasComponent(FakeComponent.class));
+ Assert.assertSame(child.getComponent(FakeComponent.class), component1);
+ }
+
+ @Test(expectedExceptions=ComponentAlreadyRegisteredError.class)
+ public void testDuplicateRegistrationWithFirstObjectInParent() {
+ FakeComponent component1 = new FakeComponent1();
+ FakeComponent component2 = new FakeComponent2();
+ container.store(FakeComponent.class,component1);
+ child.store(FakeComponent.class,component2);
+ }
+
+ @Test
+ public void testDuplicateComponentsInPeerContainers() {
+ AbstractContainer child2 = new AbstractContainer(container) {
+ public void start() { }
+ public Object getComponent(Object key) { return getStoredComponent(key); }
+ };
+ FakeComponent component1 = new FakeComponent1();
+ FakeComponent component2 = new FakeComponent2();
+ child.store(FakeComponent.class,component1);
+ child2.store(FakeComponent.class,component2);
+ Assert.assertTrue(child.hasComponent(FakeComponent.class));
+ Assert.assertSame(child.getComponent(FakeComponent.class), component1);
+ Assert.assertNotSame(child2.getComponent(FakeComponent.class), component1);
+ Assert.assertTrue(child2.hasComponent(FakeComponent.class));
+ Assert.assertSame(child2.getComponent(FakeComponent.class), component2);
+ Assert.assertNotSame(child2.getComponent(FakeComponent.class), component1);
+ Assert.assertFalse(container.hasComponent(FakeComponent.class));
+ }
+
+ public abstract class FakeComponent {
+ public abstract boolean isTrue();
+ }
+ public class FakeComponent1 extends FakeComponent {
+ public boolean isTrue() { return false; }
+ }
+ public class FakeComponent2 extends FakeComponent {
+ public boolean isTrue() { return false; }
+ }
+ public class FakeDependentComponent {
+ private final FakeComponent fake;
+ public FakeDependentComponent(FakeComponent component) {
+ this.fake = component;
+ }
+ public boolean isTrue() { return fake.isTrue(); }
+ }
+}
diff --git a/israfil-foundation-container/src/test/java/net/israfil/foundation/container/DefaultContainerTest.java b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/DefaultContainerTest.java
new file mode 100644
index 0000000..1d108b0
--- /dev/null
+++ b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/DefaultContainerTest.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container;
+
+
+import net.israfil.foundation.container.adapters.AbstractAutoWiringAdapter;
+import net.israfil.foundation.container.adapters.IndependentAutoWiringAdapter;
+import net.israfil.foundation.container.error.ComponentAlreadyRegisteredError;
+import net.israfil.foundation.container.error.CouldNotCreateComponentError;
+import net.israfil.foundation.container.error.UnsatisfiedDependencyError;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class DefaultContainerTest {
+
+
+ public DefaultContainer createContainer() { return new DefaultContainer(); }
+ public DefaultContainer createContainer(boolean tf) { return new DefaultContainer(tf); }
+ public DefaultContainer createContainer(Container c) { return new DefaultContainer(c); }
+ public DefaultContainer createContainer(Container c, boolean tf) { return new DefaultContainer(c,tf); }
+ public TestableContainer createTestableContainer() { return new TestableDefaultContainer(); }
+
+ @Test
+ public void testAutoWiringContainer() {
+ TestableContainer container = createTestableContainer();
+ container.registerType(A.class, A1.class);
+ container.registerType(B.class,B.adapter);
+ container.registerType(D.class,D.adapter); // out of order
+ container.registerType(C.class, new AbstractAutoWiringAdapter(
+ C.class,
+ new Object[] {A.class}
+ ) {
+ public Object create(Object[] param) throws IllegalAccessException, InstantiationException {
+ return new C((A)param[0]);
+ }
+ });
+ container.start();
+ Assert.assertFalse(container.isStored(A.class));
+ Assert.assertNotNull(container.getComponent(A.class));
+ Assert.assertTrue(container.isStored(A.class));
+ Assert.assertFalse(container.isStored(B.class));
+ Assert.assertNotNull(container.getComponent(B.class));
+ Assert.assertTrue(container.isStored(B.class));
+ Assert.assertFalse(container.isStored(C.class));
+ Assert.assertFalse(container.isStored(D.class));
+ Assert.assertNotNull(container.getComponent(D.class));
+ Assert.assertTrue(container.isStored(C.class));
+ Assert.assertTrue(container.isStored(D.class));
+ }
+
+ @Test(expectedExceptions=UnsatisfiedDependencyError.class)
+ public void testMissingDependenciesFailingLate() {
+ AutoWiringAdaptableContainer container = createContainer();
+ container.registerType(B.class,B.adapter);
+ container.start();
+ Assert.assertTrue(container.isRunning());
+ container.getComponent(B.class);
+ }
+
+ @Test
+ public void testDelayedFailureWithMissingDependencies() {
+ AutoWiringAdaptableContainer container = createContainer();
+ container.registerType(B.class,B.adapter);
+ container.start();
+ }
+
+ @Test(expectedExceptions=UnsatisfiedDependencyError.class)
+ public void testMissingDependenciesFailingEarly() {
+ AutoWiringAdaptableContainer container = createContainer(true);
+ container.registerType(B.class,B.adapter);
+ container.start();
+ }
+
+ @Test
+ public void testMultipleStartups() {
+ AutoWiringAdaptableContainer container = createContainer(true);
+ container.registerType(A.class,A1.class);
+ container.registerType(B.class,B.adapter);
+ container.start();
+ Assert.assertTrue(container.isRunning());
+ container.start(); // no error.
+ }
+
+ @Test(expectedExceptions=RuntimeException.class)
+ public void testStartupWithUnstartedParent() {
+ AutoWiringAdaptableContainer parent = createContainer();
+ AutoWiringAdaptableContainer child = createContainer(parent);
+ parent.registerType(A.class,A1.class);
+ child.registerType(B.class,B.adapter);
+ child.start(); // failed to start parent.
+ }
+
+ @Test(expectedExceptions=ComponentAlreadyRegisteredError.class)
+ public void testDuplicateRegistration() {
+ AutoWiringAdaptableContainer container = createContainer();
+ container.registerType(A.class,A1.class);
+ container.registerType(A.class,new AutoWiringAdapter() {
+ public Object create(Object[] parameters) throws IllegalAccessException, InstantiationException {
+ return null;
+ }
+ public Object[] dependencies() { return null; }
+ public Class getType() { return null; }
+ });
+ }
+
+ @Test(expectedExceptions=RuntimeException.class)
+ public void testRegistryFailureAfterStart() {
+ AutoWiringAdaptableContainer container = createContainer();
+ container.registerType(A.class,A1.class);
+ container.registerType(B.class,B.adapter);
+ container.start();
+ container.registerType(D.class,D.adapter);
+ }
+
+ @Test(expectedExceptions=CouldNotCreateComponentError.class)
+ public void testIllegalAccessDuringConstruction() {
+ AutoWiringAdaptableContainer container = createContainer(true);
+ container.registerType(ComponentWithProtectedConstructor.class,ComponentWithProtectedConstructor.class);
+ container.start();
+ }
+
+ @Test(expectedExceptions=CouldNotCreateComponentError.class)
+ public void testInstantiationErrorDuringConstruction() {
+ AutoWiringAdaptableContainer container = createContainer(true);
+ container.registerType(A.class,A.class);
+ container.start();
+ }
+
+ @Test(expectedExceptions=CouldNotCreateComponentError.class)
+ public void testNullComponentCreation() {
+ AutoWiringAdaptableContainer container = createContainer(true);
+ container.registerType(A.class,new IndependentAutoWiringAdapter(A.class) {
+ public Object create(Object[] param) throws IllegalAccessException, InstantiationException {
+ return null;
+ }
+ });
+ container.start();
+ }
+
+ @Test(expectedExceptions=CouldNotCreateComponentError.class)
+ public void testArbitraryErrorInComponentCreation() {
+ AutoWiringAdaptableContainer container = createContainer(true);
+ container.registerType(A.class,new IndependentAutoWiringAdapter(A.class) {
+ public Object create(Object[] param) throws IllegalAccessException, InstantiationException {
+ throw new RuntimeException("Random error");
+ }
+ });
+ container.start();
+ }
+
+
+ @Test
+ public void testAutowiringWithDependencyInParentContainerWithEarlyInstantiation() {
+ AutoWiringAdaptableContainer parent = createContainer(true);
+ AutoWiringAdaptableContainer child = createContainer(parent,true);
+ parent.registerType(A.class,A1.class);
+ child.registerType(B.class,B.adapter);
+ parent.start();
+ child.start();
+ Assert.assertNotNull(child.getComponent(B.class));
+ }
+
+ @Test
+ public void testAutowiringWithDependencyInParentContainerWithLateIntantiation() {
+ AutoWiringAdaptableContainer parent = createContainer();
+ AutoWiringAdaptableContainer child = createContainer(parent);
+ parent.registerType(A.class,A1.class);
+ child.registerType(B.class,B.adapter);
+ parent.start();
+ child.start();
+ Assert.assertNotNull(child.getComponent(B.class));
+ }
+
+ public static abstract class A {
+ }
+ public static class A1 extends A {
+ }
+ public static class B {
+ private final A a;
+ public B(A a) {
+ if (a==null) throw new IllegalArgumentException("B cannot support null constructor arguments.");
+ this.a = a;
+ }
+ public static final AutoWiringAdapter adapter = new AbstractAutoWiringAdapter(
+ B.class,
+ new Object[] {A.class}
+ ) {
+ public Object create(Object[] param) throws IllegalAccessException, InstantiationException {
+ return new B((A)param[0]);
+ }
+ };
+ }
+ public static class C {
+ private final A a;
+ public C(A a) {
+ if (a==null) throw new IllegalArgumentException("C cannot support null constructor arguments.");
+ this.a = a;
+ }
+ }
+ public static class D {
+ private final C c;
+ public D(C c) {
+ if (c==null) throw new IllegalArgumentException("D cannot support null constructor arguments.");
+ this.c = c;
+ }
+ public static final AutoWiringAdapter adapter = new AbstractAutoWiringAdapter(
+ D.class,
+ new Object[] {C.class}
+ ) {
+ public Object create(Object[] param) throws IllegalAccessException, InstantiationException {
+ return new D((C)param[0]);
+ }
+ };
+ }
+
+ public static class ComponentWithProtectedConstructor {
+ protected ComponentWithProtectedConstructor() {}
+ }
+
+ public static interface TestableContainer extends AutoWiringAdaptableContainer {
+ public boolean isStored(Object key);
+ }
+
+ public static class TestableDefaultContainer extends DefaultContainer implements TestableContainer {
+ public boolean isStored(Object key) {
+ return super.isStored(key);
+ }
+ }
+
+
+}
diff --git a/israfil-foundation-container/src/test/java/net/israfil/foundation/container/LegacyContainerTest.java b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/LegacyContainerTest.java
new file mode 100644
index 0000000..4e69610
--- /dev/null
+++ b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/LegacyContainerTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container;
+
+
+
+public class LegacyContainerTest extends DefaultContainerTest {
+
+ public DefaultContainer createContainer() { return new DefaultAutoWiringAdaptableContainer(); }
+ public DefaultContainer createContainer(boolean tf) { return new DefaultAutoWiringAdaptableContainer(tf); }
+ public DefaultContainer createContainer(Container c) { return new DefaultAutoWiringAdaptableContainer(c); }
+ public DefaultContainer createContainer(Container c, boolean tf) { return new DefaultAutoWiringAdaptableContainer(c,tf); }
+ public TestableContainer createTestableContainer() { return new TestableLegacyContainer(); }
+
+ public static class TestableLegacyContainer extends DefaultAutoWiringAdaptableContainer implements TestableContainer {
+ public boolean isStored(Object key) {
+ return super.isStored(key);
+ }
+ }
+
+}
diff --git a/israfil-foundation-container/src/test/java/net/israfil/foundation/container/LifecycleTest.java b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/LifecycleTest.java
new file mode 100644
index 0000000..920f17c
--- /dev/null
+++ b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/LifecycleTest.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container;
+
+import net.israfil.foundation.container.adapters.AbstractAutoWiringAdapter;
+import net.israfil.foundation.container.adapters.IndependentAutoWiringAdapter;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+
+public class LifecycleTest {
+
+ @Test()
+ public void testAbstractStartable() {
+ Startable s = new AbstractStartable() {};
+ Assert.assertFalse(s.isRunning());
+ s.start();
+ Assert.assertTrue(s.isRunning());
+ }
+
+ @Test()
+ public void testStartupOfSingleComponent() {
+ AutoWiringAdaptableContainer container = new DefaultContainer();
+ final A1 a1 = new A1();
+ container.registerType(A.class, new IndependentAutoWiringAdapter(A1.class) {
+ public Object create(Object[] args) { return a1; }
+ });
+ Assert.assertFalse(a1.isRunning());
+ container.start();
+ container.getComponent(A.class);
+ Assert.assertTrue(a1.isRunning());
+ }
+
+ @Test()
+ public void testStartupOfStartedComponent() {
+ AutoWiringAdaptableContainer container = new DefaultContainer();
+ final A2 a2 = new A2();
+ a2.start();
+ container.registerType(A.class, new IndependentAutoWiringAdapter(A.class) {
+ public Object create(Object[] args) { return a2; }
+ });
+ container.start();
+ container.getComponent(A.class);
+ Assert.assertEquals(a2.invoked,1);
+ }
+
+ @Test()
+ public void testStartupOfMultipleComponents() {
+ AutoWiringAdaptableContainer container = new DefaultContainer();
+ final A1 a1 = new A1();
+ final C c = new C(a1);
+ container.registerType(A.class, new IndependentAutoWiringAdapter(A1.class) {
+ public Object create(Object[] args) { return a1; }
+ });
+ container.registerType(B.class, B.adapter);
+ container.registerType(C.class, new AbstractAutoWiringAdapter(
+ C.class,
+ new Object[] {A.class}
+ ) {
+ public Object create(Object[] param) throws IllegalAccessException, InstantiationException {
+ return c;
+ }
+ });
+ Assert.assertFalse(a1.isRunning());
+ Assert.assertFalse(c.isRunning());
+ container.start();
+ container.getComponent(A.class);
+ Assert.assertFalse(c.isRunning());
+ Assert.assertTrue(a1.isRunning());
+ container.getComponent(C.class);
+ Assert.assertTrue(c.isRunning());
+ Assert.assertTrue(a1.isRunning());
+ }
+
+ public static interface A {
+ }
+
+ public static class A1 extends AbstractStartable implements A {
+ public void start() { super.start(); }
+ }
+
+ public static class A2 extends AbstractStartable implements A {
+ public int invoked = 0;
+ public void start() {
+ super.start();
+ invoked++;
+ }
+ }
+
+ public static class B {
+ private final A a;
+ public B(A a) {
+ if (a==null) throw new IllegalArgumentException("B cannot support null constructor arguments.");
+ this.a = a;
+ }
+ public static final AutoWiringAdapter adapter = new AbstractAutoWiringAdapter(
+ B.class,
+ new Object[] {A.class}
+ ) {
+ public Object create(Object[] param) throws IllegalAccessException, InstantiationException {
+ return new B((A)param[0]);
+ }
+ };
+ }
+ public static class C extends AbstractStartable implements Startable{
+ private final A a;
+ public C(A a) {
+ if (a==null) throw new IllegalArgumentException("C cannot support null constructor arguments.");
+ this.a = a;
+ }
+ public void start() { super.start(); }
+ public static final AutoWiringAdapter adapter = new AbstractAutoWiringAdapter(
+ C.class,
+ new Object[] {A.class}
+ ) {
+ public Object create(Object[] param) throws IllegalAccessException, InstantiationException {
+ return new C((A)param[0]);
+ }
+ };
+ }
+
+}
diff --git a/israfil-foundation-container/src/test/java/net/israfil/foundation/container/MultiThreadedAutoWiringContainerTest.java b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/MultiThreadedAutoWiringContainerTest.java
new file mode 100644
index 0000000..dabc119
--- /dev/null
+++ b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/MultiThreadedAutoWiringContainerTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container;
+
+import net.israfil.foundation.container.adapters.AbstractAutoWiringAdapter;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+
+public class MultiThreadedAutoWiringContainerTest {
+
+ @Test()
+ public void testMissingDependenciesWiringEarly() {
+ AutoWiringAdaptableContainer container = new DefaultContainer(true);
+ container.registerType(A.class,A1.class);
+ container.registerType(B.class,B.adapter);
+ container.start();
+ Assert.assertNotNull(container.getComponent(B.class));
+ }
+
+ public static abstract class A {
+ }
+ public static class A1 extends A {
+ }
+ public static class B {
+ private final A a;
+ public B(A a) {
+ if (a==null) throw new IllegalArgumentException("B cannot support null constructor arguments.");
+ this.a = a;
+ }
+ public static final AutoWiringAdapter adapter = new AbstractAutoWiringAdapter(
+ B.class,
+ new Object[] {A.class}
+ ) {
+ public Object create(Object[] param) throws IllegalAccessException, InstantiationException {
+ return new B((A)param[0]);
+ }
+ };
+ }
+ public static class C {
+ private final A a;
+ public C(A a) {
+ if (a==null) throw new IllegalArgumentException("C cannot support null constructor arguments.");
+ this.a = a;
+ }
+ }
+ public static class D {
+ private final C c;
+ public D(C c) {
+ if (c==null) throw new IllegalArgumentException("D cannot support null constructor arguments.");
+ this.c = c;
+ }
+ public static final AutoWiringAdapter adapter = new AbstractAutoWiringAdapter(
+ D.class,
+ new Object[] {C.class}
+ ) {
+ public Object create(Object[] param) throws IllegalAccessException, InstantiationException {
+ return new D((C)param[0]);
+ }
+ };
+ }
+
+ public static class E {
+ protected E() {}
+ }
+
+ public static class TestableAutoWiringAdaptableContainer extends DefaultContainer {
+ public boolean isStored(Object key) {
+ return super.isStored(key);
+ }
+ }
+}
diff --git a/israfil-foundation-container/src/test/java/net/israfil/foundation/container/adapters/AdaptersTest.java b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/adapters/AdaptersTest.java
new file mode 100644
index 0000000..62150ed
--- /dev/null
+++ b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/adapters/AdaptersTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container.adapters;
+
+import net.israfil.foundation.container.AutoWiringAdapter;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Tests
+ * @author cgruber
+ *
+ */
+public class AdaptersTest {
+
+ @Test(expectedExceptions=IllegalArgumentException.class)
+ public void testIndependentAutoWiringAdapterWithNullType() {
+ new IndependentAutoWiringAdapter(null);
+ }
+
+ @Test
+ public void testIndependentAutoWiringAdapterWithEmptyParamters() throws Exception {
+ AutoWiringAdapter awa = new IndependentAutoWiringAdapter(Fake.class);
+ Fake fake = (Fake)awa.create(new Object[0]);
+ Assert.assertNotNull(fake);
+ }
+
+ @Test
+ public void testIndependentAutoWiringAdapterWithNullParamters() throws Exception {
+ AutoWiringAdapter awa = new IndependentAutoWiringAdapter(Fake.class);
+ Fake fake = (Fake)awa.create(null);
+ Assert.assertNotNull(fake); // should not reach this assert.
+ }
+
+ @Test(expectedExceptions=IllegalArgumentException.class)
+ public void testIndependentAutoWiringAdapterWithNonEmptyParamters() throws Exception {
+ AutoWiringAdapter awa = new IndependentAutoWiringAdapter(Fake.class);
+ Object[] parameters = new Object[1];
+ parameters[0] = "A";
+ Fake fake = (Fake)awa.create(parameters);
+ Assert.assertNotNull(fake); // should not reach this assert.
+ }
+
+ public static class Fake {
+ public Fake() {}
+ }
+}
diff --git a/israfil-foundation-container/src/test/java/net/israfil/foundation/container/error/ComponentAlreadyRegisteredErrorTest.java b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/error/ComponentAlreadyRegisteredErrorTest.java
new file mode 100644
index 0000000..fdaa7fa
--- /dev/null
+++ b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/error/ComponentAlreadyRegisteredErrorTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container.error;
+
+import org.testng.annotations.Test;
+
+
+
+public class ComponentAlreadyRegisteredErrorTest {
+
+ @Test(expectedExceptions=ComponentAlreadyRegisteredError.class)
+ public void testSimpleErrorThrow() throws Throwable {
+ Throwable error = new ComponentAlreadyRegisteredError();
+ throw error;
+ }
+
+ @Test(expectedExceptions=ComponentAlreadyRegisteredError.class)
+ public void testSimpleErrorThrowWithString() throws Throwable {
+ Throwable error = new ComponentAlreadyRegisteredError("test");
+ throw error;
+ }
+
+}
diff --git a/israfil-foundation-container/src/test/java/net/israfil/foundation/container/error/CouldNotCreateComponentTest.java b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/error/CouldNotCreateComponentTest.java
new file mode 100644
index 0000000..87d43a4
--- /dev/null
+++ b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/error/CouldNotCreateComponentTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container.error;
+
+import org.testng.annotations.Test;
+
+
+
+public class CouldNotCreateComponentTest {
+
+ @Test(expectedExceptions=CouldNotCreateComponentError.class)
+ public void testSimpleErrorThrow() throws Throwable {
+ Throwable error = new CouldNotCreateComponentError();
+ throw error;
+ }
+
+ @Test(expectedExceptions=CouldNotCreateComponentError.class)
+ public void testSimpleErrorThrowWithString() throws Throwable {
+ Throwable error = new CouldNotCreateComponentError("test");
+ throw error;
+ }
+
+ @Test(expectedExceptions=CouldNotCreateComponentError.class)
+ public void testSimpleErrorThrowWithThrowable() {
+ RuntimeException error = new CouldNotCreateComponentError(
+ new RuntimeException("test2")
+ );
+ throw error;
+ }
+
+ @Test(expectedExceptions=CouldNotCreateComponentError.class)
+ public void testSimpleErrorThrowWithStringAndThrowable() {
+ RuntimeException error = new CouldNotCreateComponentError(
+ "test",
+ new RuntimeException("test2")
+ );
+ throw error;
+ }
+
+}
diff --git a/israfil-foundation-container/src/test/java/net/israfil/foundation/container/error/CyclicalDependencyErrorTest.java b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/error/CyclicalDependencyErrorTest.java
new file mode 100644
index 0000000..fc2fd93
--- /dev/null
+++ b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/error/CyclicalDependencyErrorTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container.error;
+
+import org.testng.annotations.Test;
+
+
+
+public class CyclicalDependencyErrorTest {
+
+ @Test(expectedExceptions=CyclicalDependencyError.class)
+ public void testSimpleErrorThrow() throws Throwable {
+ Throwable error = new CyclicalDependencyError();
+ throw error;
+ }
+
+ @Test(expectedExceptions=CyclicalDependencyError.class)
+ public void testSimpleErrorThrowWithString() throws Throwable {
+ Throwable error = new CyclicalDependencyError("test");
+ throw error;
+ }
+
+}
diff --git a/israfil-foundation-container/src/test/java/net/israfil/foundation/container/error/UnsatisfiedDependencyErrorTest.java b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/error/UnsatisfiedDependencyErrorTest.java
new file mode 100644
index 0000000..c668b5d
--- /dev/null
+++ b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/error/UnsatisfiedDependencyErrorTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container.error;
+
+import org.testng.annotations.Test;
+
+
+
+public class UnsatisfiedDependencyErrorTest {
+
+ @Test(expectedExceptions=UnsatisfiedDependencyError.class)
+ public void testSimpleErrorThrow() throws Throwable {
+ Throwable error = new UnsatisfiedDependencyError();
+ throw error;
+ }
+
+ @Test(expectedExceptions=UnsatisfiedDependencyError.class)
+ public void testSimpleErrorThrowWithString() throws Throwable {
+ Throwable error = new UnsatisfiedDependencyError("test");
+ throw error;
+ }
+
+}
diff --git a/israfil-foundation-container/src/test/java/net/israfil/foundation/container/util/CyclicalDependencyDetectionTest.java b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/util/CyclicalDependencyDetectionTest.java
new file mode 100644
index 0000000..781ad92
--- /dev/null
+++ b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/util/CyclicalDependencyDetectionTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.israfil.foundation.container.AutoWiringAdapter;
+import net.israfil.foundation.container.adapters.AbstractAutoWiringAdapter;
+import net.israfil.foundation.container.adapters.IndependentAutoWiringAdapter;
+import net.israfil.foundation.container.error.CyclicalDependencyError;
+
+import org.testng.annotations.Test;
+
+
+public class CyclicalDependencyDetectionTest {
+
+ @Test()
+ public void testCircularDependencyCheckWithNonCyclicGraph() {
+ // setup non-circular graph.
+ Map<Object,Object> registry = new HashMap<Object,Object>();
+ registry.put("a", new FakeAutoWireAdapter(new Object[]{"b","e","d"}));
+ registry.put("b", new FakeAutoWireAdapter(new Object[]{"f","c"}));
+ registry.put("c", new IndependentAutoWiringAdapter(Object.class));
+ registry.put("d", new FakeAutoWireAdapter(new Object[]{"e"}));
+ registry.put("e", new FakeAutoWireAdapter(new Object[]{"c"}));
+ registry.put("f", new IndependentAutoWiringAdapter(Object.class));
+ NonDuplicateStack<Object> nds = new NonDuplicateStack<Object>();
+ for (Object key : registry.keySet()) {
+ nds.push(key);
+ CyclicalReferenceDetectionUtil.detectCircularDependencies(registry, nds, (AutoWiringAdapter)registry.get(key));
+ nds.pop();
+ }
+ }
+
+ @Test(expectedExceptions=CyclicalDependencyError.class)
+ public void testCircularDependencyCheckWithCyclicalGraph() {
+ // setup circular graph.
+ Map<Object,Object> registry = new HashMap<Object,Object>();
+ registry.put("a", new FakeAutoWireAdapter(new Object[]{"b","e","d"}));
+ registry.put("b", new FakeAutoWireAdapter(new Object[]{"f","c"}));
+ registry.put("c", new FakeAutoWireAdapter(new Object[]{"d"}));
+ registry.put("d", new FakeAutoWireAdapter(new Object[]{"e"}));
+ registry.put("e", new FakeAutoWireAdapter(new Object[]{"c"}));
+ registry.put("f", new IndependentAutoWiringAdapter(Object.class));
+ NonDuplicateStack<Object> nds = new NonDuplicateStack<Object>();
+ for (Object key : registry.keySet()) {
+ nds.push(key);
+ CyclicalReferenceDetectionUtil.detectCircularDependencies(registry, nds, (AutoWiringAdapter)registry.get(key));
+ nds.pop();
+ }
+ }
+
+
+ public static class FakeAutoWireAdapter extends AbstractAutoWiringAdapter {
+ public FakeAutoWireAdapter(Object[] dependencies) {
+ super(Object.class, dependencies);
+ }
+ public Object create(Object[] parameters) throws IllegalAccessException, InstantiationException {
+ return null;
+ }
+ }
+}
diff --git a/israfil-foundation-container/src/test/java/net/israfil/foundation/container/util/NonDuplicateStackTest.java b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/util/NonDuplicateStackTest.java
new file mode 100644
index 0000000..a67afb0
--- /dev/null
+++ b/israfil-foundation-container/src/test/java/net/israfil/foundation/container/util/NonDuplicateStackTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2008 Israfil Consulting Services Corporation
+ * Copyright (c) 2008 Christian Edward Gruber
+ * All Rights Reserved
+ *
+ * This software is licensed under the Berkeley Standard Distribution license,
+ * (BSD license), as defined below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Israfil Consulting Services nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ *
+ * $Id: Copyright.java 618 2008-04-14 14:03:03Z christianedwardgruber $
+ */
+package net.israfil.foundation.container.util;
+
+import java.util.Stack;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+
+public class NonDuplicateStackTest {
+
+ @Test()
+ public void testBasicStackBehaviour() {
+ String s1 = "Hi.";
+ String s2 = "Hi";
+ String s3 = "Bye.";
+ Stack<Object> stack = new NonDuplicateStack<Object>();
+ stack.push(s1);
+ stack.push(s2);
+ stack.push(s3);
+ Assert.assertSame(stack.pop(),s3);
+ Assert.assertSame(stack.pop(),s2);
+ Assert.assertSame(stack.pop(),s1);
+ }
+
+ @Test(expectedExceptions=IllegalArgumentException.class)
+ public void testDuplicateHandlingByObjectRef() {
+ Object o1 = new Object();
+ Object o2 = new Object();
+ Object o3 = new Object();
+ Stack<Object> stack = new NonDuplicateStack<Object>();
+ stack.push(o1);
+ stack.push(o2);
+ stack.push(o3);
+ stack.push(o2);
+ }
+
+ @Test(expectedExceptions=IllegalArgumentException.class)
+ public void testDuplicateHandlingByValue() {
+ String s1 = "Hi.";
+ String s2 = "Hi";
+ String s3 = "Bye.";
+ String s4 = "Hi";
+ Stack<Object> stack = new NonDuplicateStack<Object>();
+ stack.push(s1);
+ stack.push(s2);
+ stack.push(s3);
+ stack.push(s4);
+ }
+
+}