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 org.picocontainer.DefaultPicoContainer;
013    
014    import junit.framework.TestCase;
015    
016    public class InterceptingTestCase extends TestCase {
017    
018        public static interface Foo {
019            void one();
020            String two(String a, int b);
021        }
022    
023        public static class FooImpl implements Foo {
024            private StringBuilder sb;
025    
026            public FooImpl(StringBuilder sb) {
027                this.sb = sb;
028            }
029    
030            public void one() {
031                sb.append("call-one(),");
032            }
033    
034            public String two(String a, int b) {
035                sb.append("call-two('"+a+"',"+b+"),");
036                return "two";
037            }
038        }
039    
040        public void testPreAndPostObservation() {
041            final StringBuilder sb = new StringBuilder();
042            DefaultPicoContainer pico = new DefaultPicoContainer(new Interception());
043            pico.addComponent(StringBuilder.class, sb);
044            pico.addComponent(Foo.class, FooImpl.class);
045    
046            Intercepted intercepted = pico.getComponentAdapter(Foo.class).findAdapterOfType(Intercepted.class);
047            final Intercepted.Controller interceptor = intercepted.getController();
048            intercepted.addPreInvocation(Foo.class, new Foo() {
049                public void one() {
050                    sb.append("pre-one(),");
051                }
052                public String two(String a, int b) {
053                    sb.append("pre-two('"+a+"',"+b+"),");
054                    return null;
055                }
056            });
057            intercepted.addPostInvocation(Foo.class, new Foo() {
058                public void one() {
059                    sb.append("addPostInvocation-one(),");
060                }
061                public String two(String a, int b) {
062                    assertEquals("two", interceptor.getOriginalRetVal());
063                    sb.append("addPostInvocation-two('"+a+"',"+b+"),");
064                    return null;
065                }
066            });
067    
068            Foo foo = pico.getComponent(Foo.class);
069            assertNotNull(foo);
070            foo.one();
071            assertEquals("two", foo.two("hello", 99));
072            assertEquals("pre-one(),call-one(),addPostInvocation-one(),pre-two('hello',99),call-two('hello',99),addPostInvocation-two('hello',99),", sb.toString());
073            assertEquals("Intercepted:ConstructorInjector-interface org.picocontainer.behaviors.InterceptingTestCase$Foo", pico.getComponentAdapter(Foo.class).toString());
074        }
075    
076        public void testPreCanBlockInvocationWithAlternateReturnValue() {
077            final StringBuilder sb = new StringBuilder();
078            DefaultPicoContainer pico = new DefaultPicoContainer(new Interception());
079            pico.addComponent(Foo.class, FooImpl.class);
080            pico.addComponent(StringBuilder.class, sb);
081    
082            Intercepted intercepted = pico.getComponentAdapter(Foo.class).findAdapterOfType(Intercepted.class);
083            final Intercepted.Controller interceptor = intercepted.getController();
084            intercepted.addPreInvocation(Foo.class, new Foo() {
085                public void one() {
086                    interceptor.veto();
087                    sb.append("veto-one(),");
088                }
089    
090                public String two(String a, int b) {
091                    interceptor.veto();
092                    sb.append("veto-two('"+a+"',"+b+"),");
093                    return "isVetoed";
094                }
095            });
096    
097            Foo foo = pico.getComponent(Foo.class);
098            assertNotNull(foo);
099            foo.one();
100            assertEquals("isVetoed", foo.two("hello", 99));
101            assertEquals("veto-one(),veto-two('hello',99),", sb.toString());
102            assertEquals("Intercepted:ConstructorInjector-interface org.picocontainer.behaviors.InterceptingTestCase$Foo", pico.getComponentAdapter(Foo.class).toString());
103        }
104    
105        public void testOverrideOfReturnValue() {
106            final StringBuilder sb = new StringBuilder();
107            DefaultPicoContainer pico = new DefaultPicoContainer(new Interception());
108            pico.addComponent(Foo.class, FooImpl.class);
109            pico.addComponent(StringBuilder.class, sb);
110            Intercepted intercepted = pico.getComponentAdapter(Foo.class).findAdapterOfType(Intercepted.class);
111            final Intercepted.Controller interceptor = intercepted.getController();
112            intercepted.addPreInvocation(Foo.class, new Foo() {
113                public void one() {
114                    sb.append("pre-one(),");
115                }
116    
117                public String two(String a, int b) {
118                    sb.append("pre-two('"+a+"',"+b+"),");
119                    return null;
120                }
121            });
122            intercepted.addPostInvocation(Foo.class, new Foo() {
123                public void one() {
124                    interceptor.override();
125                    sb.append("override-one(),");
126                 }
127    
128                public String two(String a, int b) {
129                    interceptor.override();
130                    sb.append("override-two('"+a+"',"+b+"),");
131                    return "x";
132                }
133            });
134    
135            Foo foo = pico.getComponent(Foo.class);
136            assertNotNull(foo);
137            foo.one();
138            assertEquals("x", foo.two("hello", 99));
139            assertEquals("pre-one(),call-one(),override-one(),pre-two('hello',99),call-two('hello',99),override-two('hello',99),", sb.toString());
140            assertEquals("Intercepted:ConstructorInjector-interface org.picocontainer.behaviors.InterceptingTestCase$Foo", pico.getComponentAdapter(Foo.class).toString());
141        }
142    
143        public void testNothingHappensIfNoPreOrPost() {
144            final StringBuilder sb = new StringBuilder();
145            DefaultPicoContainer pico = new DefaultPicoContainer(new Interception());
146            pico.addComponent(Foo.class, FooImpl.class);
147            pico.addComponent(StringBuilder.class, sb);
148            Foo foo = pico.getComponent(Foo.class);
149            assertNotNull(foo);
150            foo.one();
151            assertEquals("two", foo.two("hello", 99));
152            assertEquals("call-one(),call-two('hello',99),", sb.toString());
153            assertEquals("Intercepted:ConstructorInjector-interface org.picocontainer.behaviors.InterceptingTestCase$Foo", pico.getComponentAdapter(Foo.class).toString());
154        }
155    
156    
157    
158    }