General improvements:
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf / src / org / eclipse / linuxtools / tmf / signal / TmfSignalManager.java
1 /*******************************************************************************
2 * Copyright (c) 2009 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Francois Chouinard - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.linuxtools.tmf.signal;
14
15 import java.lang.reflect.InvocationTargetException;
16 import java.lang.reflect.Method;
17 import java.util.ArrayList;
18 import java.util.HashMap;
19 import java.util.List;
20 import java.util.Map;
21
22 /**
23 * <b><u>TmfSignalHandler</u></b>
24 * <p>
25 * This class manages the set of signal listeners and the signals they are
26 * interested in. When a signal is broadcasted, the appropriate listeners
27 * signal handlers are invoked.
28 * <p>
29 */
30 public class TmfSignalManager {
31
32 // The set of event listeners and their corresponding handler methods.
33 // Note: listeners could be restricted to ITmfComponents but there is no
34 // harm in letting anyone use this
35 static private Map<Object, Method[]> fListeners = new HashMap<Object, Method[]>();
36
37 // If requested, add universal signal tracer
38 // TODO: to be revisited...
39 private static boolean fTraceIsActive = false;
40 private static TmfSignalTracer fSignalTracer;
41 static {
42 if (fTraceIsActive) {
43 fSignalTracer = TmfSignalTracer.getInstance();
44 addListener(fSignalTracer);
45 }
46 }
47
48 public static synchronized void addListener(Object listener) {
49 Method[] methods = getSignalHandlerMethods(listener);
50 if (methods.length > 0)
51 fListeners.put(listener, methods);
52 }
53
54 public static synchronized void removeListener(Object listener) {
55 fListeners.remove(listener);
56 }
57
58 /**
59 * Returns the list of signal handlers in the listener. Signal handler name
60 * is irrelevant; only the annotation (@TmfSignalHandler) is important.
61 *
62 * @param listener
63 * @return
64 */
65 static private Method[] getSignalHandlerMethods(Object listener) {
66 List<Method> handlers = new ArrayList<Method>();
67 Method[] methods = listener.getClass().getMethods();
68 for (Method method : methods) {
69 if (method.isAnnotationPresent(TmfSignalHandler.class)) {
70 handlers.add(method);
71 }
72 }
73 return handlers.toArray(new Method[handlers.size()]);
74 }
75
76 /**
77 * Invokes the handling methods that listens to signals of a given type.
78 *
79 * The list of handlers is built on-the-fly to allow for the dynamic
80 * creation/deletion of signal handlers. Since the number of signal
81 * handlers shouldn't be too high, this is not a big performance issue
82 * to pay for the flexibility.
83 *
84 * @param signal
85 */
86 static public synchronized void dispatchSignal(TmfSignal signal) {
87
88 // Build the list of listener methods that are registered for this signal
89 Class<?> signalClass = signal.getClass();
90 Map<Object, List<Method>> listeners = new HashMap<Object, List<Method>>();
91 listeners.clear();
92 for (Map.Entry<Object, Method[]> entry : fListeners.entrySet()) {
93 List<Method> matchingMethods = new ArrayList<Method>();
94 for (Method method : entry.getValue()) {
95 if (method.getParameterTypes()[0].isAssignableFrom(signalClass)) {
96 matchingMethods.add(method);
97 }
98 }
99 if (!matchingMethods.isEmpty()) {
100 listeners.put(entry.getKey(), matchingMethods);
101 }
102 }
103
104 // Call the signal handlers
105 for (Map.Entry<Object, List<Method>> entry : listeners.entrySet()) {
106 for (Method method : entry.getValue()) {
107 try {
108 method.invoke(entry.getKey(), new Object[] { signal });
109 } catch (IllegalArgumentException e) {
110 // TODO Auto-generated catch block
111 } catch (IllegalAccessException e) {
112 // TODO Auto-generated catch block
113 } catch (InvocationTargetException e) {
114 // TODO Auto-generated catch block
115 }
116 }
117 }
118 }
119
120 }
This page took 0.03632 seconds and 6 git commands to generate.