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 *****************************************************************************/
010package org.picocontainer.behaviors;
011
012import static org.junit.Assert.assertEquals;
013import static org.junit.Assert.assertNotNull;
014
015import org.junit.Test;
016import org.picocontainer.DefaultPicoContainer;
017import org.picocontainer.containers.EmptyPicoContainer;
018import org.picocontainer.lifecycle.NullLifecycleStrategy;
019
020public class InterceptingTestCase {
021
022    public static interface Person {
023        String greeting();
024        String parting(String who);
025        void sleep(int howLong);
026        public static class nullobject implements Person {
027            public String greeting() {
028                return null;
029            }
030            public String parting(String who) {
031                return null;
032            }
033            public void sleep(int howLong) {
034            }
035        }
036
037    }
038
039    public static class Englishman implements Person {
040        private StringBuilder sb;
041
042        public Englishman(StringBuilder sb) {
043            this.sb = sb;
044        }
045
046        public String greeting() {
047            String phrase = "How do you do?";
048            sb.append(phrase);
049            return phrase;
050        }
051
052        public String parting(String who) {
053            String phrase = "Goodbye " + who + ".";
054            sb.append(phrase);
055            return phrase;
056        }
057
058        public void sleep(int howLong) {
059            sb.append("Nap for " + howLong);
060        }
061    }
062
063    @Test public void testPreAndPostObservation() {
064        final StringBuilder sb = new StringBuilder();
065        DefaultPicoContainer pico = new DefaultPicoContainer(new Intercepting(), new NullLifecycleStrategy(), new EmptyPicoContainer());
066        pico.addComponent(StringBuilder.class, sb);
067        pico.addComponent(Person.class, Englishman.class);
068
069        Intercepted intercepted = pico.getComponentAdapter(Person.class).findAdapterOfType(Intercepted.class);
070        final Intercepted.Controller interceptor = intercepted.getController();
071        intercepted.addPostInvocation(Person.class, new Person.nullobject() {
072            public String greeting() {
073                sb.append("</english-greeting>");
074                return null;
075            }
076        });
077        intercepted.addPreInvocation(Person.class, new Person.nullobject() {
078            public String greeting() {
079                sb.append("<english-greeting>");
080                return null;
081            }
082        });
083
084
085        Person foo = pico.getComponent(Person.class);
086        assertNotNull(foo);
087        assertEquals("How do you do?", foo.greeting());
088        assertEquals("<english-greeting>How do you do?</english-greeting>", sb.toString());
089        assertEquals("Intercepted:ConstructorInjector-interface org.picocontainer.behaviors.InterceptingTestCase$Person", pico.getComponentAdapter(Person.class).toString());
090    }
091
092    @Test public void testPreAndPostObservationWithParameter() {
093        final StringBuilder sb = new StringBuilder();
094        DefaultPicoContainer pico = new DefaultPicoContainer(new Intercepting(), new NullLifecycleStrategy(), new EmptyPicoContainer());
095        pico.addComponent(StringBuilder.class, sb);
096        pico.addComponent(Person.class, Englishman.class);
097
098        Intercepted intercepted = pico.getComponentAdapter(Person.class).findAdapterOfType(Intercepted.class);
099        final Intercepted.Controller interceptor = intercepted.getController();
100        intercepted.addPostInvocation(Person.class, new Person.nullobject() {
101            public String parting(String a) {
102                assertEquals("Goodbye Fred.", interceptor.getOriginalRetVal().toString());
103                sb.append("</english-parting>");
104                return null;
105            }
106        });
107        intercepted.addPreInvocation(Person.class, new Person.nullobject() {
108            public String parting(String who) {
109                sb.append("<english-parting who='"+who+"'>");
110                return null;
111            }
112        });
113
114        Person foo = pico.getComponent(Person.class);
115        assertNotNull(foo);
116        assertEquals("Goodbye Fred.", foo.parting("Fred").trim());
117        assertEquals("<english-parting who='Fred'>Goodbye Fred.</english-parting>", sb.toString());
118        assertEquals("Intercepted:ConstructorInjector-interface org.picocontainer.behaviors.InterceptingTestCase$Person", pico.getComponentAdapter(Person.class).toString());
119    }
120
121    @Test public void testPreCanPreventInvocationWithAlternateReturnValue() {
122        final StringBuilder sb = new StringBuilder();
123        DefaultPicoContainer pico = new DefaultPicoContainer(new Intercepting(), new NullLifecycleStrategy(), new EmptyPicoContainer());
124        pico.addComponent(Person.class, Englishman.class);
125        pico.addComponent(StringBuilder.class, sb);
126
127        Intercepted intercepted = pico.getComponentAdapter(Person.class).findAdapterOfType(Intercepted.class);
128        final Intercepted.Controller interceptor = intercepted.getController();
129        intercepted.addPreInvocation(Person.class, new Person.nullobject() {
130            public String parting(String who) {
131                interceptor.veto();
132                return "Au revoir " + who + ".";
133            }
134        });
135
136        Person foo = pico.getComponent(Person.class);
137        assertNotNull(foo);
138        assertEquals("Au revoir Fred.", foo.parting("Fred"));
139        assertEquals("", sb.toString());
140        assertEquals("Intercepted:ConstructorInjector-interface org.picocontainer.behaviors.InterceptingTestCase$Person", pico.getComponentAdapter(Person.class).toString());
141    }
142
143    @Test public void testOverrideOfReturnValue() {
144        final StringBuilder sb = new StringBuilder();
145        DefaultPicoContainer pico = new DefaultPicoContainer(new Intercepting(), new NullLifecycleStrategy(), new EmptyPicoContainer());
146        pico.addComponent(Person.class, Englishman.class);
147        pico.addComponent(StringBuilder.class, sb);
148        Intercepted intercepted = pico.getComponentAdapter(Person.class).findAdapterOfType(Intercepted.class);
149        final Intercepted.Controller interceptor = intercepted.getController();
150        intercepted.addPreInvocation(Person.class, new Person.nullobject() {
151            public String parting(String who) {
152                sb.append("[Before parting]");
153                return null;
154            }
155        });
156        intercepted.addPostInvocation(Person.class, new Person() {
157            public String greeting() {
158                return null;
159             }
160
161            public String parting(String who) {
162                interceptor.override();
163                sb.append("[After parting]");
164                return "Arrivederci " + who;
165            }
166
167            public void sleep(int howLong) {
168            }
169        });
170
171        Person foo = pico.getComponent(Person.class);
172        assertNotNull(foo);
173        assertEquals("Arrivederci Fred", foo.parting("Fred"));
174        assertEquals("[Before parting]Goodbye Fred.[After parting]", sb.toString());
175        assertEquals("Intercepted:ConstructorInjector-interface org.picocontainer.behaviors.InterceptingTestCase$Person", pico.getComponentAdapter(Person.class).toString());
176    }
177
178    @Test public void testNothingHappensIfNoPreOrPost() {
179        final StringBuilder sb = new StringBuilder();
180        DefaultPicoContainer pico = new DefaultPicoContainer(new Intercepting(), new NullLifecycleStrategy(), new EmptyPicoContainer());
181        pico.addComponent(Person.class, Englishman.class);
182        pico.addComponent(StringBuilder.class, sb);
183        Person foo = pico.getComponent(Person.class);
184        assertNotNull(foo);
185        assertEquals("Goodbye Fred.", foo.parting("Fred"));
186        assertEquals("Goodbye Fred.", sb.toString());
187        assertEquals("Intercepted:ConstructorInjector-interface org.picocontainer.behaviors.InterceptingTestCase$Person", pico.getComponentAdapter(Person.class).toString());
188    }
189
190
191
192}