tmf: Move plugins to their own sub-directory
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / request / TmfEventRequest.java
1 /*******************************************************************************
2 * Copyright (c) 2009, 2015 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 * Alexandre Montplaisir - Consolidate constructors, merge with TmfDataRequest
12 *******************************************************************************/
13
14 package org.eclipse.tracecompass.tmf.core.request;
15
16 import java.util.concurrent.CountDownLatch;
17
18 import org.eclipse.tracecompass.internal.tmf.core.TmfCoreTracer;
19 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
20 import org.eclipse.tracecompass.tmf.core.filter.ITmfFilter;
21 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
22
23 /**
24 * TmfEventRequest's are used to obtain series of events from an event provider.
25 * Open ranges can be used, especially for continuous streaming.
26 * <p>
27 * The request is processed asynchronously by a TmfEventProvider and, as events
28 * become available, handleData() is invoked synchronously for each one.
29 * <p>
30 * The TmfEventProvider indicates that the request is completed by calling
31 * done(). The request can be cancelled at any time with cancel().
32 * <p>
33 * Typical usage:
34 *
35 * <pre><code>
36 * TmfEventRequest request = new TmfEventRequest(DataType.class, range, startIndex, nbEvents, priority) {
37 *
38 * public void handleData(ITmfEvent event) {
39 * // do something with the event
40 * }
41 *
42 * public void handleSuccess() {
43 * // callback for when the request completes successfully
44 * }
45 *
46 * public void handleFailure() {
47 * // callback for when the request fails due to an error
48 * }
49 *
50 * public void handleCancel() {
51 * // callback for when the request is cancelled via .cancel()
52 * }
53 *
54 * };
55 *
56 * eventProvider.sendRequest(request);
57 * </code></pre>
58 *
59 *
60 * TODO: Implement request failures (codes, etc...)
61 *
62 * @author Francois Chouinard
63 */
64 public abstract class TmfEventRequest implements ITmfEventRequest {
65
66 // ------------------------------------------------------------------------
67 // Constants
68 // ------------------------------------------------------------------------
69
70 private static int fRequestNumber = 0;
71
72 // ------------------------------------------------------------------------
73 // Attributes
74 // ------------------------------------------------------------------------
75
76 private final Class<? extends ITmfEvent> fDataType;
77 private final ExecutionType fExecType;
78
79 /** A unique request ID */
80 private final int fRequestId;
81
82 /** The requested events time range */
83 private final TmfTimeRange fRange;
84
85 /** The index (rank) of the requested event */
86 protected long fIndex;
87
88 /** The number of requested events (ALL_DATA for all) */
89 protected int fNbRequested;
90
91 /** The number of reads so far */
92 private int fNbRead;
93
94 private final CountDownLatch startedLatch = new CountDownLatch(1);
95 private final CountDownLatch completedLatch = new CountDownLatch(1);
96
97 private boolean fRequestRunning;
98 private boolean fRequestCompleted;
99 private boolean fRequestFailed;
100 private boolean fRequestCanceled;
101
102 private ITmfFilter fEventFilter;
103
104 // ------------------------------------------------------------------------
105 // Constructors
106 // ------------------------------------------------------------------------
107
108 /**
109 * Request 'n' events of a given type, for the *whole* trace, at the given
110 * priority.
111 *
112 * @param dataType
113 * The requested data type.
114 * @param index
115 * The index of the first event to retrieve. You can use '0' to
116 * start at the beginning of the trace.
117 * @param nbRequested
118 * The number of events requested. You can use
119 * {@link TmfEventRequest#ALL_DATA} to indicate you want all
120 * events in the trace.
121 * @param priority
122 * The requested execution priority.
123 */
124 public TmfEventRequest(Class<? extends ITmfEvent> dataType,
125 long index,
126 int nbRequested,
127 ExecutionType priority) {
128 this(dataType, TmfTimeRange.ETERNITY, index, nbRequested, priority);
129 }
130
131 /**
132 * Request 'n' events of a given type, for the given time range, at the
133 * given priority.
134 *
135 * @param dataType
136 * The requested data type.
137 * @param range
138 * The time range of the requested events. You can use
139 * {@link TmfTimeRange#ETERNITY} to indicate you want to cover
140 * the whole trace.
141 * @param index
142 * The index of the first event to retrieve. You can use '0' to
143 * start at the beginning of the trace.
144 * @param nbRequested
145 * The number of events requested. You can use
146 * {@link TmfEventRequest#ALL_DATA} to indicate you want all
147 * events in the time range.
148 * @param priority
149 * The requested execution priority.
150 */
151 public TmfEventRequest(Class<? extends ITmfEvent> dataType,
152 TmfTimeRange range,
153 long index,
154 int nbRequested,
155 ExecutionType priority) {
156
157 synchronized (TmfEventRequest.class) {
158 fRequestId = fRequestNumber++;
159 }
160 fDataType = dataType;
161 fIndex = index;
162 fNbRequested = nbRequested;
163 fExecType = priority;
164 fRange = range;
165 fNbRead = 0;
166
167 fRequestRunning = false;
168 fRequestCompleted = false;
169 fRequestFailed = false;
170 fRequestCanceled = false;
171
172 /* Setup the request tracing if it's enabled */
173 if (TmfCoreTracer.isRequestTraced()) {
174 String type = getClass().getName();
175 type = type.substring(type.lastIndexOf('.') + 1);
176 @SuppressWarnings("nls")
177 String message = "CREATED "
178 + (getExecType() == ExecutionType.BACKGROUND ? "(BG)" : "(FG)")
179 + " Type=" + type + " Index=" + getIndex() + " NbReq=" + getNbRequested()
180 + " Range=" + getRange()
181 + " DataType=" + getDataType().getSimpleName();
182 TmfCoreTracer.traceRequest(fRequestId, message);
183 }
184 }
185
186 // ------------------------------------------------------------------------
187 // Accessors
188 // ------------------------------------------------------------------------
189
190 @Override
191 public int getRequestId() {
192 return fRequestId;
193 }
194
195 @Override
196 public long getIndex() {
197 return fIndex;
198 }
199
200 @Override
201 public ExecutionType getExecType() {
202 return fExecType;
203 }
204
205 @Override
206 public int getNbRequested() {
207 return fNbRequested;
208 }
209
210 @Override
211 public synchronized int getNbRead() {
212 return fNbRead;
213 }
214
215 @Override
216 public synchronized boolean isRunning() {
217 return fRequestRunning;
218 }
219
220 @Override
221 public synchronized boolean isCompleted() {
222 return fRequestCompleted;
223 }
224
225 @Override
226 public synchronized boolean isFailed() {
227 return fRequestFailed;
228 }
229
230 @Override
231 public synchronized boolean isCancelled() {
232 return fRequestCanceled;
233 }
234
235 @Override
236 public Class<? extends ITmfEvent> getDataType() {
237 return fDataType;
238 }
239
240 @Override
241 public TmfTimeRange getRange() {
242 return fRange;
243 }
244
245 @Override
246 public ITmfFilter getProviderFilter() {
247 return fEventFilter;
248 }
249
250 @Override
251 public void setProviderFilter(ITmfFilter provider) {
252 fEventFilter = provider;
253 }
254
255 // ------------------------------------------------------------------------
256 // Setters
257 // ------------------------------------------------------------------------
258
259 /**
260 * This method is called by the event provider to set the index
261 * corresponding to the time range start time
262 *
263 * @param index
264 * The start time index
265 */
266 protected void setIndex(int index) {
267 fIndex = index;
268 }
269
270 @Override
271 public void setStartIndex(int index) {
272 setIndex(index);
273 }
274
275 // ------------------------------------------------------------------------
276 // Operators
277 // ------------------------------------------------------------------------
278
279 @Override
280 public void handleData(ITmfEvent event) {
281 fNbRead++;
282 }
283
284 @Override
285 public void handleStarted() {
286 if (TmfCoreTracer.isRequestTraced()) {
287 TmfCoreTracer.traceRequest(getRequestId(), "STARTED"); //$NON-NLS-1$
288 }
289 }
290
291 @Override
292 public void handleCompleted() {
293 boolean requestFailed = false;
294 boolean requestCanceled = false;
295 synchronized (this) {
296 requestFailed = fRequestFailed;
297 requestCanceled = fRequestCanceled;
298 }
299
300 if (requestFailed) {
301 handleFailure();
302 } else if (requestCanceled) {
303 handleCancel();
304 } else {
305 handleSuccess();
306 }
307 if (TmfCoreTracer.isRequestTraced()) {
308 TmfCoreTracer.traceRequest(getRequestId(), "COMPLETED (" + fNbRead + " events read)"); //$NON-NLS-1$ //$NON-NLS-2$
309 }
310 }
311
312 @Override
313 public void handleSuccess() {
314 if (TmfCoreTracer.isRequestTraced()) {
315 TmfCoreTracer.traceRequest(getRequestId(), "SUCCEEDED"); //$NON-NLS-1$
316 }
317 }
318
319 @Override
320 public void handleFailure() {
321 if (TmfCoreTracer.isRequestTraced()) {
322 TmfCoreTracer.traceRequest(getRequestId(), "FAILED"); //$NON-NLS-1$
323 }
324 }
325
326 @Override
327 public void handleCancel() {
328 if (TmfCoreTracer.isRequestTraced()) {
329 TmfCoreTracer.traceRequest(getRequestId(), "CANCELLED"); //$NON-NLS-1$
330 }
331 }
332
333 /**
334 * To suspend the client thread until the request starts (or is canceled).
335 *
336 * @throws InterruptedException
337 * If the thread was interrupted while waiting
338 */
339 public void waitForStart() throws InterruptedException {
340 while (!fRequestRunning) {
341 startedLatch.await();
342 }
343 }
344
345 @Override
346 public void waitForCompletion() throws InterruptedException {
347 while (!fRequestCompleted) {
348 completedLatch.await();
349 }
350 }
351
352 @Override
353 public void start() {
354 synchronized (this) {
355 fRequestRunning = true;
356 }
357 handleStarted();
358 startedLatch.countDown();
359 }
360
361 @Override
362 public void done() {
363 synchronized (this) {
364 if (!fRequestCompleted) {
365 fRequestRunning = false;
366 fRequestCompleted = true;
367 } else {
368 return;
369 }
370 }
371 try {
372 handleCompleted();
373 } finally {
374 completedLatch.countDown();
375 }
376 }
377
378 @Override
379 public void fail() {
380 synchronized (this) {
381 fRequestFailed = true;
382 }
383 done();
384 }
385
386 @Override
387 public void cancel() {
388 synchronized (this) {
389 fRequestCanceled = true;
390 }
391 done();
392 }
393
394 // ------------------------------------------------------------------------
395 // Object
396 // ------------------------------------------------------------------------
397
398 @Override
399 public String toString() {
400 String name = getClass().getName();
401 int dot = name.lastIndexOf('.');
402 if (dot >= 0) {
403 name = name.substring(dot + 1);
404 }
405 return '[' + name + '(' + getRequestId() + ',' + getDataType().getSimpleName() +
406 ',' + getExecType() + ',' + getRange() + ',' + getIndex() +
407 ',' + getNbRequested() + ")]"; //$NON-NLS-1$
408 }
409
410 }
This page took 0.04051 seconds and 6 git commands to generate.