PicoContainer
  1. PicoContainer
  2. PICO-202

GenericCollectionComponentAdapter with composite pattern

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 1.0
    • Fix Version/s: 1.1
    • Component/s: PicoContainer (Java)
    • Labels:
      None
    • Number of attachments :
      2

      Description

      I would like to use GenericCollectionComponentAdapter to inject a composite comp with an array of children components in an instance of the composite pattern. The attached patch has a couple of points:

      1. Before I could successfully resolve dependencies to the array I had to make the change to the GCCA to pass the collection type to the AbstractCA. I added the collectionType.isArray() check which seemed prudent. Original test case was modified to pass String[].class for the collection type and it still passes.

      2. For the second test case, I had to tweak the container config for a composite since the composite itself is an instance of the component I'm aggregating in the array. The test is more of an integration test since I'm using a container (I realize tests using the container are discouraged), but I wanted to test the container lookup logic with the GCCA present. In order to avoid the cyclic dependency of the array->CompositeComponent->array, I had to wrap a caching CA around the GCCA and pre-instantiate the array before registering the composite. Not ideal, but it works.

      Does this approach seem reasonable or is there a better way?

        Activity

        Nick Sieger made changes -
        Field Original Value New Value
        Attachment GenericCollectionComponentAdapter.patch [ 12745 ]
        Hide
        Nick Sieger added a comment -

        Cleaned up imports in the second version

        Show
        Nick Sieger added a comment - Cleaned up imports in the second version
        Nick Sieger made changes -
        Jörg Schaible made changes -
        Assignee Joerg Schaible [ joehni ]
        Hide
        Jörg Schaible added a comment -

        I did yesterday a quite similar modification to GenericCollectionCA in the MX_PROPOSAL branch. I'll have a look.

        Show
        Jörg Schaible added a comment - I did yesterday a quite similar modification to GenericCollectionCA in the MX_PROPOSAL branch. I'll have a look.
        Hide
        Nick Sieger added a comment -

        Another approach would be to register the child comps and the array/GCCA in a parent container and put the composite in a child container, but using two containers might seem like overkill.

        Show
        Nick Sieger added a comment - Another approach would be to register the child comps and the array/GCCA in a parent container and put the composite in a child container, but using two containers might seem like overkill.
        Hide
        Jörg Schaible added a comment -

        Not really. The arrays have to be generated on the fly, since they may change ... unless the container is read-only.

        Show
        Jörg Schaible added a comment - Not really. The arrays have to be generated on the fly, since they may change ... unless the container is read-only.
        Hide
        Nick Sieger added a comment -

        In my haste I didn't even realize that GCCA is a package-private class only used by the CICA! So the testInstantiateCompositeDependingOnComponentArrayRequiresPreInstantiationAndCaching case wouldn't even normally work. I still end up having to create the array manually and registering it as a component instance. I basically end up with this, which now does not even leverage GCCA:

        public void testInstantiateCompositeDependingOnComponentArrayRequiresPreInstantiationAndCaching() {
        MutablePicoContainer pc = new DefaultPicoContainer();
        pc.registerComponentImplementation(LeafComponent.class);
        pc.registerComponentInstance("apple");
        Collection comps = pc.getComponentInstancesOfType(Component.class);
        assertEquals(1, comps.size());
        pc.registerComponentInstance("x", comps.toArray());

        Object[] arr = (Object[]) pc.getComponentInstance("x");

        assertNotNull(arr);
        assertEquals(1, arr.length);

        pc.registerComponentImplementation(CompositeComponent.class,
        CompositeComponent.class,
        new Parameter[]

        {new ComponentParameter("x")}

        );

        Component cc = (Component) pc.getComponentInstance(CompositeComponent.class);

        assertNotNull(cc);
        assertEquals("apple", cc.toString());
        }

        Show
        Nick Sieger added a comment - In my haste I didn't even realize that GCCA is a package-private class only used by the CICA! So the testInstantiateCompositeDependingOnComponentArrayRequiresPreInstantiationAndCaching case wouldn't even normally work. I still end up having to create the array manually and registering it as a component instance. I basically end up with this, which now does not even leverage GCCA: public void testInstantiateCompositeDependingOnComponentArrayRequiresPreInstantiationAndCaching() { MutablePicoContainer pc = new DefaultPicoContainer(); pc.registerComponentImplementation(LeafComponent.class); pc.registerComponentInstance("apple"); Collection comps = pc.getComponentInstancesOfType(Component.class); assertEquals(1, comps.size()); pc.registerComponentInstance("x", comps.toArray()); Object[] arr = (Object[]) pc.getComponentInstance("x"); assertNotNull(arr); assertEquals(1, arr.length); pc.registerComponentImplementation(CompositeComponent.class, CompositeComponent.class, new Parameter[] {new ComponentParameter("x")} ); Component cc = (Component) pc.getComponentInstance(CompositeComponent.class); assertNotNull(cc); assertEquals("apple", cc.toString()); }
        Hide
        Nick Sieger added a comment -

        So the patch isn't really valid.

        Even so, it would still be nice for the following to just work with minimal extra config. I guess this is related to Thomas' comments on the list about the greedy nature of the GCCA – see http://article.gmane.org/gmane.comp.java.picocontainer.devel/3491. If I have any ideas for improvement I'll speak up on the list or submit another patch.

        public static interface Component {}

        public static class CompositeComponent implements Component {
        Object[] children;

        public CompositeComponent(Object[] children)

        { this.children = children; }

        }

        public static class LeafComponent implements Component {
        public LeafComponent() {
        }
        }

        pc.registerComponentInstance(LeafComponent.class);
        pc.registerComponentInstance(CompositeComponent.class);

        Show
        Nick Sieger added a comment - So the patch isn't really valid. Even so, it would still be nice for the following to just work with minimal extra config. I guess this is related to Thomas' comments on the list about the greedy nature of the GCCA – see http://article.gmane.org/gmane.comp.java.picocontainer.devel/3491 . If I have any ideas for improvement I'll speak up on the list or submit another patch. public static interface Component {} public static class CompositeComponent implements Component { Object[] children; public CompositeComponent(Object[] children) { this.children = children; } } public static class LeafComponent implements Component { public LeafComponent() { } } pc.registerComponentInstance(LeafComponent.class); pc.registerComponentInstance(CompositeComponent.class);
        Hide
        Jörg Schaible added a comment -

        Have a look at the GenericCollectionAdapterTestCase. This should demonstrate, what you want.

        Show
        Jörg Schaible added a comment - Have a look at the GenericCollectionAdapterTestCase. This should demonstrate, what you want.
        Jörg Schaible made changes -
        Resolution Fixed [ 1 ]
        Status Open [ 1 ] Closed [ 6 ]
        Fix Version/s 1.1 [ 10307 ]

          People

          • Assignee:
            Jörg Schaible
            Reporter:
            Nick Sieger
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: