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     *****************************************************************************/
010    package org.picocontainer.behaviors;
011    
012    import static org.junit.Assert.assertEquals;
013    import static org.junit.Assert.assertNotNull;
014    
015    import org.junit.Test;
016    import org.picocontainer.DefaultPicoContainer;
017    import org.picocontainer.containers.EmptyPicoContainer;
018    import org.picocontainer.lifecycle.NullLifecycleStrategy;
019    
020    public 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    }