001/*****************************************************************************
002 * Copyright (C) PicoContainer Organization. All rights reserved.            *
003 * ------------------------------------------------------------------------- *
004 * The software in this package is published under the terms of the BSD      *
005 * style license a copy of which has been included with this distribution in *
006 * the LICENSE.txt file.                                                     *
007 *                                                                           *
008 * Original code by                                                          *
009 *****************************************************************************/
010package org.picocontainer.alternatives.issues;
011
012import org.junit.Test;
013import org.picocontainer.DefaultPicoContainer;
014import org.picocontainer.MutablePicoContainer;
015import org.picocontainer.behaviors.ImplementationHiding;
016import org.picocontainer.injectors.ConstructorInjection;
017import org.picocontainer.visitors.VerifyingVisitor;
018
019public class Issue0214TestCase {
020
021    // This bug as described in the bug report, http://jira.codehaus.org/browse/PICO-214, cannot be reproduced.
022    @Test public void testTheBug() {
023        final MutablePicoContainer pico = new DefaultPicoContainer(new ImplementationHiding().wrap(new ConstructorInjection()));
024        pico.addComponent(A.class);
025
026        /* This is a workaround for the bug described further down. Normally
027         * this method call should only be needed if specific requirements for
028         * parameters exist, but not if PicoContainer shall resolve the
029         * dependencies itself. However, with ImplementationHidingPicoContainer
030         * this is currently the only way to register a class/interface such
031         * that the automatic resolution works.
032         */
033        pico.addComponent(I1.class, B.class);
034
035        /* The following addAdapter(Object, Class) of
036         * ImplementationHidingPicoContainer is buggy, as it contains
037         * "ComponentAdapter delegate = componentFactory.createComponentAdapter(componentKey,
038         * componentImplementation, new Parameter[0]);". Instead of "new
039         * Parameter[0]" it should be "null" to have a behaviour consistent to
040         * DefaultPicoContainer, i.e. if PicoContainer shall resolve
041         * dependencies itself.
042         */
043        pico.addComponent(I2.class, C.class);
044
045        /* The following verify() throws the exception, but is expected not to
046         * throw: "org.picocontainer.PicoVerificationException:
047         * [[org.picocontainer.PicoCompositionException: Either do the
048         * specified parameters not match any of the following constructors:
049         * [public PicoContainerBugTest$C(PicoContainerBugTest$A)] or the
050         * constructors were not accessible for 'class
051         * PicoContainerBugTest$C']]".
052         *
053         * I believe that the error comes this way: In method
054         * getGreediestSatisfiableConstructor parameters are checked against
055         * null and if parameters is not null it is assumed that specific
056         * parameters have been given so that no automatic resolution takes
057         * place. As now during registration instead of "null" falsly "new
058         * Parameter[0]" was stored, this is now interpreted as if only the
059         * nullary constructor shall be used, and if that doesn't exist, the
060         * exception is thrown.
061         */
062        new VerifyingVisitor().traverse(pico);
063    }
064
065    public static interface I1 {
066    }
067
068    public static interface I2 {
069    }
070
071    public static class A {
072        public A() {
073        }
074    }
075
076    public static class B implements I1 {
077        public B(final A a) {
078        }
079    }
080
081    public static class C implements I2 {
082        public C(final A a) {
083        }
084    }
085}