/Users/lyon/j4p/src/classUtils/delegate/Delegator.java
|
1 package classUtils.delegate;
2
3
4 public class Delegator {
5
6 // preloaded Method objects for the methods in java.lang.Object
7 private static java.lang.reflect.Method hashCodeMethod;
8 private static java.lang.reflect.Method equalsMethod;
9 private static java.lang.reflect.Method toStringMethod;
10
11 static {
12 try {
13 hashCodeMethod = Object.class.getMethod("hashCode", null);
14 equalsMethod =
15 Object.class.getMethod("equals", new Class[]{Object.class
16 });
17 toStringMethod = Object.class.getMethod("toString", null);
18 } catch (NoSuchMethodException e) {
19 throw new NoSuchMethodError(e.getMessage());
20 }
21 }
22
23
24 private Class[] interfaces;
25 private Object[] delegates;
26
27 public Delegator(Class[] interfaces, Object[] delegates) {
28 this.interfaces = (Class[]) interfaces.clone();
29 this.delegates = (Object[]) delegates.clone();
30 }
31
32 public Object invoke(Object proxy, java.lang.reflect.Method m, Object[] args)
33 throws Throwable {
34 Class declaringClass = m.getDeclaringClass();
35
36 if (declaringClass == Object.class) {
37 if (m.equals(hashCodeMethod)) {
38 return proxyHashCode(proxy);
39 } else if (m.equals(equalsMethod)) {
40 return proxyEquals(proxy, args[0]);
41 } else if (m.equals(toStringMethod)) {
42 return proxyToString(proxy);
43 } else {
44 throw new InternalError(
45 "unexpected Object method dispatched: " + m);
46 }
47 } else {
48 for (int i = 0; i < interfaces.length; i++) {
49 if (declaringClass.isAssignableFrom(interfaces[i])) {
50 try {
51 return m.invoke(delegates[i], args);
52 } catch (java.lang.reflect.InvocationTargetException e) {
53 throw e.getTargetException();
54 }
55 }
56 }
57
58 return invokeNotDelegated(proxy, m, args);
59 }
60 }
61
62 protected Object invokeNotDelegated(Object proxy, java.lang.reflect.Method m,
63 Object[] args)
64 throws Throwable {
65 throw new InternalError("unexpected method dispatched: " + m);
66 }
67
68 protected Integer proxyHashCode(Object proxy) {
69 return new Integer(System.identityHashCode(proxy));
70 }
71
72 protected Boolean proxyEquals(Object proxy, Object other) {
73 return (proxy == other ? Boolean.TRUE : Boolean.FALSE);
74 }
75
76 protected String proxyToString(Object proxy) {
77 return proxy.getClass().getName() + '@' +
78 Integer.toHexString(proxy.hashCode());
79 }
80 }