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