1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package com.gridsystems.nextgrid.api.pom;
19
20 import java.lang.reflect.Method;
21 import java.util.LinkedHashSet;
22 import java.util.Set;
23 import java.util.concurrent.locks.ReentrantReadWriteLock;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28 import nextgrid.api.pem.DiscoveryEvent;
29 import nextgrid.api.pem.DiscoveryListener;
30 import nextgrid.api.pem.POMListener;
31 import nextgrid.api.pem.ProcessEvent;
32 import nextgrid.api.pem.ProcessListener;
33 import nextgrid.api.pom.Process;
34 import nextgrid.api.pom.ProcessException;
35
36
37
38
39
40
41
42
43
44 public abstract class PemHelper implements Process {
45
46
47
48
49 private static final Log LOG = LogFactory.getLog("ENACTOR");
50
51
52
53
54 private Set<POMListener> listeners = new LinkedHashSet<POMListener>();
55
56
57
58
59 private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
60
61
62
63
64 public Process copy() {
65 try {
66 PemHelper copy = (PemHelper)this.clone();
67 copy.listeners = new LinkedHashSet<POMListener>();
68 copy.lock = new ReentrantReadWriteLock(true);
69
70 return copy;
71 } catch (CloneNotSupportedException e) {
72 throw new InternalError("Unexpected CloneNotSupported exception");
73 }
74 }
75
76
77
78
79
80
81 public final void addListener(POMListener listener) {
82 if (listener == null) {
83 return;
84 }
85
86 lock.writeLock().lock();
87 try {
88 this.listeners.add(listener);
89 } finally {
90 lock.writeLock().unlock();
91 }
92 }
93
94
95
96
97
98
99 public final void removeListener(POMListener listener) {
100 if (listener == null) {
101 return;
102 }
103
104 lock.writeLock().lock();
105 try {
106 this.listeners.remove(listener);
107 } finally {
108 lock.writeLock().unlock();
109 }
110 }
111
112
113
114
115
116
117 public final void fireDiscovererSelected(DiscoveryEvent event) {
118 fireEvent(DiscoveryListener.class, "discovererSelected", event);
119 }
120
121
122
123
124
125
126 public final void fireDiscoveryStarting(DiscoveryEvent event) {
127 fireEvent(DiscoveryListener.class, "discoveryStarting", event);
128 }
129
130
131
132
133
134
135 public final void fireDiscoveryFinished(DiscoveryEvent event) {
136 fireEvent(DiscoveryListener.class, "discoveryFinished", event);
137 }
138
139
140
141
142
143
144 public final void fireDiscoveryFailed(DiscoveryEvent event) {
145 fireEvent(DiscoveryListener.class, "discoveryFailed", event);
146 }
147
148
149
150
151
152
153 public final void fireProcessSelected(ProcessEvent event) {
154 fireEvent(ProcessListener.class, "processSelected", event);
155 }
156
157
158
159
160
161
162 public final void fireProcessFinished(ProcessEvent event) {
163 fireEvent(ProcessListener.class, "processFinished", event);
164 }
165
166
167
168
169
170
171 public final void fireProcessFailed(ProcessEvent event) {
172 fireEvent(ProcessListener.class, "processFailed", event);
173 }
174
175
176
177
178 public final void fireProcessFinished() {
179 fireProcessFinished(new ProcessEvent(this));
180 }
181
182
183
184
185 public final void fireProcessEvaluated() {
186 fireEvent(ProcessListener.class, "processEvaluated", new ProcessEvent(this));
187 }
188
189
190
191
192 public final void fireProcessStarted() {
193 fireEvent(ProcessListener.class, "processStarted", new ProcessEvent(this));
194 }
195
196
197
198
199
200
201 public final void fireProcessFailed(ProcessException e) {
202 ProcessEvent event = new ProcessEvent(this);
203 event.setException(e);
204 fireProcessFailed(event);
205 }
206
207
208
209
210
211
212
213
214
215 protected final void fireEvent(Class<?> iface, String method, Object event) {
216
217 if (iface == null || method == null || event == null) {
218 return;
219 }
220 fireEvent(iface, method, event, true);
221 }
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236 @SuppressWarnings("unchecked")
237 private void fireEvent(Class iface, String method, Object event,
238 boolean direct) {
239
240
241 Method m;
242 try {
243 m = iface.getMethod(method, event.getClass());
244 } catch (SecurityException e) {
245 LOG.fatal("Security policy prevents access to listener", e);
246 throw new RuntimeException(e);
247 } catch (NoSuchMethodException e) {
248 LOG.fatal("Method '" + method + "'not found in listener", e);
249 throw new RuntimeException("Method '" + method + "'not found in listener",
250 e);
251 }
252
253
254 lock.readLock().lock();
255 try {
256
257
258 for (POMListener listener : listeners) {
259 if (direct || listener.isListeningToDescendants()) {
260 if (iface.isAssignableFrom(listener.getClass())) {
261
262 m.invoke(listener, event);
263 }
264 }
265 }
266 } catch (Exception e) {
267 LOG.error("Unexpected exception", e);
268 throw new RuntimeException("Unexpected exception", e);
269 } finally {
270 lock.readLock().unlock();
271 }
272
273
274 Process parentProcess = this.getParent();
275 if (parentProcess instanceof ProcessImpl) {
276 ((PemHelper)parentProcess).fireEvent(iface, method, event, false);
277 }
278 }
279
280 }