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