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    }