1 /* 2 * The Apache Software License, Version 1.1 3 * 4 * Copyright (c) 2002 The Apache Software Foundation. All rights 5 * reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 19 * 3. The end-user documentation included with the redistribution, 20 * if any, must include the following acknowledgment: 21 * "This product includes software developed by the 22 * Apache Software Foundation (http://www.apache.org/)." 23 * Alternately, this acknowledgment may appear in the software itself, 24 * if and wherever such third-party acknowledgments normally appear. 25 * 26 * 4. The names "Apache" and "Apache Software Foundation" must 27 * not be used to endorse or promote products derived from this 28 * software without prior written permission. For written 29 * permission, please contact apache@apache.org. 30 * 31 * 5. Products derived from this software may not be called "Apache", 32 * nor may "Apache" appear in their name, without prior written 33 * permission of the Apache Software Foundation. 34 * 35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 42 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 44 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 45 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 46 * SUCH DAMAGE. 47 * ==================================================================== 48 * 49 * This software consists of voluntary contributions made by many 50 * individuals on behalf of the Apache Software Foundation. For more 51 * information on the Apache Software Foundation, please see 52 * <http://www.apache.org/>;. 53 */ 54 package net.sf.cglib.proxy; 55 56 import java.io.*; 57 import java.lang.reflect.*; 58 import junit.framework.*; 59 import net.sf.cglib.CodeGenTestCase; 60 import net.sf.cglib.core.ReflectUtils; 61 62 /*** 63 *@author Juozas Baliuka <a href="mailto:baliuka@mwm.lt"> 64 * baliuka@mwm.lt</a> 65 *@version $Id: TestEnhancer.java,v 1.39 2004/01/18 13:29:41 baliuka Exp $ 66 */ 67 public class TestEnhancer extends CodeGenTestCase { 68 private static final MethodInterceptor TEST_INTERCEPTOR = new TestInterceptor(); 69 70 private static final Class [] EMPTY_ARG = new Class[]{}; 71 72 private boolean invokedProtectedMethod = false; 73 74 private boolean invokedPackageMethod = false; 75 76 private boolean invokedAbstractMethod = false; 77 78 public TestEnhancer(String testName) { 79 super(testName); 80 } 81 82 83 84 public static Test suite() { 85 return new TestSuite(TestEnhancer.class); 86 } 87 88 public static void main(String args[]) { 89 String[] testCaseName = {TestEnhancer.class.getName()}; 90 junit.textui.TestRunner.main(testCaseName); 91 } 92 93 94 public void testEnhance()throws Throwable{ 95 96 java.util.Vector vector1 = (java.util.Vector)Enhancer.create( 97 java.util.Vector.class, 98 new Class[]{java.util.List.class}, TEST_INTERCEPTOR ); 99 100 java.util.Vector vector2 = (java.util.Vector)Enhancer.create( 101 java.util.Vector.class, 102 new Class[]{java.util.List.class}, TEST_INTERCEPTOR ); 103 104 105 106 107 assertTrue("Cache failed",vector1.getClass() == vector2.getClass()); 108 } 109 110 111 public void testMethods()throws Throwable{ 112 113 MethodInterceptor interceptor = 114 new TestInterceptor(){ 115 116 public Object afterReturn( Object obj, Method method, 117 Object args[], 118 boolean invokedSuper, Object retValFromSuper, 119 java.lang.Throwable e )throws java.lang.Throwable{ 120 121 int mod = method.getModifiers(); 122 123 if( Modifier.isProtected( mod ) ){ 124 invokedProtectedMethod = true; 125 } 126 127 if( Modifier.isAbstract(mod) ){ 128 invokedAbstractMethod = true; 129 } 130 131 132 if( ! ( Modifier.isProtected( mod ) || Modifier.isPublic( mod ) )){ 133 invokedPackageMethod = true; 134 } 135 136 return retValFromSuper;//return the same as supper 137 } 138 139 }; 140 141 142 Source source = (Source)Enhancer.create( 143 Source.class, 144 null,interceptor ); 145 146 source.callAll(); 147 assertTrue("protected", invokedProtectedMethod ); 148 assertTrue("package", invokedPackageMethod ); 149 assertTrue("abstract", invokedAbstractMethod ); 150 } 151 152 public void testEnhanced()throws Throwable{ 153 154 Source source = (Source)Enhancer.create( 155 Source.class, 156 null, TEST_INTERCEPTOR ); 157 158 159 TestCase.assertTrue("enhance", Source.class != source.getClass() ); 160 161 } 162 163 public void testEnhanceObject() throws Throwable { 164 EA obj = new EA(); 165 EA save = obj; 166 obj.setName("herby"); 167 EA proxy = (EA)Enhancer.create( EA.class, new DelegateInterceptor(save) ); 168 169 assertTrue(proxy.getName().equals("herby")); 170 171 Factory factory = (Factory)proxy; 172 assertTrue(((EA)factory.newInstance(factory.getCallbacks())).getName().equals("herby")); 173 } 174 175 class DelegateInterceptor implements MethodInterceptor { 176 Object delegate; 177 DelegateInterceptor(Object delegate){ 178 this.delegate = delegate; 179 } 180 public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args, MethodProxy proxy) throws Throwable { 181 return proxy.invoke(delegate,args); 182 } 183 184 } 185 public void testEnhanceObjectDelayed() throws Throwable { 186 187 DelegateInterceptor mi = new DelegateInterceptor(null); 188 EA proxy = (EA)Enhancer.create( EA.class, mi); 189 EA obj = new EA(); 190 obj.setName("herby"); 191 mi.delegate = obj; 192 assertTrue(proxy.getName().equals("herby")); 193 } 194 195 196 public void testTypes()throws Throwable{ 197 198 Source source = (Source)Enhancer.create( 199 Source.class, 200 null, TEST_INTERCEPTOR ); 201 TestCase.assertTrue("intType", 1 == source.intType(1)); 202 TestCase.assertTrue("longType", 1L == source.longType(1L)); 203 TestCase.assertTrue("floatType", 1.1f == source.floatType(1.1f)); 204 TestCase.assertTrue("doubleType",1.1 == source.doubleType(1.1)); 205 TestCase.assertEquals("objectType","1", source.objectType("1") ); 206 TestCase.assertEquals("objectType","", source.toString() ); 207 source.arrayType( new int[]{} ); 208 209 } 210 211 212 public void testModifiers()throws Throwable{ 213 214 Source source = (Source)Enhancer.create( 215 Source.class, 216 null, TEST_INTERCEPTOR ); 217 218 Class enhancedClass = source.getClass(); 219 220 assertTrue("isProtected" , Modifier.isProtected( enhancedClass.getDeclaredMethod("protectedMethod", EMPTY_ARG ).getModifiers() )); 221 int mod = enhancedClass.getDeclaredMethod("packageMethod", EMPTY_ARG ).getModifiers() ; 222 assertTrue("isPackage" , !( Modifier.isProtected(mod)|| Modifier.isPublic(mod) ) ); 223 224 //not sure about this (do we need it for performace ?) 225 assertTrue("isFinal" , Modifier.isFinal( mod ) ); 226 227 mod = enhancedClass.getDeclaredMethod("synchronizedMethod", EMPTY_ARG ).getModifiers() ; 228 assertTrue("isSynchronized" , !Modifier.isSynchronized( mod ) ); 229 230 231 } 232 233 public void testObject()throws Throwable{ 234 235 Object source = Enhancer.create( 236 null, 237 null, TEST_INTERCEPTOR ); 238 239 assertTrue("parent is object", 240 source.getClass().getSuperclass() == Object.class ); 241 242 } 243 244 public void testSystemClassLoader()throws Throwable{ 245 246 Object source = enhance( 247 null, 248 null, TEST_INTERCEPTOR , ClassLoader.getSystemClassLoader()); 249 source.toString(); 250 assertTrue("SystemClassLoader", 251 source.getClass().getClassLoader() 252 == ClassLoader.getSystemClassLoader() ); 253 254 } 255 256 public void testCustomClassLoader()throws Throwable{ 257 258 ClassLoader custom = new ClassLoader(this.getClass().getClassLoader()){}; 259 260 Object source = enhance( null, null, TEST_INTERCEPTOR, custom); 261 source.toString(); 262 assertTrue("Custom classLoader", source.getClass().getClassLoader() == custom ); 263 264 custom = new ClassLoader(){}; 265 266 source = enhance( null, null, TEST_INTERCEPTOR, custom); 267 source.toString(); 268 assertTrue("Custom classLoader", source.getClass().getClassLoader() == custom ); 269 270 271 } 272 273 public void testRuntimException()throws Throwable{ 274 275 Source source = (Source)Enhancer.create( 276 Source.class, 277 null, TEST_INTERCEPTOR ); 278 279 try{ 280 281 source.throwIndexOutOfBoundsException(); 282 fail("must throw an exception"); 283 284 }catch( IndexOutOfBoundsException ok ){ 285 286 } 287 288 } 289 290 static abstract class CastTest{ 291 CastTest(){} 292 abstract int getInt(); 293 } 294 295 class CastTestInterceptor implements MethodInterceptor{ 296 297 public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args, MethodProxy proxy) throws Throwable { 298 return new Short((short)0); 299 } 300 301 } 302 303 304 public void testCast()throws Throwable{ 305 306 CastTest castTest = (CastTest)Enhancer.create(CastTest.class, null, new CastTestInterceptor()); 307 308 assertTrue(castTest.getInt() == 0); 309 310 } 311 312 public void testABC() throws Throwable{ 313 Enhancer.create(EA.class, null, TEST_INTERCEPTOR); 314 Enhancer.create(EC1.class, null, TEST_INTERCEPTOR).toString(); 315 ((EB)Enhancer.create(EB.class, null, TEST_INTERCEPTOR)).finalTest(); 316 assertTrue("abstract method",( (EC1)Enhancer.create(EC1.class, 317 null, TEST_INTERCEPTOR) ).compareTo( new EC1() ) == -1 ); 318 Enhancer.create(ED.class, null, TEST_INTERCEPTOR).toString(); 319 Enhancer.create(ClassLoader.class, null, TEST_INTERCEPTOR).toString(); 320 } 321 322 public static class AroundDemo { 323 public String getFirstName() { 324 return "Chris"; 325 } 326 public String getLastName() { 327 return "Nokleberg"; 328 } 329 } 330 331 public void testAround() throws Throwable { 332 AroundDemo demo = (AroundDemo)Enhancer.create(AroundDemo.class, null, new MethodInterceptor() { 333 public Object intercept(Object obj, Method method, Object[] args, 334 MethodProxy proxy) throws Throwable { 335 if (method.getName().equals("getFirstName")) { 336 return "Christopher"; 337 } 338 return proxy.invokeSuper(obj, args); 339 } 340 }); 341 assertTrue(demo.getFirstName().equals("Christopher")); 342 assertTrue(demo.getLastName().equals("Nokleberg")); 343 } 344 345 346 public static interface TestClone extends Cloneable{ 347 public Object clone()throws java.lang.CloneNotSupportedException; 348 349 } 350 public static class TestCloneImpl implements TestClone{ 351 public Object clone()throws java.lang.CloneNotSupportedException{ 352 return super.clone(); 353 } 354 } 355 356 public void testClone() throws Throwable{ 357 358 TestClone testClone = (TestClone)Enhancer.create( TestCloneImpl.class, 359 TEST_INTERCEPTOR ); 360 assertTrue( testClone.clone() != null ); 361 362 363 testClone = (TestClone)Enhancer.create( TestClone.class, 364 new MethodInterceptor(){ 365 366 public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args, 367 MethodProxy proxy) throws Throwable{ 368 return proxy.invokeSuper(obj, args); 369 } 370 371 372 } ); 373 374 assertTrue( testClone.clone() != null ); 375 376 377 } 378 379 public void testSamples() throws Throwable{ 380 samples.Trace.main(new String[]{}); 381 samples.Beans.main(new String[]{}); 382 } 383 384 public static interface FinalA { 385 void foo(); 386 } 387 388 public static class FinalB implements FinalA { 389 final public void foo() { } 390 } 391 392 public void testFinal() throws Throwable { 393 ((FinalA)Enhancer.create(FinalB.class, TEST_INTERCEPTOR)).foo(); 394 } 395 396 public static interface ConflictA { 397 int foo(); 398 } 399 400 public static interface ConflictB { 401 String foo(); 402 } 403 404 public void testConflict() throws Throwable { 405 Object foo = 406 Enhancer.create(Object.class, new Class[]{ ConflictA.class, ConflictB.class }, TEST_INTERCEPTOR); 407 ((ConflictA)foo).foo(); 408 ((ConflictB)foo).foo(); 409 } 410 411 public void testArgInit() throws Throwable{ 412 413 Enhancer e = new Enhancer(); 414 e.setSuperclass(ArgInit.class); 415 e.setCallbackType(MethodInterceptor.class); 416 Class f = e.createClass(); 417 ArgInit a = (ArgInit)ReflectUtils.newInstance(f, 418 new Class[]{ String.class }, 419 new Object[]{ "test" }); 420 assertEquals("test", a.toString()); 421 ((Factory)a).setCallback(0, TEST_INTERCEPTOR); 422 assertEquals("test", a.toString()); 423 424 Callback[] callbacks = new Callback[]{ TEST_INTERCEPTOR }; 425 ArgInit b = (ArgInit)((Factory)a).newInstance(new Class[]{ String.class }, 426 new Object[]{ "test2" }, 427 callbacks); 428 assertEquals("test2", b.toString()); 429 try{ 430 ((Factory)a).newInstance(new Class[]{ String.class, String.class }, 431 new Object[]{"test"}, 432 callbacks); 433 fail("must throw exception"); 434 }catch( IllegalArgumentException iae ){ 435 436 } 437 } 438 439 public static class Signature { 440 public int interceptor() { 441 return 42; 442 } 443 } 444 445 public void testSignature() throws Throwable { 446 Signature sig = (Signature)Enhancer.create(Signature.class, TEST_INTERCEPTOR); 447 assertTrue(((Factory)sig).getCallback(0) == TEST_INTERCEPTOR); 448 assertTrue(sig.interceptor() == 42); 449 } 450 451 public abstract static class AbstractMethodCallInConstructor { 452 public AbstractMethodCallInConstructor() { 453 foo(); 454 } 455 456 public abstract void foo(); 457 } 458 459 public void testAbstractMethodCallInConstructor() throws Throwable { 460 AbstractMethodCallInConstructor obj = (AbstractMethodCallInConstructor) 461 Enhancer.create(AbstractMethodCallInConstructor.class, 462 TEST_INTERCEPTOR); 463 obj.foo(); 464 } 465 466 public void testProxyIface() throws Throwable { 467 final DI1 other = new DI1() { 468 public String herby() { 469 return "boop"; 470 } 471 }; 472 DI1 d = (DI1)Enhancer.create(DI1.class, new MethodInterceptor() { 473 public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args, 474 MethodProxy proxy) throws Throwable { 475 return proxy.invoke(other, args); 476 } 477 }); 478 assertTrue("boop".equals(d.herby())); 479 } 480 481 public static Object enhance(Class cls, Class interfaces[], Callback callback, ClassLoader loader) { 482 Enhancer e = new Enhancer(); 483 e.setSuperclass(cls); 484 e.setInterfaces(interfaces); 485 e.setCallback(callback); 486 e.setClassLoader(loader); 487 return e.create(); 488 } 489 490 public interface PublicClone extends Cloneable { 491 Object clone() throws CloneNotSupportedException; 492 } 493 494 public void testNoOpClone() throws Exception { 495 Enhancer enhancer = new Enhancer(); 496 enhancer.setSuperclass(PublicClone.class); 497 enhancer.setCallback(NoOp.INSTANCE); 498 ((PublicClone)enhancer.create()).clone(); 499 } 500 501 public void testNoFactory() throws Exception { 502 noFactoryHelper(); 503 noFactoryHelper(); 504 } 505 506 private void noFactoryHelper() { 507 MethodInterceptor mi = new MethodInterceptor() { 508 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { 509 return "Foo"; 510 } 511 }; 512 Enhancer enhancer = new Enhancer(); 513 enhancer.setUseFactory(false); 514 enhancer.setSuperclass(AroundDemo.class); 515 enhancer.setCallback(mi); 516 AroundDemo obj = (AroundDemo)enhancer.create(); 517 assertTrue(obj.getFirstName().equals("Foo")); 518 assertTrue(!(obj instanceof Factory)); 519 } 520 521 interface MethDec { 522 void foo(); 523 } 524 525 abstract static class MethDecImpl implements MethDec { 526 } 527 528 public void testMethodDeclarer() throws Exception { 529 final boolean[] result = new boolean[]{ false }; 530 Enhancer enhancer = new Enhancer(); 531 enhancer.setSuperclass(MethDecImpl.class); 532 enhancer.setCallback(new MethodInterceptor() { 533 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { 534 535 result[0] = method.getDeclaringClass().getName().equals(MethDec.class.getName()); 536 return null; 537 } 538 }); 539 ((MethDecImpl)enhancer.create()).foo(); 540 assertTrue(result[0]); 541 } 542 543 544 interface ClassOnlyX { } 545 public void testClassOnlyFollowedByInstance() { 546 Enhancer enhancer = new Enhancer(); 547 enhancer.setSuperclass(ClassOnlyX.class); 548 enhancer.setCallbackType(NoOp.class); 549 Class type = enhancer.createClass(); 550 551 enhancer = new Enhancer(); 552 enhancer.setSuperclass(ClassOnlyX.class); 553 enhancer.setCallback(NoOp.INSTANCE); 554 Object instance = enhancer.create(); 555 556 assertTrue(instance instanceof ClassOnlyX); 557 assertTrue(instance.getClass().equals(type)); 558 } 559 560 public void testSql() { 561 Enhancer.create(null, new Class[]{ java.sql.PreparedStatement.class }, TEST_INTERCEPTOR); 562 } 563 564 public void testEquals() throws Exception { 565 final boolean[] result = new boolean[]{ false }; 566 EqualsInterceptor intercept = new EqualsInterceptor(); 567 Object obj = Enhancer.create(null, intercept); 568 obj.equals(obj); 569 assertTrue(intercept.called); 570 } 571 572 public static class EqualsInterceptor implements MethodInterceptor { 573 final static Method EQUALS_METHOD = ReflectUtils.findMethod("Object.equals(Object)"); 574 boolean called; 575 576 public Object intercept(Object obj, 577 Method method, 578 Object[] args, 579 MethodProxy proxy) throws Throwable { 580 if (method.equals(EQUALS_METHOD)) { 581 return proxy.invoke(this, args); 582 } else { 583 return proxy.invokeSuper(obj, args); 584 } 585 } 586 587 public boolean equals(Object other) { 588 called = true; 589 return super.equals(other); 590 } 591 } 592 593 private static interface ExceptionThrower { 594 void throwsThrowable(int arg) throws Throwable; 595 void throwsException(int arg) throws Exception; 596 void throwsNothing(int arg); 597 } 598 599 private static class MyThrowable extends Throwable { } 600 private static class MyException extends Exception { } 601 private static class MyRuntimeException extends RuntimeException { } 602 603 public void testExceptions() { 604 Enhancer e = new Enhancer(); 605 e.setSuperclass(ExceptionThrower.class); 606 e.setCallback(new MethodInterceptor() { 607 public Object intercept(Object obj, 608 Method method, 609 Object[] args, 610 MethodProxy proxy) throws Throwable { 611 switch (((Integer)args[0]).intValue()) { 612 case 1: 613 throw new MyThrowable(); 614 case 2: 615 throw new MyException(); 616 case 3: 617 throw new MyRuntimeException(); 618 default: 619 return null; 620 } 621 } 622 }); 623 ExceptionThrower et = (ExceptionThrower)e.create(); 624 try { et.throwsThrowable(1); } catch (MyThrowable t) { } catch (Throwable t) { fail(); } 625 try { et.throwsThrowable(2); } catch (MyException t) { } catch (Throwable t) { fail(); } 626 try { et.throwsThrowable(3); } catch (MyRuntimeException t) { } catch (Throwable t) { fail(); } 627 628 try { et.throwsException(1); } catch (Throwable t) { assertTrue(t instanceof MyThrowable); } 629 try { et.throwsException(2); } catch (MyException t) { } catch (Throwable t) { fail(); } 630 try { et.throwsException(3); } catch (MyRuntimeException t) { } catch (Throwable t) { fail(); } 631 try { et.throwsException(4); } catch (Throwable t) { fail(); } 632 633 try { et.throwsNothing(1); } catch (Throwable t) { assertTrue(t instanceof MyThrowable); } 634 try { et.throwsNothing(2); } catch (Exception t) { assertTrue(t instanceof MyException); } 635 try { et.throwsNothing(3); } catch (MyRuntimeException t) { } catch (Throwable t) { fail(); } 636 try { et.throwsNothing(4); } catch (Throwable t) { fail(); } 637 } 638 639 public void testUnusedCallback() { 640 Enhancer e = new Enhancer(); 641 e.setCallbackTypes(new Class[]{ MethodInterceptor.class, NoOp.class }); 642 e.setCallbackFilter(new CallbackFilter() { 643 public int accept(Method method) { 644 return 0; 645 } 646 }); 647 e.createClass(); 648 } 649 }

This page was automatically generated by Maven