Monster merge from the integration branch. Still some problems left and JUnits failing.
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf / src / org / eclipse / linuxtools / tmf / signal / TmfSignalManager.java
CommitLineData
8c8bf09f 1/*******************************************************************************
e31e01e8 2 * Copyright (c) 2009, 2010 Ericsson
8c8bf09f
ASL
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
13package org.eclipse.linuxtools.tmf.signal;
14
15import java.lang.reflect.InvocationTargetException;
16import java.lang.reflect.Method;
17import java.util.ArrayList;
18import java.util.HashMap;
19import java.util.List;
20import java.util.Map;
21
22/**
23 * <b><u>TmfSignalHandler</u></b>
24 * <p>
8d2e2848
FC
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.
8c8bf09f
ASL
28 * <p>
29 */
30public class TmfSignalManager {
31
8d2e2848
FC
32 // The set of event listeners and their corresponding handler methods.
33 // Note: listeners could be restricted to ITmfComponents but there is no
e31e01e8
FC
34 // harm in letting anyone use this since it is not tied to anything but
35 // the signal data type.
8c8bf09f
ASL
36 static private Map<Object, Method[]> fListeners = new HashMap<Object, Method[]>();
37
8d2e2848 38 // If requested, add universal signal tracer
e31e01e8 39 // TODO: Temporary solution: should be enabled/disabled dynamically
8f965dd5 40 private static boolean fTraceIsActive = false;
8d2e2848 41 private static TmfSignalTracer fSignalTracer;
82b08e62
FC
42 static {
43 if (fTraceIsActive) {
8d2e2848 44 fSignalTracer = TmfSignalTracer.getInstance();
e31e01e8 45 register(fSignalTracer);
82b08e62
FC
46 }
47 }
8c8bf09f 48
e31e01e8 49 public static synchronized void register(Object listener) {
8c8bf09f
ASL
50 Method[] methods = getSignalHandlerMethods(listener);
51 if (methods.length > 0)
82b08e62 52 fListeners.put(listener, methods);
8c8bf09f
ASL
53 }
54
e31e01e8 55 public static synchronized void deregister(Object listener) {
82b08e62 56 fListeners.remove(listener);
8c8bf09f
ASL
57 }
58
59 /**
8d2e2848
FC
60 * Returns the list of signal handlers in the listener. Signal handler name
61 * is irrelevant; only the annotation (@TmfSignalHandler) is important.
62 *
63 * @param listener
64 * @return
65 */
66 static private Method[] getSignalHandlerMethods(Object listener) {
67 List<Method> handlers = new ArrayList<Method>();
68 Method[] methods = listener.getClass().getMethods();
69 for (Method method : methods) {
70 if (method.isAnnotationPresent(TmfSignalHandler.class)) {
71 handlers.add(method);
72 }
73 }
74 return handlers.toArray(new Method[handlers.size()]);
75 }
76
77 /**
78 * Invokes the handling methods that listens to signals of a given type.
8c8bf09f
ASL
79 *
80 * The list of handlers is built on-the-fly to allow for the dynamic
81 * creation/deletion of signal handlers. Since the number of signal
82 * handlers shouldn't be too high, this is not a big performance issue
83 * to pay for the flexibility.
84 *
fc6ccf6f
FC
85 * For synchronization purposes, the signal is bracketed by two synch signals.
86 *
87 * @param signal the signal to dispatch
8c8bf09f 88 */
fc6ccf6f 89 static int fSynchId = 0;
8d2e2848 90 static public synchronized void dispatchSignal(TmfSignal signal) {
fc6ccf6f
FC
91 fSynchId++;
92 sendSignal(new TmfStartSynchSignal(fSynchId));
93 signal.setReference(fSynchId);
94 sendSignal(signal);
95 sendSignal(new TmfEndSynchSignal(fSynchId));
550d787e 96// Tracer.traceSignal(signal);
fc6ccf6f
FC
97 }
98
99 static private void sendSignal(TmfSignal signal) {
8c8bf09f
ASL
100
101 // Build the list of listener methods that are registered for this signal
102 Class<?> signalClass = signal.getClass();
103 Map<Object, List<Method>> listeners = new HashMap<Object, List<Method>>();
82b08e62 104 listeners.clear();
8c8bf09f 105 for (Map.Entry<Object, Method[]> entry : fListeners.entrySet()) {
82b08e62 106 List<Method> matchingMethods = new ArrayList<Method>();
8c8bf09f
ASL
107 for (Method method : entry.getValue()) {
108 if (method.getParameterTypes()[0].isAssignableFrom(signalClass)) {
109 matchingMethods.add(method);
110 }
111 }
112 if (!matchingMethods.isEmpty()) {
113 listeners.put(entry.getKey(), matchingMethods);
114 }
115 }
116
e31e01e8 117 // Call the signal handlers
8c8bf09f
ASL
118 for (Map.Entry<Object, List<Method>> entry : listeners.entrySet()) {
119 for (Method method : entry.getValue()) {
8f965dd5
FC
120 try {
121 method.invoke(entry.getKey(), new Object[] { signal });
122 } catch (IllegalArgumentException e) {
123 // TODO Auto-generated catch block
8f965dd5
FC
124 } catch (IllegalAccessException e) {
125 // TODO Auto-generated catch block
8f965dd5
FC
126 } catch (InvocationTargetException e) {
127 // TODO Auto-generated catch block
8f965dd5 128 }
8c8bf09f
ASL
129 }
130 }
131 }
132
8f965dd5 133}
This page took 0.034483 seconds and 5 git commands to generate.