Browse Source

Add some nice proxy methods for calling callbacks

Change-Id: I09a4f22fc43a549aa3c9d0fd8794061d7feb31cb
Reviewed-on: http://gerrit.dmdirc.com/2001
Automatic-Compile: DMDirc Build Manager
Reviewed-by: Greg Holmes <greg@dmdirc.com>
tags/0.7rc1
Chris Smith 13 years ago
parent
commit
f14215375b

+ 15
- 0
src/com/dmdirc/parser/common/BaseParser.java View File

@@ -23,6 +23,7 @@
23 23
 package com.dmdirc.parser.common;
24 24
 
25 25
 import com.dmdirc.parser.interfaces.Parser;
26
+import com.dmdirc.parser.interfaces.callbacks.CallbackInterface;
26 27
 
27 28
 import java.net.URI;
28 29
 import java.util.HashMap;
@@ -122,6 +123,20 @@ public abstract class BaseParser implements Parser {
122 123
         return callbackManager;
123 124
     }
124 125
 
126
+    /**
127
+     * Gets a proxy object which can be used to despatch callbacks of the
128
+     * specified type. Callers may pass <code>null</code> for the first two
129
+     * arguments of any callback, and these will automatically be replaced
130
+     * by the relevant Parser instance and the current date.
131
+     *
132
+     * @param <T> The type of the callback to retrieve
133
+     * @param callback The callback to retrieve
134
+     * @return A proxy object which can be used to call the specified callback
135
+     */
136
+    protected <T extends CallbackInterface> T getCallback(final Class<T> callback) {
137
+        return callbackManager.getCallback(callback);
138
+    }
139
+
125 140
     /** {@inheritDoc} */
126 141
     @Override
127 142
     public Map<Object, Object> getMap() {

+ 59
- 0
src/com/dmdirc/parser/common/CallbackManager.java View File

@@ -26,6 +26,10 @@ import com.dmdirc.parser.interfaces.Parser;
26 26
 import com.dmdirc.parser.interfaces.SpecificCallback;
27 27
 import com.dmdirc.parser.interfaces.callbacks.*; //NOPMD
28 28
 
29
+import java.lang.reflect.InvocationHandler;
30
+import java.lang.reflect.Method;
31
+import java.lang.reflect.Proxy;
32
+import java.util.Date;
29 33
 import java.util.HashMap;
30 34
 import java.util.Map;
31 35
 
@@ -71,8 +75,12 @@ public class CallbackManager {
71 75
     private final Map<Class<? extends CallbackInterface>, CallbackObject> callbackHash
72 76
             = new HashMap<Class<? extends CallbackInterface>, CallbackObject>();
73 77
 
78
+    /** A map of implementations to use for parser interfaces. */
74 79
     private final Map<Class<?>, Class<?>> implementationMap;
75 80
 
81
+    /** The parser this callback manager is for. */
82
+    private final Parser parser;
83
+
76 84
     /**
77 85
      * Constructor to create a CallbackManager.
78 86
      *
@@ -81,6 +89,7 @@ public class CallbackManager {
81 89
      */
82 90
     public CallbackManager(final Parser parser, final Map<Class<?>, Class<?>> implementationMap) {
83 91
         this.implementationMap = implementationMap;
92
+        this.parser = parser;
84 93
 
85 94
         initialise(parser);
86 95
     }
@@ -288,4 +297,54 @@ public class CallbackManager {
288 297
             final CallbackInterface o) {
289 298
         getCallbackType(callback).del(o);
290 299
     }
300
+
301
+    /**
302
+     * Gets a proxy object which can be used to despatch callbacks of the
303
+     * specified type. Callers may pass <code>null</code> for the first two
304
+     * arguments of any callback, and these will automatically be replaced
305
+     * by the relevant Parser instance and the current date.
306
+     *
307
+     * @param <T> The type of the callback to retrieve
308
+     * @param callback The callback to retrieve
309
+     * @return A proxy object which can be used to call the specified callback
310
+     */
311
+    @SuppressWarnings("unchecked")
312
+    public <T extends CallbackInterface> T getCallback(final Class<T> callback) {
313
+        return (T) Proxy.newProxyInstance(getClass().getClassLoader(),
314
+                new Class[]{ callback }, new CallbackHandler(callback));
315
+    }
316
+
317
+    /**
318
+     * A Proxy invocation handler for a specified parser callback.
319
+     */
320
+    private class CallbackHandler implements InvocationHandler {
321
+
322
+        /** The callback that should be called. */
323
+        private final Class<? extends CallbackInterface> callback;
324
+
325
+        /**
326
+         * Creates a new callback handler for the specified callback.
327
+         *
328
+         * @param callback The callback to handle
329
+         */
330
+        public CallbackHandler(final Class<? extends CallbackInterface> callback) {
331
+            this.callback = callback;
332
+        }
333
+
334
+        /** {@inheritDoc} */
335
+        @Override
336
+        public Object invoke(final Object proxy, final Method method, final Object[] args) {
337
+            final Object[] modifiedArgs = new Object[args.length - 2];
338
+            System.arraycopy(args, 2, modifiedArgs, 0, args.length - 2);
339
+
340
+            if (args[1] == null) {
341
+                getCallbackType(callback).call(modifiedArgs);
342
+            } else {
343
+                getCallbackType(callback).call((Date) args[1], modifiedArgs);
344
+            }
345
+
346
+            return null;
347
+        }
348
+
349
+    }
291 350
 }

Loading…
Cancel
Save