1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package fulmine.event.listener;
17
18 import static fulmine.util.Utils.logException;
19
20 import java.lang.reflect.ParameterizedType;
21 import java.lang.reflect.TypeVariable;
22 import java.util.Arrays;
23 import java.util.Map;
24
25 import fulmine.event.EventProcessor;
26 import fulmine.event.IEvent;
27 import fulmine.event.IEventManager;
28 import fulmine.event.IEventSource;
29 import fulmine.util.collection.CollectionFactory;
30 import fulmine.util.collection.CollectionUtils;
31 import fulmine.util.log.AsyncLog;
32 import fulmine.util.reference.AutoCreatingStore;
33 import fulmine.util.reference.IAutoCreatingStore;
34 import fulmine.util.reference.IObjectBuilder;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public abstract class AbstractEventHandler<T extends IEvent> implements
52 IEventListener
53 {
54 private final static AsyncLog LOG =
55 new AsyncLog(AbstractEventHandler.class);
56
57
58 final Class<? extends IEvent>[] eventFilter;
59
60
61
62
63
64
65 private final static class EventFilterBuilder implements
66 IObjectBuilder<Class<? extends IEvent>, Class<? extends IEvent>[]>
67 {
68 @SuppressWarnings("unchecked")
69 public Class<? extends IEvent>[] create(Class<? extends IEvent> key)
70 {
71 Class<? extends IEvent>[] filter = new Class[1];
72 filter[0] = key;
73 return filter;
74 }
75 }
76
77
78 private final static IAutoCreatingStore<Class<? extends IEvent>, Class<? extends IEvent>[]> eventFilterStore =
79 new AutoCreatingStore<Class<? extends IEvent>, Class<? extends IEvent>[]>(
80 new EventFilterBuilder());
81
82 @SuppressWarnings("unchecked")
83 public AbstractEventHandler()
84 {
85 super();
86
87 final ParameterizedType ptype = getParameterizedType(this);
88 if (ptype.getActualTypeArguments()[0] instanceof TypeVariable)
89 {
90 throw new IllegalArgumentException("Must be a parameterised class");
91 }
92 this.eventFilter =
93 eventFilterStore.get((Class<? extends IEvent>) ptype.getActualTypeArguments()[0]);
94 }
95
96
97
98
99
100
101
102
103
104
105
106
107 @SuppressWarnings("unchecked")
108 public static Map<Class<? extends IEvent>, IEventListener> getEventHandlerMappings(
109 AbstractEventHandler<? extends IEvent>... handlers)
110 {
111 Map<Class<? extends IEvent>, IEventListener> listeners =
112 CollectionFactory.newMap();
113 for (AbstractEventHandler<? extends IEvent> handler : handlers)
114 {
115 try
116 {
117
118
119 ParameterizedType ptype = getParameterizedType(handler);
120 if (ptype.getActualTypeArguments()[0] instanceof TypeVariable)
121 {
122 throw new IllegalArgumentException(
123 "Must be a parameterised class");
124 }
125 listeners.put(
126 (Class<? extends IEvent>) ptype.getActualTypeArguments()[0],
127 handler);
128 }
129 catch (Exception e)
130 {
131 logException(null, handler, e);
132 }
133 }
134 if (LOG.isTraceEnabled())
135 {
136 LOG.trace("Handler map for " + Arrays.toString(handlers) + " is "
137 + CollectionUtils.toFormattedString(listeners));
138 }
139 return listeners;
140 }
141
142
143
144
145
146
147
148
149
150
151 @SuppressWarnings("unchecked")
152 private static ParameterizedType getParameterizedType(
153 AbstractEventHandler<? extends IEvent> handler)
154 {
155 Class<? extends AbstractEventHandler> clazz = handler.getClass();
156 while (!(clazz.getGenericSuperclass() instanceof ParameterizedType))
157 {
158 clazz =
159 (Class<? extends AbstractEventHandler>) clazz.getSuperclass();
160 }
161 return (ParameterizedType) clazz.getGenericSuperclass();
162 }
163
164 @SuppressWarnings("unchecked")
165 public final void update(IEvent event)
166 {
167 if (getLog().isDebugEnabled())
168 {
169 getLog().debug("update event=" + event);
170 }
171 handle((T) event);
172 }
173
174 public void addedAsListenerFor(IEventSource source)
175 {
176 }
177
178 public void removedAsListenerFrom(IEventSource source)
179 {
180 }
181
182 public final Class<? extends IEvent>[] getEventTypeFilter()
183 {
184 return this.eventFilter;
185 }
186
187
188
189
190
191
192
193
194
195 public abstract void handle(T event);
196
197
198
199
200
201
202 protected abstract AsyncLog getLog();
203
204 }