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