    001    /*****************************************************************************
    002     * Copyright (C) NanoContainer 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     *****************************************************************************/
    009
    010    package org.picocontainer.behaviors;
    011
    012    import org.junit.Test;
    013    import static org.junit.Assert.assertNotNull;
    014    import org.picocontainer.MutablePicoContainer;
    015    import org.picocontainer.DefaultPicoContainer;
    016    import org.picocontainer.annotations.Inject;
    017    import org.picocontainer.injectors.ConstructorInjection;
    018
    019    import java.lang.reflect.Field;import static junit.framework.Assert.assertEquals;
    020
    021    public class DecoratingTestCase {
    022
    023        public static interface Swede {
    024        }
    025
    026        public static class Turnip {
    027            @Inject
    028            Swede swede;
    029            private final String foo;
    030
    031            public Turnip(String foo) {
    032                this.foo = foo;
    033            }
    034
    035            public Swede getSwede() {
    036                return swede;
    037            }
    038
    039            public String getFoo() {
    040                return foo;
    041            }
    042        }
    043
    044
    045        @Test
    046        public void testThatComponentCanHaveAProvidedDependencyViaDecoratorBehavior() {
    047            MutablePicoContainer container = new DefaultPicoContainer(new SwedeDecorating().wrap(new ConstructorInjection()));
    048            container.addComponent(String.class, "foo");
    049            container.addComponent(Turnip.class);
    050            Turnip t = container.getComponent(Turnip.class);
    051            assertNotNull(t);
    052            assertNotNull(t.getSwede());
    053            assertEquals("Swede:" + Turnip.class.getName(), t.getSwede().toString());
    054            assertEquals("foo", t.getFoo());
    055
    056        }
    057
    058        @Test
    059        public void testThatComponentCanHaveAProvidedDependencyViaFieldDecoratorBehavior() {
    060            MutablePicoContainer container = new DefaultPicoContainer(
    061                    new FieldDecorating(Swede.class) {
    062                        public Object decorate(final Object instance) {
    063                            return new Swede() {
    064                                public String toString() {
    065                                    return "Swede:" + instance.getClass().getName();
    066                                }
    067                            };
    068                        }
    069                    }.wrap(new ConstructorInjection()));
    070            container.addComponent(String.class, "foo");
    071            container.addComponent(Turnip.class);
    072            Turnip t = container.getComponent(Turnip.class);
    073            assertNotNull(t);
    074            assertNotNull(t.getSwede());
    075            assertEquals("Swede:" + Turnip.class.getName(), t.getSwede().toString());
    076            assertEquals("foo", t.getFoo());
    077
    078        }
    079
    080        private static class SwedeDecorating extends Decorating {
    081            public void decorate(final Object instance) {
    082                Field[] fields = instance.getClass().getDeclaredFields();
    083                for (int i = 0; i < fields.length; i++) {
    084                    Field field = fields[i];
    085                    if (field.getType() == Swede.class) {
    086                        Swede value = new Swede() {
    087                            public String toString() {
    088                                return "Swede:" + instance.getClass().getName();
    089                            }
    090                        };
    091                        field.setAccessible(true);
    092                        try {
    093                            field.set(instance, value);
    094                        } catch (IllegalAccessException e) {
    095                            throw new RuntimeException(e);
    096                        }
    097                    }
    098
    099                }
    100            }
    101        }
    102
    103    }