KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > common > proxy > GenericInvocationHandler


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.common.proxy;
5
6 import com.tc.logging.TCLogger;
7 import com.tc.logging.TCLogging;
8 import com.tc.util.Assert;
9
10 import java.lang.reflect.InvocationHandler JavaDoc;
11 import java.lang.reflect.InvocationTargetException JavaDoc;
12 import java.lang.reflect.Method JavaDoc;
13 import java.lang.reflect.Proxy JavaDoc;
14
15 /**
16  * This class provides a generic {@link InvocationHandler}, used with {@link java.lang.reflect.Proxy}, that allows
17  * some sanity in generating proxies. Basically, you create a {@link GenericInvocationHandler}as the target of a
18  * {@link Proxy}. When called, the invocation handler will look in an object that you give it at construction time for
19  * a method of the correct signature, and invoke that.
20  * </p>
21  * <p>
22  * If no such method exists, the method {@link #handlerMethodNotFound}will be called instead. By default, this simply
23  * throws a {@link RuntimeException}, but can be overridden in subclasses to do anything you want.
24  */

25 class GenericInvocationHandler implements InvocationHandler JavaDoc {
26   private static final TCLogger logger = TCLogging.getLogger(GenericInvocationHandler.class);
27
28   private Object JavaDoc handler;
29
30   /**
31    * Only should be called from subclasses that know what they're doing.
32    */

33   protected GenericInvocationHandler() {
34     this.handler = null;
35   }
36
37   public GenericInvocationHandler(Object JavaDoc handler) {
38     Assert.eval(handler != null);
39     this.handler = handler;
40   }
41
42   public Object JavaDoc invoke(Object JavaDoc proxy, Method JavaDoc method, Object JavaDoc[] args) throws Throwable JavaDoc {
43     try {
44       return invokeInternal(proxy, method, args);
45     } catch (Throwable JavaDoc t) {
46       // try to log, but make sure the orignal exception is always re-thrown, even if
47
// logging somehow manages to throw an exception
48
try {
49         if (logger.isDebugEnabled()) {
50           logger.debug("EXCEPTION thrown trying to call " + method, t);
51         }
52       } catch (Throwable JavaDoc loggingError) {
53         // too bad, logging blows
54
}
55
56       throw t;
57     }
58   }
59
60   protected Object JavaDoc getHandler() {
61     return this.handler;
62   }
63
64   protected void setHandler(Object JavaDoc o) {
65     this.handler = o;
66   }
67
68   private Object JavaDoc invokeInternal(Object JavaDoc proxy, Method JavaDoc method, Object JavaDoc[] args) throws Throwable JavaDoc {
69     try {
70       final Method JavaDoc theMethod = handler.getClass().getMethod(method.getName(), method.getParameterTypes());
71       try {
72         theMethod.setAccessible(true);
73       } catch (SecurityException JavaDoc se) {
74         logger.warn("Cannot setAccessible(true) for method [" + theMethod + "], " + se.getMessage());
75       }
76       return theMethod.invoke(handler, args);
77     } catch (InvocationTargetException JavaDoc ite) {
78       // We need to unwrap this; we want to throw what the method actually
79
// threw, not an InvocationTargetException (which causes all sorts of
80
// madness, since it's unlikely the interface method throws that
81
// exception, and you'll end up with an UndeclaredThrowableException.
82
// Blech.)
83
throw ite.getCause();
84     } catch (NoSuchMethodException JavaDoc nsme) {
85       return handlerMethodNotFound(proxy, method, args);
86     }
87   }
88
89   private String JavaDoc describeClasses(Class JavaDoc[] classes) {
90     StringBuffer JavaDoc out = new StringBuffer JavaDoc();
91     for (int i = 0; i < classes.length; ++i) {
92       if (i > 0) out.append(", ");
93       out.append(classes[i].getName());
94     }
95     return out.toString();
96   }
97
98   protected Object JavaDoc handlerMethodNotFound(Object JavaDoc proxy, Method JavaDoc method, Object JavaDoc[] args) throws Throwable JavaDoc {
99     throw new NoSuchMethodError JavaDoc("Handler " + handler + " does not have a method named " + method.getName()
100                                 + " that is " + "has argument types " + describeClasses(method.getParameterTypes()));
101   }
102
103 }
Popular Tags