incubator-composer-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hamm...@apache.org
Subject svn commit: r613775 [8/15] - in /incubator/composer: ./ core/ core/src/ core/src/java/ core/src/java/org/ core/src/java/org/apache/ core/src/java/org/apache/composer/ core/src/java/org/apache/composer/core/ core/src/java/org/apache/composer/core/adapte...
Date Mon, 21 Jan 2008 06:41:50 GMT
Added: incubator/composer/core/src/java/org/apache/composer/core/security/CustomPermissionsURLClassLoader.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/security/CustomPermissionsURLClassLoader.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/security/CustomPermissionsURLClassLoader.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/security/CustomPermissionsURLClassLoader.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,89 @@
+/*****************************************************************************
+ * Copyright (C) PicoContainer Organization. All rights reserved.            *
+ * ------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the BSD      *
+ * style license a copy of which has been included with this distribution in *
+ * the LICENSE.txt file.                                                     *
+ *                                                                           *
+ *****************************************************************************/
+
+package org.apache.composer.core.security;
+
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.PrivilegedAction;
+import java.util.Map;
+
+/**
+ * CustomPermissionsURLClassLoader extends URLClassLoader, adding the abilty to programatically add permissions easily.
+ * To be effective for permission management, it should be run in conjunction with a policy that restricts
+ * some of the classloaders, but not all.
+ * It's not ordinarily used by PicoContainer, but is here because PicoContainer is common
+ * to most classloader trees.
+ * 
+ * @author Paul Hammant
+ */
+public class CustomPermissionsURLClassLoader extends URLClassLoader {
+    private final Map<URL, Permissions> permissionsMap;
+
+    public CustomPermissionsURLClassLoader(URL[] urls, Map<URL, Permissions> permissionsMap, ClassLoader parent) {
+        super(urls, parent);
+        this.permissionsMap = permissionsMap;
+    }
+
+    public Class<?> loadClass(String name) throws ClassNotFoundException {
+        try {
+            return super.loadClass(name);
+        } catch (ClassNotFoundException e) {
+            throw decorateException(name, e);
+        }
+    }
+
+    protected Class<?> findClass(String name) throws ClassNotFoundException {
+        try {
+            return super.findClass(name);
+        } catch (ClassNotFoundException e) {
+            throw decorateException(name, e);
+        }
+    }
+
+    private ClassNotFoundException decorateException(String name, ClassNotFoundException e) {
+        if (name.startsWith("class ")) {
+            return new ClassNotFoundException("Class '" + name + "' is not a classInstance.getName(). " +
+                    "It's a classInstance.toString(). The clue is that it starts with 'class ', no classname contains a space.");
+        }
+        ClassLoader classLoader = this;
+        StringBuffer sb = new StringBuffer("'").append(name).append("' classloader stack [");
+        while (classLoader != null) {
+            sb.append(classLoader.toString()).append("\n");
+            final ClassLoader cl = classLoader;
+            classLoader = (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    return cl.getParent();
+                }
+            });
+
+        }
+        return new ClassNotFoundException(sb.append("]").toString(), e);
+    }
+
+    public String toString() {
+        String result = CustomPermissionsURLClassLoader.class.getName() + " " + System.identityHashCode(this) + ":";
+        URL[] urls = getURLs();
+        for (URL url : urls) {
+            result += "\n\t" + url.toString();
+        }
+
+        return result;
+    }
+
+    public PermissionCollection getPermissions(CodeSource codeSource) {
+        return (Permissions) permissionsMap.get(codeSource.getLocation());
+    }
+
+}
+

Added: incubator/composer/core/src/java/org/apache/composer/core/visitors/AbstractContainerVisitor.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/visitors/AbstractContainerVisitor.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/visitors/AbstractContainerVisitor.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/visitors/AbstractContainerVisitor.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,93 @@
+/*****************************************************************************
+ * Copyright (C) PicoContainer Organization. All rights reserved.            *
+ * ------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the BSD      *
+ * style license a copy of which has been included with this distribution in *
+ * the LICENSE.txt file.                                                     *
+ *****************************************************************************/
+package org.apache.composer.core.visitors;
+
+import org.apache.composer.core.ContainerVisitor;
+import org.apache.composer.core.ComposerException;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Abstract PicoVisitor implementation. A generic traverse method is implemented, that 
+ * accepts any object with a method named &quot;accept&quot;, that takes a 
+ * {@link org.apache.composer.core.ContainerVisitor}  as argument and and invokes it. Additionally it provides the
+ * {@link #checkTraversal()} method, that throws a {@link AbstractContainerVisitor.ComposerVisitorTraversalException},
+ * if currently no traversal is running.
+ * 
+ * @author J&ouml;rg Schaible
+ */
+public abstract class AbstractContainerVisitor implements ContainerVisitor {
+    private boolean traversal;
+
+    public Object traverse(final Object node) {
+        traversal = true;
+        Object retval =
+                AccessController.doPrivileged(new PrivilegedAction() {
+                    public Object run() {
+                        try {
+                            return node.getClass().getMethod("accept", ContainerVisitor.class);
+                        } catch (NoSuchMethodException e) {
+                            return e;
+                        }
+                    }
+                });
+        try {
+            if (retval instanceof NoSuchMethodException) {
+                throw (NoSuchMethodException) retval;
+            }
+            Method accept = (Method) retval;
+            accept.invoke(node, this);
+            return Void.TYPE;
+        } catch (NoSuchMethodException e) {
+        } catch (IllegalAccessException e) {
+        } catch (InvocationTargetException e) {
+            Throwable cause = e.getTargetException();
+            if (cause instanceof RuntimeException) {
+                throw (RuntimeException)cause;
+            } else if (cause instanceof Error) {
+                throw (Error)cause;
+            }
+        } finally {
+            traversal = false;
+        }
+        throw new IllegalArgumentException(node.getClass().getName() + " is not a valid type for traversal");
+    }
+
+    /**
+     * Checks the traversal flag, indicating a currently running traversal of the visitor.
+     * @throws AbstractContainerVisitor.ComposerVisitorTraversalException if no traversal is active.
+     */
+    protected void checkTraversal() {
+        if (!traversal) {
+            throw new ComposerVisitorTraversalException(this);
+        }
+    }
+
+    /**
+     * Exception for a PicoVisitor, that is dependent on a defined starting point of the traversal.
+     * If the traversal is not initiated with a call of {@link org.apache.composer.core.ContainerVisitor#traverse}
+     *
+     * @author joehni
+     */
+    public static class ComposerVisitorTraversalException
+            extends ComposerException {
+
+        /**
+         * Construct the PicoVisitorTraversalException.
+         *
+         * @param visitor The visitor casing the exception.
+         */
+        public ComposerVisitorTraversalException(ContainerVisitor visitor) {
+            super("Traversal for PicoVisitor of type " + visitor.getClass().getName() + " must start with the visitor's traverse method");
+        }
+    }
+
+}

Added: incubator/composer/core/src/java/org/apache/composer/core/visitors/MethodCallingVisitor.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/visitors/MethodCallingVisitor.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/visitors/MethodCallingVisitor.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/visitors/MethodCallingVisitor.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,117 @@
+/*****************************************************************************
+ * Copyright (C) PicoContainer Organization. All rights reserved.            *
+ * ------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the BSD      *
+ * style license a copy of which has been included with this distribution in *
+ * the LICENSE.txt file.                                                     *
+ *****************************************************************************/
+package org.apache.composer.core.visitors;
+
+import org.apache.composer.core.Container;
+import org.apache.composer.core.CompositionException;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+
+/**
+ * A PicoVisitor implementation, that calls methods on the components of a specific type.
+ * 
+ * @author Aslak Helles&oslash;y
+ * @author J&ouml;rg Schaible
+ */
+public class MethodCallingVisitor extends TraversalCheckingVisitor implements Serializable {
+
+    // TODO: we must serialize method with read/writeObject ... and are our parent serializable ???
+    private transient Method method;
+    private final Object[] arguments;
+    private final Class type;
+    private final boolean visitInInstantiationOrder;
+    private final List componentInstances;
+
+    /**
+     * Construct a MethodCallingVisitor for a method with arguments.
+     * 
+     * @param method the {@link Method} to invoke
+     * @param ofType the type of the components, that will be invoked
+     * @param visitInInstantiationOrder <code>true</code> if components are visited in instantiation order
+     * @param arguments the arguments for the method invocation (may be <code>null</code>)
+     * @throws NullPointerException if <tt>method</tt>, or <tt>ofType</tt> is <code>null</code>
+     */
+    public MethodCallingVisitor(Method method, Class ofType, Object[] arguments, boolean visitInInstantiationOrder) {
+        if (method == null) {
+            throw new NullPointerException();
+        }
+        this.method = method;
+        this.arguments = arguments;
+        this.type = ofType;
+        this.visitInInstantiationOrder = visitInInstantiationOrder;
+        this.componentInstances = new ArrayList();
+    }
+
+    /**
+     * Construct a MethodCallingVisitor for standard methods visiting the component in instantiation order.
+     * 
+     * @param method the method to invoke
+     * @param ofType the type of the components, that will be invoked
+     * @param arguments the arguments for the method invocation (may be <code>null</code>)
+     * @throws NullPointerException if <tt>method</tt>, or <tt>ofType</tt> is <code>null</code>
+     */
+    public MethodCallingVisitor(Method method, Class ofType, Object[] arguments) {
+        this(method, ofType, arguments, true);
+    }
+
+    public Object traverse(Object node) {
+        componentInstances.clear();
+        try {
+            super.traverse(node);
+            if (!visitInInstantiationOrder) {
+                Collections.reverse(componentInstances);
+            }
+            for (Object componentInstance : componentInstances) {
+                invoke(componentInstance);
+            }
+        } finally {
+            componentInstances.clear();
+        }
+        return Void.TYPE;
+    }
+
+    public void visitContainer(Container pico) {
+        super.visitContainer(pico);
+        componentInstances.addAll(pico.getComponents(type));
+    }
+
+    protected Method getMethod() {
+        return method;
+    }
+
+    protected Object[] getArguments() {
+        return arguments;
+    }
+
+    protected void invoke(final Object[] targets) {
+        for (Object target : targets) {
+            invoke(target);
+        }
+    }
+
+    protected Class<Void> invoke(final Object target) {
+        final Method method = getMethod();
+        try {
+            method.invoke(target, getArguments());
+        } catch (IllegalArgumentException e) {
+            throw new CompositionException("Can't call " + method.getName() + " on " + target, e);
+        } catch (IllegalAccessException e) {
+            throw new CompositionException("Can't call " + method.getName() + " on " + target, e);
+        } catch (InvocationTargetException e) {
+            throw new CompositionException("Failed when calling " + method.getName() + " on " + target, e
+                    .getTargetException());
+        }
+        return Void.TYPE;
+    }
+}

Added: incubator/composer/core/src/java/org/apache/composer/core/visitors/TraversalCheckingVisitor.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/visitors/TraversalCheckingVisitor.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/visitors/TraversalCheckingVisitor.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/visitors/TraversalCheckingVisitor.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,53 @@
+/*****************************************************************************
+ * Copyright (C) PicoContainer Organization. All rights reserved.            *
+ * ------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the BSD      *
+ * style license a copy of which has been included with this distribution in *
+ * the LICENSE.txt file.                                                     *
+ *****************************************************************************/
+package org.apache.composer.core.visitors;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.Parameter;
+import org.apache.composer.core.Container;
+import org.apache.composer.core.visitors.AbstractContainerVisitor;
+
+
+/**
+ * Concrete implementation of Visitor which simply checks traversals.
+ * This can be a useful class for other Visitor implementations to extend, 
+ * as it provides a default implementation in case you one is only interested
+ * in one PicoVisitor type.  Example:
+ *
+ *<pre>
+ * PicoContainer container = new DefaultPicoContainer();
+ * PicoContainer child = container.makeChildContainer();
+ *
+ * final List allContainers = new ArrayList();
+ *
+ * PicoVisitor visitor = new TraversalCheckingVisitor() {
+ *     public void visitContainer(PicoContainer pico) {
+ *         super.visitContainer(pico);  //Calls checkTraversal for us.
+ *         allContainers.add(pico);
+ *     }
+ * }
+ * </pre>
+ *
+ * @author Micheal Rimov
+ */
+public class TraversalCheckingVisitor
+        extends AbstractContainerVisitor {
+
+    public void visitContainer(Container pico) {
+        checkTraversal();
+    }
+
+    public void visitComponentAdapter(ComponentAdapter componentAdapter) {
+        checkTraversal();
+    }
+
+    public void visitParameter(Parameter parameter) {
+        checkTraversal();
+    }
+
+}

Added: incubator/composer/core/src/java/org/apache/composer/core/visitors/VerifyingVisitor.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/java/org/apache/composer/core/visitors/VerifyingVisitor.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/java/org/apache/composer/core/visitors/VerifyingVisitor.java (added)
+++ incubator/composer/core/src/java/org/apache/composer/core/visitors/VerifyingVisitor.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,100 @@
+/*****************************************************************************
+ * Copyright (C) PicoContainer Organization. All rights reserved.            *
+ * ------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the BSD      *
+ * style license a copy of which has been included with this distribution in *
+ * the LICENSE.txt file.                                                     *
+ *****************************************************************************/
+package org.apache.composer.core.visitors;
+
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.Parameter;
+import org.apache.composer.core.Container;
+import org.apache.composer.core.ComposerVerificationException;
+import org.apache.composer.core.ContainerVisitor;
+import org.apache.composer.core.visitors.TraversalCheckingVisitor;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+
+/**
+ * Visitor to verify {@link org.apache.composer.core.Container} instances. The visitor walks down the logical container hierarchy.
+ * 
+ * @author J&ouml;rg Schaible
+ */
+public class VerifyingVisitor extends TraversalCheckingVisitor {
+
+    private final List nestedVerificationExceptions;
+    private final Set verifiedComponentAdapters;
+    private final ContainerVisitor componentAdapterCollector;
+    private Container currentPico;
+
+    /**
+     * Construct a VerifyingVisitor.
+     */
+    public VerifyingVisitor() {
+        nestedVerificationExceptions = new ArrayList();
+        verifiedComponentAdapters = new HashSet();
+        componentAdapterCollector = new ComponentAdapterCollector();
+    }
+
+    /**
+     * Traverse through all components of the {@link org.apache.composer.core.Container} hierarchy and verify the components.
+     * 
+     * @throws org.apache.composer.core.ComposerVerificationException if some components could not be verified.
+     * @see org.apache.composer.core.ContainerVisitor#traverse(java.lang.Object)
+     */
+    public Object traverse(Object node) throws ComposerVerificationException {
+        nestedVerificationExceptions.clear();
+        verifiedComponentAdapters.clear();
+        try {
+            super.traverse(node);
+            if (!nestedVerificationExceptions.isEmpty()) {
+                throw new ComposerVerificationException(new ArrayList(nestedVerificationExceptions));
+            }
+        } finally {
+            nestedVerificationExceptions.clear();
+            verifiedComponentAdapters.clear();
+        }
+        return Void.TYPE;
+    }
+
+    public void visitContainer(Container pico) {
+        super.visitContainer(pico);
+        currentPico = pico;
+    }
+
+    public void visitComponentAdapter(ComponentAdapter componentAdapter) {
+        super.visitComponentAdapter(componentAdapter);
+        if (!verifiedComponentAdapters.contains(componentAdapter)) {
+            try {
+                componentAdapter.verify(currentPico);
+            } catch (RuntimeException e) {
+                nestedVerificationExceptions.add(e);
+            }
+            componentAdapter.accept(componentAdapterCollector);
+        }
+    }
+
+    private class ComponentAdapterCollector implements ContainerVisitor {
+        // /CLOVER:OFF
+        public Object traverse(Object node) {
+            return null;
+        }
+
+        public void visitContainer(Container pico) {
+        }
+
+        // /CLOVER:ON
+
+        public void visitComponentAdapter(ComponentAdapter componentAdapter) {
+            verifiedComponentAdapters.add(componentAdapter);
+        }
+
+        public void visitParameter(Parameter parameter) {
+        }
+    }
+}

Added: incubator/composer/core/src/test/org/apache/composer/core/CharacteristicsTestCase.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/test/org/apache/composer/core/CharacteristicsTestCase.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/test/org/apache/composer/core/CharacteristicsTestCase.java (added)
+++ incubator/composer/core/src/test/org/apache/composer/core/CharacteristicsTestCase.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,15 @@
+package org.apache.composer.core;
+
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+
+public class CharacteristicsTestCase  {
+
+    @Test(expected=UnsupportedOperationException.class)    
+    public void testCharacteristicsAreImmutable() {
+        assertNotNull(Characteristics.CDI.toString());
+        Characteristics.CDI.remove("injection");
+    }
+
+}

Added: incubator/composer/core/src/test/org/apache/composer/core/ComposerVisitorTestCase.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/test/org/apache/composer/core/ComposerVisitorTestCase.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/test/org/apache/composer/core/ComposerVisitorTestCase.java (added)
+++ incubator/composer/core/src/test/org/apache/composer/core/ComposerVisitorTestCase.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,104 @@
+/*****************************************************************************
+ * Copyright (C) PicoContainer Organization. All rights reserved.            *
+ * ------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the BSD      *
+ * style license a copy of which has been included with this distribution in *
+ * the LICENSE.txt file.                                                     *
+ *****************************************************************************/
+package org.apache.composer.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.apache.composer.core.tck.MockFactory.mockeryWithCountingNamingScheme;
+
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.Sequence;
+import org.jmock.integration.junit4.JMock;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.apache.composer.core.visitors.AbstractContainerVisitor;
+import org.apache.composer.core.visitors.VerifyingVisitor;
+
+
+/**
+ * Test general PicoVisitor behaviour.
+ * @author J&ouml;rg Schaible
+ * @author Mauro Talevi
+ */
+@RunWith(JMock.class)
+public class ComposerVisitorTestCase {
+
+	private Mockery mockery = mockeryWithCountingNamingScheme();
+	
+    @Test public void testVisitorThatMustBeInvokedUsingTraverse() {
+        MutableContainer pico = new DefaultContainer();
+        try {
+            pico.accept(new VerifyingVisitor());
+            fail("PicoVisitorTraversalException expected");
+        } catch (AbstractContainerVisitor.ComposerVisitorTraversalException e) {
+            assertTrue(e.getMessage().indexOf(VerifyingVisitor.class.getName()) >= 0);
+        }
+    }
+
+    public static class UnusualNode {
+        boolean visited;
+
+        public void accept(ContainerVisitor visit) {
+            visited = true;
+        }
+    }
+
+    @Test public void testUnusualTraverseNode() {
+        UnusualNode node = new UnusualNode();
+        new VerifyingVisitor().traverse(node);
+        assertTrue(node.visited);
+    }
+
+    @Test public void testIllegalTraverseNode() {
+        try {
+            new VerifyingVisitor().traverse("Gosh!");
+            fail("IllegalArgumentException expected");
+        } catch (IllegalArgumentException e) {
+            assertTrue(e.getMessage().indexOf(String.class.getName()) >= 0);
+        }
+    }
+
+    @Test public void testThrownRuntimeExceptionIsUnwrapped() {
+    	final Container pico = mockery.mock(Container.class);
+        final ContainerVisitor visitor = new VerifyingVisitor();
+        final Error exception = new Error("junit");
+        mockery.checking(new Expectations() {{
+            one(pico).accept(with(same(visitor)));
+            will(throwException(new CompositionException("message", exception)));
+        }});
+        try {
+            visitor.traverse(pico);
+            fail("PicoCompositionException expected");
+        } catch (RuntimeException e) {
+            assertEquals("message", e.getMessage());
+            assertSame(exception, e.getCause());
+        }
+    }
+
+    @Test public void testThrownErrorIsUnwrapped() {
+    	final Container pico = mockery.mock(Container.class);
+        final ContainerVisitor visitor = new VerifyingVisitor();
+        final Error error = new InternalError("junit");
+        final Sequence sequence = mockery.sequence("accepting");
+        mockery.checking(new Expectations() {{
+            one(pico).accept(with(same(visitor))); inSequence(sequence);
+            one(pico).accept(with(same(visitor))); inSequence(sequence);
+            will(throwException(error));
+        }});
+        visitor.traverse(pico);
+        try {
+            visitor.traverse(pico);
+            fail("UndeclaredThrowableException expected");
+        } catch(InternalError e) {
+            assertEquals("junit", e.getMessage());
+        }
+    }
+}

Added: incubator/composer/core/src/test/org/apache/composer/core/ContainerBuilderTestCase.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/test/org/apache/composer/core/ContainerBuilderTestCase.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/test/org/apache/composer/core/ContainerBuilderTestCase.java (added)
+++ incubator/composer/core/src/test/org/apache/composer/core/ContainerBuilderTestCase.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,430 @@
+/*****************************************************************************
+ * Copyright (C) PicoContainer Organization. All rights reserved.            *
+ * ------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the BSD      *
+ * style license a copy of which has been included with this distribution in *
+ * the LICENSE.txt file.                                                     *
+ *                                                                           *
+ * Original code by                                                          *
+ *****************************************************************************/
+package org.apache.composer.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.apache.composer.core.behaviors.Behaviors.caching;
+import static org.apache.composer.core.behaviors.Behaviors.implementationHiding;
+import static org.apache.composer.core.behaviors.Behaviors.synchronizing;
+import static org.apache.composer.core.injectors.Injectors.SDI;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Properties;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.apache.composer.core.behaviors.ImplementationHiding;
+import org.apache.composer.core.containers.EmptyContainer;
+import org.apache.composer.core.lifecycle.LifecycleState;
+import org.apache.composer.core.monitors.ConsoleComponentMonitor;
+import org.apache.composer.core.monitors.NullComponentMonitor;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+
+public class ContainerBuilderTestCase {
+
+    private XStream xs;
+
+    @Before
+    public void setUp() throws Exception {
+        xs = new XStream();
+        xs.alias("PICO", DefaultContainer.class);
+        xs.registerConverter(new Converter() {
+            public boolean canConvert(Class aClass) {
+                return aClass.getName().equals("org.apache.composer.core.DefaultContainer$1") ||
+                       aClass.getName().equals("org.apache.composer.core.Properties") ||
+                       aClass == Boolean.class ||
+                       aClass == HashSet.class ||
+                       aClass == ArrayList.class;
+            }
+
+            public void marshal(Object o, HierarchicalStreamWriter hierarchicalStreamWriter, MarshallingContext marshallingContext) {
+            }
+
+            public Object unmarshal(HierarchicalStreamReader hierarchicalStreamReader, UnmarshallingContext unmarshallingContext) {
+                return null;
+            }
+        });
+        xs.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);
+    }
+
+    @Test public void testBasic() {
+        MutableContainer mpc = new ContainerBuilder().build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                "  componentFactory=org.apache.composer.core.injectors.AdaptingInjection\n" +
+                "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                "PICO",foo);
+    }
+
+    @Test public void testWithStartableLifecycle() {
+
+        new NullComponentMonitor();
+
+        MutableContainer mpc = new ContainerBuilder().withLifecycle().build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                "  componentFactory=org.apache.composer.core.injectors.AdaptingInjection\n" +
+                "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                "  lifecycleStrategy=org.apache.composer.core.lifecycle.StartableLifecycleStrategy\n" +
+                "    componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor reference=/PICO/lifecycleStrategy/componentMonitor\n" +
+                "PICO",foo);
+    }
+
+    @Test public void testWithReflectionLifecycle() {
+        MutableContainer mpc = new ContainerBuilder().withReflectionLifecycle().build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                "  componentFactory=org.apache.composer.core.injectors.AdaptingInjection\n" +
+                "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                "  lifecycleStrategy=org.apache.composer.core.lifecycle.ReflectionLifecycleStrategy\n" +
+                "    methodNames\n" +
+                "      stringstartstring\n" +
+                "      stringstopstring\n" +
+                "      stringdisposestring\n" +
+                "    methodNames\n" +
+                "    componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor reference=/PICO/lifecycleStrategy/componentMonitor\n" +
+                "PICO",foo);
+    }
+
+
+    @Test public void testWithConsoleMonitor() {
+        MutableContainer mpc = new ContainerBuilder().withConsoleMonitor().build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                "  componentFactory=org.apache.composer.core.injectors.AdaptingInjection\n" +
+                "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                "  componentMonitor=org.apache.composer.core.monitors.ConsoleComponentMonitor\n" +
+                "    delegate=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                "PICO",foo);
+    }
+
+    @Test public void testWithConsoleMonitorAndLifecycleUseTheSameUltimateMonitor() {
+        MutableContainer mpc = new ContainerBuilder().withLifecycle().withConsoleMonitor().build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                     "  componentFactory=org.apache.composer.core.injectors.AdaptingInjection\n" +
+                     "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                     "  lifecycleStrategy=org.apache.composer.core.lifecycle.StartableLifecycleStrategy\n" +
+                     "    componentMonitor=org.apache.composer.core.monitors.ConsoleComponentMonitor\n" +
+                     "      delegate=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                     "  componentMonitor=org.apache.composer.core.monitors.ConsoleComponentMonitor reference=/PICO/lifecycleStrategy/componentMonitor\n" +
+                     "PICO",foo);
+    }
+
+
+    @Test public void testWithCustomMonitorByClass() {
+        MutableContainer mpc = new ContainerBuilder().withMonitor(ConsoleComponentMonitor.class).build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                "  componentFactory=org.apache.composer.core.injectors.AdaptingInjection\n" +
+                "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                "  componentMonitor=org.apache.composer.core.monitors.ConsoleComponentMonitor\n" +
+                "    delegate=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                "PICO",foo);
+    }
+
+    @SuppressWarnings({ "unchecked" })
+    @Test public void testWithBogusCustomMonitorByClass() {
+        // We do unchecked assignment so we test what its really doing, and smart IDE's don't complain
+        try {
+            Class aClass = HashMap.class;
+            new ContainerBuilder().withMonitor(aClass).build();
+            fail("should have barfed");
+        } catch (ClassCastException e) {
+            // expected
+        }
+    }
+
+    @Test public void testWithImplementationHiding() {
+        MutableContainer mpc = new ContainerBuilder().withHiddenImplementations().build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                "  componentFactory=org.apache.composer.core.behaviors.ImplementationHiding\n" +
+                "    delegate=org.apache.composer.core.injectors.AdaptingInjection\n" +
+                "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                "PICO",foo);
+    }
+
+    @Test public void testWithImplementationHidingInstance() {
+        MutableContainer mpc = new ContainerBuilder().withComponentFactory(new ImplementationHiding()).build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                "  componentFactory=org.apache.composer.core.behaviors.ImplementationHiding\n" +
+                "    delegate=org.apache.composer.core.injectors.AdaptingInjection\n" +
+                "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                "PICO",foo);
+    }
+
+    @Test public void testWithCafsListChainThingy() {
+        MutableContainer mpc = new ContainerBuilder(SDI()).withBehaviors(caching(), synchronizing(), implementationHiding()).build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                "  componentFactory=org.apache.composer.core.behaviors.Caching\n" +
+                "    delegate=org.apache.composer.core.behaviors.Synchronizing\n" +
+                "      delegate=org.apache.composer.core.behaviors.ImplementationHiding\n" +
+                "        delegate=org.apache.composer.core.injectors.SetterInjection\n" +
+                "          set\n" +
+                "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                "PICO",foo);
+    }
+
+
+    public static class CustomParentcontainer extends EmptyContainer {}
+
+    @Test public void testWithCustomParentContainer() {
+        MutableContainer mpc = new ContainerBuilder(new CustomParentcontainer()).build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                "  componentFactory=org.apache.composer.core.injectors.AdaptingInjection\n" +
+                "  parent=org.apache.composer.core.ContainerBuilderTestCase_CustomParentcontainer\n" +
+                "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                "PICO",foo);
+    }
+
+    @Test public void testWithBogusParentContainerBehavesAsIfNotSet() {
+        MutableContainer mpc = new ContainerBuilder((Container)null).build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                     "  componentFactory=org.apache.composer.core.injectors.AdaptingInjection\n" +
+                     "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                     "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                     "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                     "PICO", foo);
+    }
+
+
+    @Test public void testWithSetterDI() {
+        MutableContainer mpc = new ContainerBuilder().withSetterInjection().build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                "  componentFactory=org.apache.composer.core.injectors.SetterInjection\n" +
+                "    set\n" +
+                "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                "PICO",foo);
+    }
+
+    @Test public void testWithAnnotatedMethodDI() {
+            MutableContainer mpc = new ContainerBuilder().withAnnotatedMethodInjection().build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                "  componentFactory=org.apache.composer.core.injectors.AnnotatedMethodInjection\n" +
+                "    org.apache.composer.core.annotations.Inject\n" +
+                "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                "PICO",foo);
+    }
+
+    @Test public void testWithAnnotatedFieldDI() {
+            MutableContainer mpc = new ContainerBuilder().withAnnotatedFieldInjection().build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                "  componentFactory=org.apache.composer.core.injectors.AnnotatedFieldInjection\n" +
+                "    org.apache.composer.core.annotations.Inject\n" +
+                "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                "PICO",foo);
+    }
+
+    @Test public void testWithCtorDI() {
+        MutableContainer mpc = new ContainerBuilder().withConstructorInjection().build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                "  componentFactory=org.apache.composer.core.injectors.ConstructorInjection\n" +
+                "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                "PICO",foo);
+    }
+
+    @Test public void testWithImplementationHidingAndSetterDI() {
+        MutableContainer mpc = new ContainerBuilder().withHiddenImplementations().withSetterInjection().build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                "  componentFactory=org.apache.composer.core.behaviors.ImplementationHiding\n" +
+                "    delegate=org.apache.composer.core.injectors.SetterInjection\n" +
+                "      set\n" +
+                "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                "PICO",foo);
+    }
+
+    @Test public void testWithCachingImplementationHidingAndSetterDI() {
+        MutableContainer mpc = new ContainerBuilder().withCaching().withHiddenImplementations().withSetterInjection().build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                "  componentFactory=org.apache.composer.core.behaviors.Caching\n" +
+                "    delegate=org.apache.composer.core.behaviors.ImplementationHiding\n" +
+                "      delegate=org.apache.composer.core.injectors.SetterInjection\n" +
+                "        set\n" +                
+                "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                "PICO",foo);
+    }
+
+    @Test public void testWithSynchronizing() {
+        MutableContainer mpc = new ContainerBuilder().withSynchronizing().build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                "  componentFactory=org.apache.composer.core.behaviors.Synchronizing\n" +
+                "    delegate=org.apache.composer.core.injectors.AdaptingInjection\n" +
+                "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                "PICO",foo);
+    }
+
+    @Test public void testWithLocking() {
+        MutableContainer mpc = new ContainerBuilder().withLocking().build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                "  componentFactory=org.apache.composer.core.behaviors.Locking\n" +
+                "    delegate=org.apache.composer.core.injectors.AdaptingInjection\n" +
+                "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                "PICO",foo);
+    }
+
+    @Test public void testWithPropertyApplier() {
+        MutableContainer mpc = new ContainerBuilder().withPropertyApplier().build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                     "  componentFactory=org.apache.composer.core.behaviors.PropertyApplying\n" +
+                     "    delegate=org.apache.composer.core.injectors.AdaptingInjection\n" +
+                     "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                     "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                     "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                     "PICO",foo);
+    }
+
+    //TODO - fix up to refer to SomeContainerDependency
+    @Test public void testWithCustomComponentFactory() {
+        MutableContainer mpc = new ContainerBuilder().withCustomContainerComponent(new SomeContainerDependency()).withComponentFactory(CustomComponentFactory.class).build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("PICO\n" +
+                     "  componentFactory=org.apache.composer.core.ContainerBuilderTestCase_CustomComponentFactory\n" +
+                     "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                     "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                     "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                     "PICO",foo);
+    }
+
+    public static class SomeContainerDependency {
+    }
+    public static class CustomComponentFactory implements ComponentFactory {
+
+        @SuppressWarnings({ "UnusedDeclaration" })
+        public CustomComponentFactory(SomeContainerDependency someDependency) {
+        }
+
+        public ComponentAdapter createComponentAdapter(ComponentMonitor componentMonitor,
+                                                       LifecycleStrategy lifecycleStrategy,
+                                                       Properties componentProperties,
+                                                       Object componentKey,
+                                                       Class componentImplementation,
+                                                       Parameter... parameters) throws CompositionException {
+            return null;
+        }
+    }
+
+
+    @Test public void testWithCustomPicoContainer() {
+        MutableContainer mpc = new ContainerBuilder().implementedBy(TestContainer.class).build();
+        String foo = simplifyRepresentation(mpc);
+        assertEquals("org.apache.composer.core.ContainerBuilderTestCase_-TestContainer\n" +
+                "  componentFactory=org.apache.composer.core.injectors.AdaptingInjection\n" +
+                "  parent=org.apache.composer.core.containers.EmptyContainer\n" +
+                "  lifecycleStrategy=org.apache.composer.core.lifecycle.NullLifecycleStrategy\n" +
+                "  componentMonitor=org.apache.composer.core.monitors.NullComponentMonitor\n" +
+                "org.apache.composer.core.ContainerBuilderTestCase_-TestContainer",foo);
+    }
+
+
+    public static class TestContainer extends DefaultContainer {
+        public TestContainer(ComponentFactory componentFactory, ComponentMonitor monitor, LifecycleStrategy lifecycleStrategy, Container parent) {
+            super(componentFactory, lifecycleStrategy, parent, monitor);
+        }
+    }
+
+
+    private String simplifyRepresentation(MutableContainer mpc) {
+        String foo = xs.toXML(mpc);
+        foo = foo.replace('$','_');
+        foo = foo.replaceAll("/>","");
+        foo = foo.replaceAll("</","");
+        foo = foo.replaceAll("<","");
+        foo = foo.replaceAll(">","");
+        foo = foo.replaceAll("\n  startedComponentAdapters","");
+        foo = foo.replaceAll("\n  componentKeyToAdapterCache","");
+        foo = foo.replaceAll("\n  componentAdapters","");
+        foo = foo.replaceAll("\n  orderedComponentAdapters","");
+        foo = foo.replaceAll("\n  childrenStarted","");
+        foo = foo.replaceAll("\n  handler","");
+        foo = foo.replaceAll("\n  children","");
+        foo = foo.replaceAll("injectionAnnotation","");
+        foo = foo.replaceAll("setterMethodPrefix","");
+        foo = foo.replaceAll("lifecycleState","");
+        for (LifecycleState eachState : LifecycleState.values()) {
+            foo = foo.replaceAll("\n  " + eachState.name(), "");        	
+        }
+        foo = foo.replaceAll("\n  lifecycleStrategy\n","\n");
+        foo = foo.replaceAll("\n  componentMonitor\n","\n");
+        foo = foo.replaceAll("\n    componentMonitor\n","\n");
+        foo = foo.replaceAll("\n  delegate\n","\n");
+        foo = foo.replaceAll("\n    useNames\n","\n");
+        foo = foo.replaceAll("\n    delegate\n","\n");
+        foo = foo.replaceAll("\n      delegate\n","\n");
+        foo = foo.replaceAll("\n        delegate\n","\n");
+        foo = foo.replaceAll("\n  componentCharacteristic class=\"org.apache.composer.core.DefaultPicoContainer$1\"","");
+        foo = foo.replaceAll("\n  componentProperties","");
+        foo = foo.replaceAll("\n    startedComponentAdapters","");
+        foo = foo.replaceAll("\"class=","\"\nclass=");
+        foo = foo.replaceAll("\n  componentFactory\n","\n");
+        foo = foo.replaceAll("\n  lifecycleManager","");
+        foo = foo.replaceAll("class=\"org.apache.composer.core.DefaultPicoContainer_1\"","");
+        foo = foo.replaceAll("class=","=");
+        foo = foo.replaceAll("\"","");
+        foo = foo.replaceAll(" \n","\n");
+        foo = foo.replaceAll(" =","=");
+        foo = foo.replaceAll("\n\n","\n");
+
+        return foo;
+    }
+
+
+}

Added: incubator/composer/core/src/test/org/apache/composer/core/DefaultContainerTestCase.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/test/org/apache/composer/core/DefaultContainerTestCase.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/test/org/apache/composer/core/DefaultContainerTestCase.java (added)
+++ incubator/composer/core/src/test/org/apache/composer/core/DefaultContainerTestCase.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,741 @@
+/*****************************************************************************
+ * Copyright (c) PicoContainer Organization. All rights reserved.            *
+ * ------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the BSD      *
+ * style license a copy of which has been included with this distribution in *
+ * the LICENSE.txt file.                                                     *
+ *                                                                           *
+ * Idea by Rachel Davies, Original code by Aslak Hellesoy and Paul Hammant   *
+ *****************************************************************************/
+package org.apache.composer.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.apache.composer.core.Characteristics.CDI;
+import static org.apache.composer.core.Characteristics.SDI;
+
+import java.io.Serializable;
+import java.io.StringWriter;
+import java.lang.reflect.Member;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.junit.Test;
+import org.apache.composer.core.behaviors.Caching;
+import org.apache.composer.core.containers.EmptyContainer;
+import org.apache.composer.core.injectors.AbstractInjector;
+import org.apache.composer.core.injectors.ConstructorInjection;
+import org.apache.composer.core.injectors.ConstructorInjector;
+import org.apache.composer.core.lifecycle.NullLifecycleStrategy;
+import org.apache.composer.core.monitors.NullComponentMonitor;
+import org.apache.composer.core.monitors.WriterComponentMonitor;
+import org.apache.composer.core.tck.AbstractContainerTest;
+import org.apache.composer.core.testmodel.DecoratedTouchable;
+import org.apache.composer.core.testmodel.DependsOnTouchable;
+import org.apache.composer.core.testmodel.SimpleTouchable;
+import org.apache.composer.core.testmodel.Touchable;
+
+/**
+ * @author Aslak Helles&oslash;y
+ * @author Paul Hammant
+ * @author Ward Cunningham
+ * @author Mauro Talevi
+ */
+public final class DefaultContainerTestCase extends
+        AbstractContainerTest {
+
+	protected MutableContainer createPicoContainer(Container parent) {
+		return new DefaultContainer(parent);
+	}
+
+	protected Properties[] getProperties() {
+		return new Properties[0];
+	}
+
+	@Test public void testInstantiationWithNullComponentFactory() {
+		try {
+			new DefaultContainer((ComponentFactory) null, null);
+			fail("NPE expected");
+		} catch (NullPointerException e) {
+			// expected
+		}
+	}
+
+	@Test public void testUpDownDependenciesCannotBeFollowed() {
+		MutableContainer parent = createPicoContainer(null);
+		MutableContainer child = createPicoContainer(parent);
+
+		// ComponentF -> ComponentA -> ComponentB+C
+		child.addComponent(ComponentF.class);
+		parent.addComponent(ComponentA.class);
+		child.addComponent(ComponentB.class);
+		child.addComponent(ComponentC.class);
+
+		try {
+			child.getComponent(ComponentF.class);
+			fail("Thrown "
+					+ AbstractInjector.UnsatisfiableDependenciesException.class
+							.getName() + " expected");
+		} catch (final AbstractInjector.UnsatisfiableDependenciesException e) {
+			assertEquals(ComponentB.class, e.getUnsatisfiedDependencyType());
+		}
+	}
+
+	@Test public void testComponentsCanBeRemovedByInstance() {
+		MutableContainer pico = createPicoContainer(null);
+		pico.addComponent(HashMap.class);
+		pico.addComponent(ArrayList.class);
+		List list = pico.getComponent(List.class);
+		pico.removeComponentByInstance(list);
+		assertEquals(1, pico.getComponentAdapters().size());
+		assertEquals(1, pico.getComponents().size());
+		assertEquals(HashMap.class, pico.getComponent(Serializable.class)
+				.getClass());
+	}
+
+	@Test public void testComponentInstancesListIsReturnedForNullType() {
+		MutableContainer pico = createPicoContainer(null);
+		List componentInstances = pico.getComponents(null);
+		assertNotNull(componentInstances);
+		assertEquals(0, componentInstances.size());
+	}
+
+	@Test public void testComponentsWithCommonSupertypeWhichIsAConstructorArgumentCanBeLookedUpByConcreteType() {
+		MutableContainer pico = createPicoContainer(null);
+		pico.addComponent(LinkedList.class, LinkedList.class, Parameter.ZERO);
+		pico.addComponent(ArrayList.class);
+		assertEquals(ArrayList.class, pico
+				.getComponent((Class) ArrayList.class).getClass());
+	}
+
+	/*
+	 * When pico tries to resolve DecoratedTouchable it find as dependency
+	 * itself and SimpleTouchable. Problem is basically the same as above. Pico
+	 * should not consider self as solution.
+	 * 
+	 * JS fixed it ( PICO-222 ) KP
+	 */
+	@Test public void testUnambiguouSelfDependency() {
+		MutableContainer pico = createPicoContainer(null);
+		pico.addComponent(SimpleTouchable.class);
+		pico.addComponent(DecoratedTouchable.class);
+		Touchable t = (Touchable) pico
+				.getComponent((Object) DecoratedTouchable.class);
+		assertNotNull(t);
+	}
+
+	@Test public void testPicoUsedInBuilderStyle() {
+		MutableContainer pico = createPicoContainer(null);
+		Touchable t = pico.change(Characteristics.CACHE).addComponent(
+				SimpleTouchable.class).addComponent(DecoratedTouchable.class)
+				.getComponent(DecoratedTouchable.class);
+		SimpleTouchable t2 = pico.getComponent(SimpleTouchable.class);
+		assertNotNull(t);
+		assertNotNull(t2);
+		t.touch();
+		assertTrue(t2.wasTouched);
+	}
+
+	public static class Thingie {
+		public Thingie(List c) {
+			assertNotNull(c);
+		}
+	}
+
+	@Test public void testThangCanBeInstantiatedWithArrayList() {
+		MutableContainer pico = new DefaultContainer();
+		pico.addComponent(Thingie.class);
+		pico.addComponent(ArrayList.class);
+		assertNotNull(pico.getComponent(Thingie.class));
+	}
+
+	@Test public void testGetComponentAdaptersOfTypeNullReturnsEmptyList() {
+		DefaultContainer pico = new DefaultContainer();
+		List adapters = pico.getComponentAdapters(null);
+		assertNotNull(adapters);
+		assertEquals(0, adapters.size());
+	}
+
+	public static class Service {
+	}
+
+	public static final class TransientComponent {
+		private final Service service;
+
+		public TransientComponent(Service service) {
+			this.service = service;
+		}
+	}
+
+	@Test public void testDefaultPicoContainerReturnsNewInstanceForEachCallWhenUsingTransientComponentAdapter() {
+
+		DefaultContainer picoContainer = new DefaultContainer(
+				new Caching().wrap(new ConstructorInjection()));
+
+		picoContainer.addComponent(Service.class);
+		picoContainer.as(Characteristics.NO_CACHE).addAdapter(
+				new ConstructorInjector(TransientComponent.class,
+						TransientComponent.class, null,
+						new NullComponentMonitor(),
+						new NullLifecycleStrategy(), false));
+		TransientComponent c1 = picoContainer
+				.getComponent(TransientComponent.class);
+		TransientComponent c2 = picoContainer
+				.getComponent(TransientComponent.class);
+		assertNotSame(c1, c2);
+		assertSame(c1.service, c2.service);
+	}
+
+	public static class DependsOnCollection {
+		public DependsOnCollection(Collection c) {
+		}
+	}
+
+	@Test public void testShouldProvideInfoAboutDependingWhenAmbiguityHappens() {
+		MutableContainer pico = this.createPicoContainer(null);
+		pico.addComponent(new ArrayList());
+		pico.addComponent(new LinkedList());
+		pico.addComponent(DependsOnCollection.class);
+		try {
+			pico.getComponent(DependsOnCollection.class);
+			fail();
+		} catch (AbstractInjector.AmbiguousComponentResolutionException expected) {
+			String doc = DependsOnCollection.class.getName();
+			assertEquals(
+					"class "
+							+ doc
+							+ " needs a 'java.util.Collection' injected, but there are too many choices to inject. These:[class java.util.ArrayList, class java.util.LinkedList], refer http://picocontainer.org/ambiguous-injectable-help.html",
+					expected.getMessage());
+		}
+	}
+
+	@Test public void testInstantiationWithMonitorAndParent() {
+		StringWriter writer = new StringWriter();
+		ComponentMonitor monitor = new WriterComponentMonitor(writer);
+		DefaultContainer parent = new DefaultContainer();
+		DefaultContainer child = new DefaultContainer(monitor, parent);
+		parent.addComponent("st", SimpleTouchable.class);
+		child.addComponent("dot", DependsOnTouchable.class);
+		DependsOnTouchable dot = (DependsOnTouchable) child.getComponent("dot");
+		assertNotNull(dot);
+		assertTrue("writer not empty", writer.toString().length() > 0);
+	}
+
+	@Test public void testStartCapturedByMonitor() {
+		final StringBuffer sb = new StringBuffer();
+		DefaultContainer dpc = new DefaultContainer(
+				new NullComponentMonitor() {
+					public void invoking(Container container,
+							ComponentAdapter componentAdapter, Member member,
+							Object instance) {
+						sb.append(member.toString());
+					}
+				});
+		dpc.as(Characteristics.CACHE).addComponent(DefaultContainer.class);
+		dpc.start();
+		assertEquals(
+				"ComponentMonitor should have been notified that the component had been started",
+				"public abstract void org.apache.composer.core.Startable.start()", sb
+						.toString());
+	}
+
+	public static class StartableClazz implements Startable {
+		private MutableContainer _pico;
+
+		public void start() {
+			List<SimpleTouchable> cps = _pico
+					.getComponents(SimpleTouchable.class);
+			assertNotNull(cps);
+		}
+
+		public void stop() {
+		}
+
+	}
+
+	@Test public void testListComponentsOnStart() {
+
+		// This is really discouraged. Breaks basic principals of IoC -
+		// components should not refer
+		// to their containers
+		//
+		// Might be deleted in due coure, along with adaptersClone stuff in DPC
+
+		DefaultContainer dpc = new DefaultContainer();
+		dpc.addComponent(SimpleTouchable.class);
+		StartableClazz cl = new StartableClazz();
+		cl._pico = dpc;
+		dpc.addComponent(cl);
+		dpc.start();
+	}
+
+	@Test public void testCanChangeMonitor() {
+		StringWriter writer1 = new StringWriter();
+		ComponentMonitor monitor1 = new WriterComponentMonitor(writer1);
+		DefaultContainer pico = new DefaultContainer(monitor1);
+		pico.addComponent("t1", SimpleTouchable.class);
+		pico.addComponent("t3", SimpleTouchable.class);
+		Touchable t1 = (Touchable) pico.getComponent("t1");
+		assertNotNull(t1);
+		final String s = writer1.toString();
+		assertTrue("writer not empty", s.length() > 0);
+		StringWriter writer2 = new StringWriter();
+		ComponentMonitor monitor2 = new WriterComponentMonitor(writer2);
+		pico.changeMonitor(monitor2);
+		pico.addComponent("t2", SimpleTouchable.class);
+		Touchable t2 = (Touchable) pico.getComponent("t2");
+		assertNotNull(t2);
+		final String s2 = writer2.toString();
+		assertTrue("writer not empty", s2.length() > 0);
+		assertTrue("writers of same length",
+				writer1.toString().length() == writer2.toString().length());
+		Touchable t3 = (Touchable) pico.getComponent("t3");
+		assertNotNull(t3);
+		assertTrue("old writer was used", writer1.toString().length() < writer2
+				.toString().length());
+	}
+
+	@Test public void testCanChangeMonitorOfChildContainers() {
+		StringWriter writer1 = new StringWriter();
+		ComponentMonitor monitor1 = new WriterComponentMonitor(writer1);
+		DefaultContainer parent = new DefaultContainer();
+		DefaultContainer child = new DefaultContainer(monitor1);
+		parent.addChildContainer(child);
+		child.addComponent("t1", SimpleTouchable.class);
+		child.addComponent("t3", SimpleTouchable.class);
+		Touchable t1 = (Touchable) child.getComponent("t1");
+		assertNotNull(t1);
+		assertTrue("writer not empty", writer1.toString().length() > 0);
+		StringWriter writer2 = new StringWriter();
+		ComponentMonitor monitor2 = new WriterComponentMonitor(writer2);
+		parent.changeMonitor(monitor2);
+		child.addComponent("t2", SimpleTouchable.class);
+		Touchable t2 = (Touchable) child.getComponent("t2");
+		assertNotNull(t2);
+		assertTrue("writer not empty", writer2.toString().length() > 0);
+		String s1 = writer1.toString();
+		String s2 = writer2.toString();
+		assertTrue("writers of same length", s1.length() == s2.length());
+		Touchable t3 = (Touchable) child.getComponent("t3");
+		assertNotNull(t3);
+		assertTrue("old writer was used", writer1.toString().length() < writer2
+				.toString().length());
+	}
+
+	@Test public void testChangeMonitorIsIgnoredIfNotSupportingStrategy() {
+		StringWriter writer = new StringWriter();
+		ComponentMonitor monitor = new WriterComponentMonitor(writer);
+		DefaultContainer parent = new DefaultContainer(
+				new ComponentFactoryWithNoMonitor(
+						new ComponentAdapterWithNoMonitor(new SimpleTouchable())));
+		parent.addChildContainer(new EmptyContainer());
+		parent.addComponent("t1", SimpleTouchable.class);
+		parent.changeMonitor(monitor);
+		assertTrue("writer empty", writer.toString().length() == 0);
+	}
+
+	@Test public void testCanReturnCurrentMonitorFromComponentFactory() {
+		StringWriter writer1 = new StringWriter();
+		ComponentMonitor monitor1 = new WriterComponentMonitor(writer1);
+		DefaultContainer pico = new DefaultContainer(monitor1);
+		assertEquals(monitor1, pico.currentMonitor());
+		StringWriter writer2 = new StringWriter();
+		ComponentMonitor monitor2 = new WriterComponentMonitor(writer2);
+		pico.changeMonitor(monitor2);
+		assertEquals(monitor2, pico.currentMonitor());
+	}
+
+	private static final class ComponentFactoryWithNoMonitor implements
+			ComponentFactory {
+		private final ComponentAdapter adapter;
+
+		public ComponentFactoryWithNoMonitor(ComponentAdapter adapter) {
+			this.adapter = adapter;
+		}
+
+		public ComponentAdapter createComponentAdapter(
+				ComponentMonitor componentMonitor,
+				LifecycleStrategy lifecycleStrategy,
+				Properties componentProperties, Object componentKey,
+				Class componentImplementation, Parameter... parameters)
+				throws CompositionException {
+			return adapter;
+		}
+	}
+
+	private static final class ComponentAdapterWithNoMonitor implements
+			ComponentAdapter {
+		private final Object instance;
+
+		public ComponentAdapterWithNoMonitor(Object instance) {
+			this.instance = instance;
+		}
+
+		public Object getComponentKey() {
+			return instance.getClass();
+		}
+
+		public Class getComponentImplementation() {
+			return instance.getClass();
+		}
+
+		public Object getComponentInstance(Container container)
+				throws CompositionException {
+			return instance;
+		}
+
+		public void verify(Container container)
+				throws CompositionException {
+		}
+
+		public void accept(ContainerVisitor visitor) {
+		}
+
+		public ComponentAdapter getDelegate() {
+			return null;
+		}
+
+		public ComponentAdapter findAdapterOfType(Class componentAdapterType) {
+			return null;
+		}
+
+		public String getDescriptor() {
+			return null;
+		}
+
+	}
+
+	@Test public void testMakeChildContainer() {
+		MutableContainer parent = new DefaultContainer();
+		parent.addComponent("t1", SimpleTouchable.class);
+		MutableContainer child = parent.makeChildContainer();
+		Object t1 = child.getParent().getComponent("t1");
+		assertNotNull(t1);
+		assertTrue(t1 instanceof SimpleTouchable);
+	}
+
+	@Test public void testCanUseCustomLifecycleStrategyForClassRegistrations() {
+		DefaultContainer dpc = new DefaultContainer(
+				new FailingLifecycleStrategy(), null);
+		dpc.as(Characteristics.CACHE).addComponent(Startable.class,
+				MyStartable.class);
+		try {
+			dpc.start();
+			fail("should have barfed");
+		} catch (RuntimeException e) {
+			assertEquals("foo", e.getMessage());
+		}
+	}
+
+	@Test public void testCanUseCustomLifecycleStrategyForInstanceRegistrations() {
+		DefaultContainer dpc = new DefaultContainer(
+				new FailingLifecycleStrategy(), null);
+		Startable myStartable = new MyStartable();
+		dpc.addComponent(Startable.class, myStartable);
+		try {
+			dpc.start();
+			fail("should have barfed");
+		} catch (RuntimeException e) {
+			assertEquals("foo", e.getMessage());
+		}
+	}
+
+	public static class FailingLifecycleStrategy implements LifecycleStrategy {
+		public void start(Object component) {
+			throw new RuntimeException("foo");
+		}
+
+		public void stop(Object component) {
+		}
+
+		public void dispose(Object component) {
+		}
+
+		public boolean hasLifecycle(Class type) {
+			return true;
+		}
+
+	}
+
+	public static class MyStartable implements Startable {
+		public MyStartable() {
+		}
+
+		public void start() {
+		}
+
+		public void stop() {
+		}
+	}
+
+	public static interface A {
+
+	}
+
+	public static class SimpleA implements A {
+
+	}
+
+	public static class WrappingA implements A {
+		private final A wrapped;
+
+		public WrappingA(A wrapped) {
+			this.wrapped = wrapped;
+		}
+	}
+
+	@Test public void testCanRegisterTwoComponentsImplementingSameInterfaceOneWithInterfaceAsKey()
+			throws Exception {
+		MutableContainer container = createPicoContainer(null);
+
+		container.addComponent(SimpleA.class);
+		container.addComponent(A.class, WrappingA.class);
+
+		container.start();
+
+		assertEquals(WrappingA.class, container.getComponent(A.class)
+				.getClass());
+	}
+
+	@Test public void testCanRegisterTwoComponentsWithSameImplementionAndDifferentKey()
+			throws Exception {
+		MutableContainer container = createPicoContainer(null);
+
+		container.addComponent(SimpleA.class);
+		container.addComponent("A", SimpleA.class);
+
+		container.start();
+
+		assertNotNull(container.getComponent("A"));
+		assertNotNull(container.getComponent(SimpleA.class));
+		assertNotSame(container.getComponent("A"), container
+				.getComponent(SimpleA.class));
+	}
+
+	@Test public void testPicoCanDifferentiateBetweenNamedStringsThatWouldOtherwiseBeAmbiguous() {
+		MutableContainer mpc = createPicoContainer(null);
+		mpc.addComponent("greeting", "1");
+		mpc.addComponent("message", "2");
+		mpc.as(Characteristics.USE_NAMES).addComponent(
+				CompositionException.class, CompositionException.class);
+		assertEquals("2", mpc.getComponent(CompositionException.class)
+				.getMessage());
+	}
+
+	@Test public void testPicoCanDifferentiateBetweenNamedObjectsThatWouldOtherwiseBeAmbiguous() {
+		MutableContainer mpc = createPicoContainer(null);
+		Horse dobbin = new Horse();
+		Horse redRum = new Horse();
+		mpc.addComponent("dobbin", dobbin);
+		mpc.addComponent("horse", redRum);
+		mpc.as(Characteristics.USE_NAMES).addComponent(CdiTurtle.class);
+		assertEquals(redRum, mpc.getComponent(CdiTurtle.class).horse);
+	}
+
+	@Test public void testPicoCanDifferentiateBetweenNamedIntsThatWouldOtherwiseBeAmbiguous() {
+		MutableContainer mpc = createPicoContainer(null);
+		mpc.addComponent("one", 1);
+		mpc.addComponent("two", 2);
+		mpc.as(Characteristics.USE_NAMES).addComponent(NeedsTwo.class);
+		assertEquals(2, mpc.getComponent(NeedsTwo.class).two);
+	}
+
+	public static class ListComponentsInStartClass implements Startable {
+		private MutableContainer _pico;
+
+		public void start() {
+			List<SimpleTouchable> cps = _pico
+					.getComponents(SimpleTouchable.class);
+			assertNotNull(cps);
+		}
+
+		public void stop() {
+		}
+
+	}
+
+	/**
+	 * JIRA: PICO-295 reported by Erik Putrycz
+	 */
+	@Test public void testListComponentsInStart() {
+		DefaultContainer dpc = new DefaultContainer();
+		dpc.addComponent(SimpleTouchable.class);
+		ListComponentsInStartClass cl = new ListComponentsInStartClass();
+		cl._pico = dpc;
+		dpc.addComponent(cl);
+		dpc.start();
+	}
+
+	public static class NeedsTwo {
+		private final int two;
+
+		public NeedsTwo(Integer two) {
+			this.two = two;
+		}
+	}
+
+	public static class Horse {
+	}
+
+	public static class CdiTurtle {
+		public final Horse horse;
+
+		public CdiTurtle(Horse horse) {
+			this.horse = horse;
+		}
+	}
+
+	public static class SdiDonkey {
+		public Horse horse;
+
+		public void setHorse(Horse horse) {
+			this.horse = horse;
+		}
+	}
+
+	public static class SdiRabbit {
+		public Horse horse;
+
+		public void setHorse(Horse horse) {
+			this.horse = horse;
+		}
+	}
+
+	@Test public void testMixingOfSDIandCDI() {
+
+		MutableContainer container = createPicoContainer(null).change(
+				Characteristics.CACHE);
+		container.addComponent(Horse.class);
+		container.change(SDI);
+		container.addComponent(SdiDonkey.class);
+		container.addComponent(SdiRabbit.class);
+		container.change(CDI);
+		container.addComponent(CdiTurtle.class);
+
+		SdiDonkey donkey = container.getComponent(SdiDonkey.class);
+		SdiRabbit rabbit = container.getComponent(SdiRabbit.class);
+		CdiTurtle turtle = container.getComponent(CdiTurtle.class);
+
+		assertions(donkey, rabbit, turtle);
+	}
+
+	@Test public void testMixingOfSDIandCDIDifferently() {
+
+		MutableContainer container = createPicoContainer(null).change(
+				Characteristics.CACHE);
+		container.addComponent(Horse.class);
+		container.addComponent(CdiTurtle.class);
+		container.change(SDI);
+		container.addComponent(SdiDonkey.class);
+		container.addComponent(SdiRabbit.class);
+
+		SdiDonkey donkey = container.getComponent(SdiDonkey.class);
+		SdiRabbit rabbit = container.getComponent(SdiRabbit.class);
+		CdiTurtle turtle = container.getComponent(CdiTurtle.class);
+
+		assertions(donkey, rabbit, turtle);
+	}
+
+	@Test public void testMixingOfSDIandCDIInBuilderStyle() {
+
+		MutableContainer container = createPicoContainer(null).change(
+				Characteristics.CACHE);
+		container.addComponent(Horse.class).change(SDI).addComponent(
+				SdiDonkey.class).addComponent(SdiRabbit.class).change(CDI)
+				.addComponent(CdiTurtle.class);
+
+		SdiDonkey donkey = container.getComponent(SdiDonkey.class);
+		SdiRabbit rabbit = container.getComponent(SdiRabbit.class);
+		CdiTurtle turtle = container.getComponent(CdiTurtle.class);
+
+		assertions(donkey, rabbit, turtle);
+	}
+
+	private void assertions(SdiDonkey donkey, SdiRabbit rabbit, CdiTurtle turtle) {
+		assertNotNull(rabbit);
+		assertNotNull(donkey);
+		assertNotNull(turtle);
+		assertNotNull(turtle.horse);
+		assertNotNull(donkey.horse);
+		assertNotNull(rabbit.horse);
+		assertSame(donkey.horse, turtle.horse);
+		assertSame(rabbit.horse, turtle.horse);
+	}
+
+	@Test public void testMixingOfSDIandCDIWithTemporaryCharacterizations() {
+
+		MutableContainer container = createPicoContainer(null).change(
+				Characteristics.CACHE);
+		container.addComponent(Horse.class);
+		container.addComponent(CdiTurtle.class);
+		container.as(SDI).addComponent(SdiDonkey.class);
+		container.as(SDI).addComponent(SdiRabbit.class);
+
+		SdiDonkey donkey = container.getComponent(SdiDonkey.class);
+		SdiRabbit rabbit = container.getComponent(SdiRabbit.class);
+		CdiTurtle turtle = container.getComponent(CdiTurtle.class);
+
+		assertions(donkey, rabbit, turtle);
+	}
+
+	@Test public void testMixingOfSDIandCDIWithTemporaryCharacterizationsDifferently() {
+
+		MutableContainer container = createPicoContainer(null).change(
+				Characteristics.CACHE);
+		container.as(SDI).addComponent(SdiDonkey.class);
+		container.as(SDI).addComponent(SdiRabbit.class);
+		container.addComponent(Horse.class);
+		container.addComponent(CdiTurtle.class);
+
+		SdiDonkey donkey = container.getComponent(SdiDonkey.class);
+		SdiRabbit rabbit = container.getComponent(SdiRabbit.class);
+		CdiTurtle turtle = container.getComponent(CdiTurtle.class);
+
+		assertions(donkey, rabbit, turtle);
+	}
+
+	@Test public void testNoComponentIsMonitoredAndPotentiallyLateProvided() {
+		final String[] missingKey = new String[1];
+
+		String foo = (String) new DefaultContainer(
+				new NullComponentMonitor() {
+					public Object noComponentFound(
+							MutableContainer container, Object componentKey) {
+						missingKey[0] = (String) componentKey;
+						return "foo";
+					}
+				}).getComponent("missingKey");
+
+		assertNotNull(missingKey[0]);
+		assertEquals("missingKey", missingKey[0]);
+		assertEquals("foo", foo);
+
+	}
+
+	@Test public void testThatComponentCannotBeRemovedFromStartedContainer() {
+		MutableContainer container = createPicoContainer(null);
+		container.addComponent(Map.class, HashMap.class);
+		container.start();
+		try {
+			container.removeComponent(Map.class);
+			fail("should have barfed");
+		} catch (CompositionException e) {
+		}
+	}
+
+	@Test public void testThatSimpleStringComponentIsAddedOnlyOnce() {
+		MutableContainer container = createPicoContainer(null);
+		container.addComponent("foo bar");
+		assertEquals(1, container.getComponentAdapters().size());
+	}
+
+}
\ No newline at end of file

Added: incubator/composer/core/src/test/org/apache/composer/core/adapters/ComponentAdapterTestCase.java
URL: http://svn.apache.org/viewvc/incubator/composer/core/src/test/org/apache/composer/core/adapters/ComponentAdapterTestCase.java?rev=613775&view=auto
==============================================================================
--- incubator/composer/core/src/test/org/apache/composer/core/adapters/ComponentAdapterTestCase.java (added)
+++ incubator/composer/core/src/test/org/apache/composer/core/adapters/ComponentAdapterTestCase.java Sun Jan 20 22:41:26 2008
@@ -0,0 +1,147 @@
+/*****************************************************************************
+ * Copyright (C) PicoContainer Organization. All rights reserved.            *
+ * ------------------------------------------------------------------------- *
+ * The software in this package is published under the terms of the BSD      *
+ * style license a copy of which has been included with this distribution in *
+ * the LICENSE.txt file.                                                     *
+ *****************************************************************************/
+package org.apache.composer.core.adapters;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.lang.reflect.Constructor;
+
+import org.junit.Test;
+import org.apache.composer.core.ComponentAdapter;
+import org.apache.composer.core.ComponentMonitor;
+import org.apache.composer.core.Parameter;
+import org.apache.composer.core.CompositionException;
+import org.apache.composer.core.Container;
+import org.apache.composer.core.ComposerVerificationException;
+import org.apache.composer.core.ContainerVisitor;
+import org.apache.composer.core.injectors.AbstractInjector;
+import org.apache.composer.core.lifecycle.NullLifecycleStrategy;
+import org.apache.composer.core.monitors.NullComponentMonitor;
+import org.apache.composer.core.parameters.ConstantParameter;
+
+/**
+ * Test AbstractAdapter behaviour
+ * @author J&ouml;rg Schaible
+ */
+public class ComponentAdapterTestCase {
+
+    @SuppressWarnings("serial")
+	private static class TestAdapter<T> extends AbstractAdapter<T> {
+    	
+        TestAdapter(Object componentKey, Class<T> componentImplementation, ComponentMonitor componentMonitor) {
+            super(componentKey, componentImplementation, componentMonitor);
+        }
+        TestAdapter(Object componentKey, Class<T> componentImplementation) {
+            super(componentKey, componentImplementation);
+        }
+        public T getComponentInstance(Container container) throws CompositionException {
+            return null;
+        }
+        public void verify(Container container) throws ComposerVerificationException {
+        }
+
+        public String getDescriptor() {
+            return TestAdapter.class.getName() + ":" ;
+        }
+    }
+
+    @SuppressWarnings("serial")
+	private static class TestMonitoringComponentAdapter<T> extends AbstractAdapter<T> {
+        TestMonitoringComponentAdapter(ComponentMonitor componentMonitor) {
+            super(null, null, componentMonitor);
+        }
+        public T getComponentInstance(Container container) throws CompositionException {
+            return null;
+        }
+        public void verify(Container container) throws ComposerVerificationException {
+        }
+        public Object getComponentKey() {
+            return null;
+        }
+        public Class<T> getComponentImplementation() {
+            return null;
+        }
+        public void accept(ContainerVisitor visitor) {
+        }
+
+        public String getDescriptor() {
+            return null;
+        }
+    }
+    
+    @SuppressWarnings("serial")
+	private static class TestInstantiatingAdapter<T> extends AbstractInjector<T> {
+        TestInstantiatingAdapter(Object componentKey, Class<T> componentImplementation, Parameter... parameters) {
+            super(componentKey, componentImplementation, parameters, new NullComponentMonitor(), new NullLifecycleStrategy(), false);
+        }
+        protected Constructor<T> getGreediestSatisfiableConstructor(Container container) throws CompositionException {
+            return null;
+        }
+
+        public void verify(Container container) throws CompositionException {
+        }
+
+        public T getComponentInstance(Container container) throws CompositionException {
+            return null;
+        }
+
+        public String getDescriptor() {
+            return null;
+        }
+    }
+    
+    @Test public void testComponentImplementationMayNotBeNull() {
+        try {
+            new TestAdapter<Object>("Key", null);
+            fail("NullPointerException expected");
+        } catch (NullPointerException e) {
+            assertEquals("componentImplementation", e.getMessage());
+        }
+    }
+
+    @Test public void testComponentKeyCanBeNullButNotRequested() {
+        ComponentAdapter<String> componentAdapter = new TestAdapter<String>(null, String.class);
+        try {
+            componentAdapter.getComponentKey();
+            fail("NullPointerException expected");
+        } catch (NullPointerException e) {
+            assertEquals("componentKey", e.getMessage());
+        }
+    }
+
+    @Test public void testComponentMonitorMayNotBeNull() {
+        try {
+            new TestAdapter<String>("Key", String.class, null);
+            fail("NullPointerException expected");
+        } catch (NullPointerException e) {
+            assertEquals("ComponentMonitor==null", e.getMessage());
+        }
+        try {
+            new TestMonitoringComponentAdapter<Object>(null);
+            fail("NullPointerException expected");
+        } catch (NullPointerException e) {
+            assertEquals("ComponentMonitor==null", e.getMessage());
+        }
+    }
+
+    @Test public void testParameterMayNotBeNull() throws Exception {
+        try {
+            new TestInstantiatingAdapter<String>("Key", String.class, new Parameter[]{new ConstantParameter("Value"), null});
+            fail("Thrown " + NullPointerException.class.getName() + " expected");
+        } catch (final NullPointerException e) {
+            assertTrue(e.getMessage().endsWith("1 is null"));
+        }
+    }
+    
+    @Test public void testStringRepresentation() {
+        ComponentAdapter<Integer> componentAdapter = new TestAdapter<Integer>("Key", Integer.class);
+        assertEquals(TestAdapter.class.getName() + ":Key", componentAdapter.toString());
+    }
+}



Mime
View raw message