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