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
010package org.picocontainer.behaviors;
011
012import org.junit.Test;
013import static org.junit.Assert.assertNotNull;
014import org.picocontainer.MutablePicoContainer;
015import org.picocontainer.DefaultPicoContainer;
016import org.picocontainer.annotations.Inject;
017import org.picocontainer.injectors.ConstructorInjection;
018
019import java.lang.reflect.Field;import static junit.framework.Assert.assertEquals;
020
021public 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}