1 /*******************************************************************************
2 * Copyright (c) 2009 Ericsson
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
10 * Francois Chouinard - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.signal
;
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
;
23 * <b><u>TmfSignalHandler</u></b>
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.
30 public class TmfSignalManager
{
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
[]>();
37 // If requested, add universal signal tracer
38 // TODO: to be revisited...
39 private static boolean fTraceIsActive
= false;
40 private static TmfSignalTracer fSignalTracer
;
43 fSignalTracer
= TmfSignalTracer
.getInstance();
44 addListener(fSignalTracer
);
48 public static synchronized void addListener(Object listener
) {
49 Method
[] methods
= getSignalHandlerMethods(listener
);
50 if (methods
.length
> 0)
51 fListeners
.put(listener
, methods
);
54 public static synchronized void removeListener(Object listener
) {
55 fListeners
.remove(listener
);
59 * Returns the list of signal handlers in the listener. Signal handler name
60 * is irrelevant; only the annotation (@TmfSignalHandler) is important.
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)) {
73 return handlers
.toArray(new Method
[handlers
.size()]);
77 * Invokes the handling methods that listens to signals of a given type.
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.
86 static public synchronized void dispatchSignal(TmfSignal signal
) {
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
>>();
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
);
99 if (!matchingMethods
.isEmpty()) {
100 listeners
.put(entry
.getKey(), matchingMethods
);
104 // Call the signal handlers
105 for (Map
.Entry
<Object
, List
<Method
>> entry
: listeners
.entrySet()) {
106 for (Method method
: entry
.getValue()) {
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