소스 검색

Add methods to ListenerList to proxy calls nicely

Change-Id: Ie1b86ffca587c8cc97bcc0a1ff440c4832e126bf
Fixes-Issue: CLIENT-298
Reviewed-on: http://gerrit.dmdirc.com/2143
Reviewed-by: Greg Holmes <greg@dmdirc.com>
Automatic-Compile: DMDirc Build Manager
tags/0.7rc1
Chris Smith 13 년 전
부모
커밋
fefaaceb21
1개의 변경된 파일58개의 추가작업 그리고 0개의 파일을 삭제
  1. 58
    0
      src/com/dmdirc/util/ListenerList.java

+ 58
- 0
src/com/dmdirc/util/ListenerList.java 파일 보기

@@ -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
 }

Loading…
취소
저장