(no commit message)
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf / src / org / eclipse / linuxtools / tmf / signal / TmfSignalManager.java
CommitLineData
8c8bf09f
ASL
1/*******************************************************************************
2 * Copyright (c) 2009, 2010 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
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>
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 */
30public 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 since it is not tied to anything but
35 // the signal data type.
36 static private Map<Object, Method[]> fListeners = new HashMap<Object, Method[]>();
37
38 // If requested, add universal signal tracer
39 // TODO: Temporary solution: should be enabled/disabled dynamically
40 private static boolean fTraceIsActive = false;
41 private static TmfSignalTracer fSignalTracer;
42 static {
43 if (fTraceIsActive) {
44 fSignalTracer = TmfSignalTracer.getInstance();
45 register(fSignalTracer);
46 }
47 }
48
49 public static synchronized void register(Object listener) {
50 Method[] methods = getSignalHandlerMethods(listener);
51 if (methods.length > 0)
52 fListeners.put(listener, methods);
53 }
54
55 public static synchronized void deregister(Object listener) {
56 fListeners.remove(listener);
57 }
58
59 /**
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.
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 *
85 * For synchronization purposes, the signal is bracketed by two synch signals.
86 *
87 * @param signal the signal to dispatch
88 */
89 static int fSynchId = 0;
90 static public synchronized void dispatchSignal(TmfSignal signal) {
91 fSynchId++;
92 sendSignal(new TmfStartSynchSignal(fSynchId));
93 signal.setReference(fSynchId);
94 sendSignal(signal);
95 sendSignal(new TmfEndSynchSignal(fSynchId));
96 }
97
98 static private void sendSignal(TmfSignal signal) {
99
100 // Build the list of listener methods that are registered for this signal
101 Class<?> signalClass = signal.getClass();
102 Map<Object, List<Method>> listeners = new HashMap<Object, List<Method>>();
103 listeners.clear();
104 for (Map.Entry<Object, Method[]> entry : fListeners.entrySet()) {
105 List<Method> matchingMethods = new ArrayList<Method>();
106 for (Method method : entry.getValue()) {
107 if (method.getParameterTypes()[0].isAssignableFrom(signalClass)) {
108 matchingMethods.add(method);
109 }
110 }
111 if (!matchingMethods.isEmpty()) {
112 listeners.put(entry.getKey(), matchingMethods);
113 }
114 }
115
116 // Call the signal handlers
117 for (Map.Entry<Object, List<Method>> entry : listeners.entrySet()) {
118 for (Method method : entry.getValue()) {
119 try {
120 method.invoke(entry.getKey(), new Object[] { signal });
121 } catch (IllegalArgumentException e) {
122 // TODO Auto-generated catch block
123 } catch (IllegalAccessException e) {
124 // TODO Auto-generated catch block
125 } catch (InvocationTargetException e) {
126 // TODO Auto-generated catch block
127 }
128 }
129 }
130 }
131
132}
This page took 0.030107 seconds and 5 git commands to generate.