|
@@ -22,6 +22,10 @@
|
22
|
22
|
|
23
|
23
|
package com.dmdirc.util;
|
24
|
24
|
|
|
25
|
+import java.lang.reflect.InvocationHandler;
|
|
26
|
+import java.lang.reflect.InvocationTargetException;
|
|
27
|
+import java.lang.reflect.Method;
|
|
28
|
+import java.lang.reflect.Proxy;
|
25
|
29
|
import java.util.Collection;
|
26
|
30
|
import java.util.HashMap;
|
27
|
31
|
import java.util.Map;
|
|
@@ -126,4 +130,58 @@ public class ListenerList {
|
126
|
130
|
}
|
127
|
131
|
}
|
128
|
132
|
|
|
133
|
+ /**
|
|
134
|
+ * Returns a callable proxy of the specified type. Methods called on the
|
|
135
|
+ * returned proxy will be proxied to all of the registered listeners.
|
|
136
|
+ *
|
|
137
|
+ * @param <T> The type of listener to be called
|
|
138
|
+ * @param listenerType The type of listener to be called
|
|
139
|
+ * @return A proxy instance that can be used to call methods
|
|
140
|
+ */
|
|
141
|
+ public <T> T getCallable(final Class<T> listenerType) {
|
|
142
|
+ return (T) Proxy.newProxyInstance(getClass().getClassLoader(),
|
|
143
|
+ new Class[] { listenerType }, new CallHandler<T>(listenerType));
|
|
144
|
+ }
|
|
145
|
+
|
|
146
|
+ /**
|
|
147
|
+ * Utility class to handle calls to a "callable" interface as returned by
|
|
148
|
+ * {@link #getCallable(java.lang.Class)}.
|
|
149
|
+ *
|
|
150
|
+ * @param <T> The type of listener being called
|
|
151
|
+ */
|
|
152
|
+ private class CallHandler<T> implements InvocationHandler {
|
|
153
|
+
|
|
154
|
+ /** The type of listener this handler is handling. */
|
|
155
|
+ private final Class<T> listenerType;
|
|
156
|
+
|
|
157
|
+ /**
|
|
158
|
+ * Creates a new call handler for the specified type of listener.
|
|
159
|
+ *
|
|
160
|
+ * @param listenerType The type of listener to handle
|
|
161
|
+ */
|
|
162
|
+ public CallHandler(final Class<T> listenerType) {
|
|
163
|
+ this.listenerType = listenerType;
|
|
164
|
+ }
|
|
165
|
+
|
|
166
|
+ /** {@inheritDoc} */
|
|
167
|
+ @Override
|
|
168
|
+ public Object invoke(final Object proxy, final Method method,
|
|
169
|
+ final Object[] args) throws Throwable {
|
|
170
|
+ for (T target : get(listenerType)) {
|
|
171
|
+ try {
|
|
172
|
+ method.invoke(target, args);
|
|
173
|
+ } catch (IllegalAccessException ex) {
|
|
174
|
+ // Ignore, not possible
|
|
175
|
+ } catch (IllegalArgumentException ex) {
|
|
176
|
+ // Ignore, not possible
|
|
177
|
+ } catch (InvocationTargetException ex) {
|
|
178
|
+ throw ex.getCause();
|
|
179
|
+ }
|
|
180
|
+ }
|
|
181
|
+
|
|
182
|
+ return null;
|
|
183
|
+ }
|
|
184
|
+
|
|
185
|
+ }
|
|
186
|
+
|
129
|
187
|
}
|