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 * TODO: Implement me. Please.
27 * TODO: Error/exception handling
29 public class TmfSignalManager
{
32 * The set of event listeners and their corresponding handler methods.
34 static private Map
<Object
, Method
[]> fListeners
= new HashMap
<Object
, Method
[]>();
36 // TODO: read from the preferences
37 private static boolean fTraceIsActive
= false;
38 private static TmfSignalTrace fSignalTracer
;
40 // private static TmfSignalManager fInstance;
44 fSignalTracer
= new TmfSignalTrace();
45 addListener(fSignalTracer
);
49 public static synchronized void addListener(Object listener
) {
50 Method
[] methods
= getSignalHandlerMethods(listener
);
51 if (methods
.length
> 0)
52 fListeners
.put(listener
, methods
);
55 public static synchronized void removeListener(Object listener
) {
56 fListeners
.remove(listener
);
59 // public static TmfSignalManager getInstance() {
60 // if (fInstance == null) {
61 // fInstance = new TmfSignalManager();
67 * Invokes the handling methods that expect this signal.
69 * The list of handlers is built on-the-fly to allow for the dynamic
70 * creation/deletion of signal handlers. Since the number of signal
71 * handlers shouldn't be too high, this is not a big performance issue
72 * to pay for the flexibility.
76 // private class Dispatch implements Runnable {
78 // private final Method method;
79 // private final Object entry;
80 // private final Object signal;
82 // public Dispatch(Method m, Object e, Object s) {
88 // public void run() {
90 // method.invoke(entry, new Object[] { signal });
91 // } catch (IllegalArgumentException e) {
92 // // TODO Auto-generated catch block
93 // e.printStackTrace();
94 // } catch (IllegalAccessException e) {
95 // // TODO Auto-generated catch block
96 // e.printStackTrace();
97 // } catch (InvocationTargetException e) {
98 // // TODO Auto-generated catch block
99 // e.printStackTrace();
104 // private void dispatch(Method method, Object key, Object signal) {
105 // Dispatch disp = new Dispatch(method, key, signal);
106 // new Thread(disp).start();
109 static public synchronized void dispatchSignal(Object signal
) {
111 // Build the list of listener methods that are registered for this signal
112 Class
<?
> signalClass
= signal
.getClass();
113 Map
<Object
, List
<Method
>> listeners
= new HashMap
<Object
, List
<Method
>>();
115 for (Map
.Entry
<Object
, Method
[]> entry
: fListeners
.entrySet()) {
116 List
<Method
> matchingMethods
= new ArrayList
<Method
>();
117 for (Method method
: entry
.getValue()) {
118 if (method
.getParameterTypes()[0].isAssignableFrom(signalClass
)) {
119 matchingMethods
.add(method
);
122 if (!matchingMethods
.isEmpty()) {
123 listeners
.put(entry
.getKey(), matchingMethods
);
127 // Call the signal handlers
128 for (Map
.Entry
<Object
, List
<Method
>> entry
: listeners
.entrySet()) {
129 for (Method method
: entry
.getValue()) {
130 // getInstance().dispatch(method, entry.getKey(), signal);
132 method
.invoke(entry
.getKey(), new Object
[] { signal
});
133 } catch (IllegalArgumentException e
) {
134 // TODO Auto-generated catch block
135 } catch (IllegalAccessException e
) {
136 // TODO Auto-generated catch block
137 } catch (InvocationTargetException e
) {
138 // TODO Auto-generated catch block
145 * Returns the list of signal handlers in the listener. Signal handler name
146 * is irrelevant; only the annotation (@TmfSignalHandler) is important.
151 static private Method
[] getSignalHandlerMethods(Object listener
) {
152 List
<Method
> handlers
= new ArrayList
<Method
>();
153 Method
[] methods
= listener
.getClass().getMethods();
154 for (Method method
: methods
) {
155 if (method
.isAnnotationPresent(TmfSignalHandler
.class)) {
156 handlers
.add(method
);
159 return handlers
.toArray(new Method
[handlers
.size()]);