001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.proxy2; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertTrue; 023 024import java.util.Date; 025 026import org.apache.commons.proxy2.exception.ProxyFactoryException; 027import org.apache.commons.proxy2.invoker.NullInvoker; 028import org.apache.commons.proxy2.provider.ConstantProvider; 029import org.apache.commons.proxy2.util.AbstractEcho; 030import org.apache.commons.proxy2.util.Echo; 031import org.apache.commons.proxy2.util.EchoImpl; 032import org.junit.Test; 033 034@SuppressWarnings("serial") 035public abstract class AbstractSubclassingProxyFactoryTestCase extends AbstractProxyFactoryTestCase 036{ 037 //---------------------------------------------------------------------------------------------------------------------- 038 // Fields 039 //---------------------------------------------------------------------------------------------------------------------- 040 041 private static final Class<?>[] DATE_ONLY = new Class[] { Date.class }; 042 043 //---------------------------------------------------------------------------------------------------------------------- 044 // Other Methods 045 //---------------------------------------------------------------------------------------------------------------------- 046 047 @Override 048 @Test 049 public void testCanProxy() 050 { 051 assertTrue(factory.canProxy(new Class[] { Echo.class })); 052 assertTrue(factory.canProxy(new Class[] { EchoImpl.class })); 053 assertFalse(factory.canProxy(new Class[] { FinalEcho.class })); 054 assertTrue(factory.canProxy(new Class[] { FinalMethodEcho.class, Echo.class })); 055 assertFalse(factory.canProxy(new Class[] { NoDefaultConstructorEcho.class })); 056 assertTrue(factory.canProxy(new Class[] { ProtectedConstructorEcho.class })); 057 assertFalse(factory.canProxy(new Class[] { InvisibleEcho.class })); 058 assertFalse(factory.canProxy(new Class[] { Echo.class, EchoImpl.class, String.class })); 059 } 060 061 @Override 062 @Test 063 public void testDelegatorEquals() throws Exception 064 { 065 final EqualsEcho echo = new EqualsEcho("text"); 066 final Echo proxy1 = factory.createDelegatorProxy(new ConstantProvider<Echo>(echo), 067 new Class[] { EqualsEcho.class }); 068 final Echo proxy2 = factory.createDelegatorProxy(new ConstantProvider<Echo>(echo), 069 new Class[] { EqualsEcho.class }); 070 assertEquals(proxy1, proxy1); 071 assertFalse(proxy1.equals(proxy2)); 072 assertFalse(proxy2.equals(proxy1)); 073 } 074 075 @Test(expected = ProxyFactoryException.class) 076 public void testDelegatorWithMultipleSuperclasses() 077 { 078 factory.createDelegatorProxy(new ConstantProvider<EchoImpl>(new EchoImpl()), new Class[] { EchoImpl.class, 079 String.class }); 080 } 081 082 @Test 083 public void testDelegatorWithSuperclass() 084 { 085 final Echo echo = factory.createDelegatorProxy(new ConstantProvider<EchoImpl>(new EchoImpl()), new Class[] { 086 Echo.class, EchoImpl.class }); 087 assertTrue(echo instanceof EchoImpl); 088 } 089 090 @Override 091 @Test 092 public void testInterceptorEquals() 093 { 094 final EqualsEcho echo = new EqualsEcho("text"); 095 final Echo proxy1 = factory.createInterceptorProxy(echo, new NoOpMethodInterceptor(), 096 new Class[] { EqualsEcho.class }); 097 final Echo proxy2 = factory.createInterceptorProxy(echo, new NoOpMethodInterceptor(), 098 new Class[] { EqualsEcho.class }); 099 assertEquals(proxy1, proxy1); 100 assertFalse(proxy1.equals(proxy2)); 101 assertFalse(proxy2.equals(proxy1)); 102 } 103 104 @Test(expected = ProxyFactoryException.class) 105 public void testInterceptorWithMultipleSuperclasses() 106 { 107 factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), new Class[] { EchoImpl.class, 108 String.class }); 109 } 110 111 @Test 112 public void testInterceptorWithSuperclass() 113 { 114 final Echo echo = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), new Class[] { 115 Echo.class, EchoImpl.class }); 116 assertTrue(echo instanceof EchoImpl); 117 } 118 119 @Test(expected = ProxyFactoryException.class) 120 public void testInvocationHandlerWithMultipleSuperclasses() 121 { 122 factory.createInvokerProxy(new NullInvoker(), new Class[] { EchoImpl.class, String.class }); 123 } 124 125 @Override 126 @Test 127 public void testInvokerEquals() throws Exception 128 { 129 final Date proxy1 = factory.createInvokerProxy(new InvokerTester(), DATE_ONLY); 130 final Date proxy2 = factory.createInvokerProxy(new InvokerTester(), DATE_ONLY); 131 assertEquals(proxy1, proxy1); 132 assertFalse(proxy1.equals(proxy2)); 133 assertFalse(proxy2.equals(proxy1)); 134 } 135 136 @Test 137 public void testInvokerWithSuperclass() 138 { 139 final Echo echo = factory.createInvokerProxy(new NullInvoker(), new Class[] { Echo.class, EchoImpl.class }); 140 assertTrue(echo instanceof EchoImpl); 141 } 142 143 @Test 144 public void testProxiesWithClashingFinalMethodInSuperclass() 145 { 146 final Class<?>[] proxyClasses = new Class[] { Echo.class, FinalMethodEcho.class }; 147 Echo proxy = factory.createDelegatorProxy(new ConstantProvider<EchoImpl>(new EchoImpl()), proxyClasses); 148 assertEquals("final", proxy.echoBack("echo")); 149 150 proxy = factory.createInterceptorProxy(new EchoImpl(), new NoOpMethodInterceptor(), proxyClasses); 151 assertEquals("final", proxy.echoBack("echo")); 152 153 proxy = factory.createInvokerProxy(new NullInvoker(), proxyClasses); 154 assertEquals("final", proxy.echoBack("echo")); 155 } 156 157 @Test 158 public void testWithAbstractSuperclass() 159 { 160 final Echo echo = factory.createDelegatorProxy(new ConstantProvider<EchoImpl>(new EchoImpl()), 161 new Class[] { AbstractEcho.class }); 162 assertEquals("hello", echo.echoBack("hello")); 163 assertEquals("helloworld", echo.echoBack("hello", "world")); 164 } 165 166 //---------------------------------------------------------------------------------------------------------------------- 167 // Inner Classes 168 //---------------------------------------------------------------------------------------------------------------------- 169 170 public static class EqualsEcho extends EchoImpl 171 { 172 @SuppressWarnings("unused") 173 private final String text; 174 175 protected EqualsEcho() 176 { 177 this("testing"); 178 } 179 180 public EqualsEcho(String text) 181 { 182 this.text = text; 183 } 184 } 185 186 public static final class FinalEcho extends EchoImpl 187 { 188 } 189 190 public static class FinalMethodEcho extends EchoImpl 191 { 192 @Override 193 public final String echoBack(String message) 194 { 195 return "final"; 196 } 197 } 198 199 private static class InvisibleEcho extends EchoImpl 200 { 201 } 202 203 public static class NoDefaultConstructorEcho extends EchoImpl 204 { 205 public NoDefaultConstructorEcho(String param) 206 { 207 } 208 } 209 210 public static class ProtectedConstructorEcho extends EchoImpl 211 { 212 protected ProtectedConstructorEcho() 213 { 214 } 215 } 216}