Commit | Line | Data |
---|---|---|
d18dd09b | 1 | /******************************************************************************* |
60ae41e1 | 2 | * Copyright (c) 2009, 2014 Ericsson |
0283f7ff | 3 | * |
d18dd09b ASL |
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 | |
0283f7ff | 8 | * |
d18dd09b ASL |
9 | * Contributors: |
10 | * Francois Chouinard - Initial API and implementation | |
ea271da6 | 11 | * Patrick Tasse - Updated for removal of context clone |
d18dd09b ASL |
12 | *******************************************************************************/ |
13 | ||
2bdf0193 | 14 | package org.eclipse.tracecompass.tmf.tests.stubs.trace; |
d18dd09b ASL |
15 | |
16 | import java.io.FileNotFoundException; | |
17 | import java.io.IOException; | |
18 | import java.io.RandomAccessFile; | |
2b5c3b7e | 19 | import java.lang.reflect.Method; |
032ecd45 | 20 | import java.nio.ByteBuffer; |
2b5c3b7e BH |
21 | import java.util.LinkedList; |
22 | import java.util.List; | |
73005152 | 23 | import java.util.concurrent.locks.ReentrantLock; |
d18dd09b | 24 | |
2352aed9 | 25 | import org.eclipse.core.resources.IProject; |
20658947 | 26 | import org.eclipse.core.resources.IResource; |
a94410d9 MK |
27 | import org.eclipse.core.runtime.IStatus; |
28 | import org.eclipse.core.runtime.Status; | |
5733be39 | 29 | import org.eclipse.jdt.annotation.NonNull; |
2bdf0193 | 30 | import org.eclipse.tracecompass.internal.tmf.core.Activator; |
2b5c3b7e BH |
31 | import org.eclipse.tracecompass.internal.tmf.core.request.TmfCoalescedEventRequest; |
32 | import org.eclipse.tracecompass.tmf.core.component.TmfEventProvider; | |
2bdf0193 AM |
33 | import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; |
34 | import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException; | |
35 | import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; | |
36 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal; | |
37 | import org.eclipse.tracecompass.tmf.core.signal.TmfTraceSelectedSignal; | |
38 | import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; | |
39 | import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; | |
40 | import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp; | |
41 | import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; | |
42 | import org.eclipse.tracecompass.tmf.core.trace.ITmfEventParser; | |
43 | import org.eclipse.tracecompass.tmf.core.trace.TmfContext; | |
44 | import org.eclipse.tracecompass.tmf.core.trace.TmfTrace; | |
45 | import org.eclipse.tracecompass.tmf.core.trace.indexer.ITmfPersistentlyIndexable; | |
46 | import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint; | |
47 | import org.eclipse.tracecompass.tmf.core.trace.indexer.checkpoint.TmfCheckpoint; | |
48 | import org.eclipse.tracecompass.tmf.core.trace.location.ITmfLocation; | |
49 | import org.eclipse.tracecompass.tmf.core.trace.location.TmfLongLocation; | |
d18dd09b ASL |
50 | |
51 | /** | |
52 | * <b><u>TmfTraceStub</u></b> | |
53 | * <p> | |
8d2e2848 | 54 | * Dummy test trace. Use in conjunction with TmfEventParserStub. |
d18dd09b | 55 | */ |
5733be39 | 56 | public class TmfTraceStub extends TmfTrace implements ITmfPersistentlyIndexable { |
d18dd09b | 57 | |
e31e01e8 | 58 | // ------------------------------------------------------------------------ |
d18dd09b | 59 | // Attributes |
e31e01e8 | 60 | // ------------------------------------------------------------------------ |
d18dd09b ASL |
61 | |
62 | // The actual stream | |
ff4ed569 | 63 | private RandomAccessFile fTrace; |
d18dd09b | 64 | |
5733be39 AM |
65 | // The associated event parser |
66 | private final @NonNull ITmfEventParser fParser; | |
d18dd09b | 67 | |
73005152 | 68 | // The synchronization lock |
085d898f FC |
69 | private final ReentrantLock fLock = new ReentrantLock(); |
70 | ||
66262ad8 BH |
71 | private ITmfTimestamp fInitialRangeOffset = null; |
72 | ||
e31e01e8 | 73 | // ------------------------------------------------------------------------ |
d18dd09b | 74 | // Constructors |
e31e01e8 | 75 | // ------------------------------------------------------------------------ |
d18dd09b | 76 | |
ff0960ac AM |
77 | /** |
78 | * Default constructor | |
79 | */ | |
20658947 FC |
80 | public TmfTraceStub() { |
81 | super(); | |
5733be39 | 82 | fParser = new TmfEventParserStub(this); |
20658947 FC |
83 | } |
84 | ||
d18dd09b | 85 | /** |
ff0960ac AM |
86 | * Constructor with which you can specify a custom streaming interval. The |
87 | * parser and indexer won't be specified. | |
88 | * | |
3ef62bac | 89 | * @param path |
ff0960ac | 90 | * The path to the trace file |
e31e01e8 | 91 | * @param cacheSize |
ff0960ac AM |
92 | * The cache size |
93 | * @param interval | |
94 | * The trace streaming interval | |
95 | * @throws TmfTraceException | |
96 | * If an error occurred opening the trace | |
8d2e2848 | 97 | */ |
ff0960ac AM |
98 | public TmfTraceStub(final String path, |
99 | final int cacheSize, | |
100 | final long interval) throws TmfTraceException { | |
5733be39 | 101 | super(null, ITmfEvent.class, path, cacheSize, interval); |
ff0960ac | 102 | setupTrace(path); |
5733be39 | 103 | fParser = new TmfEventParserStub(this); |
1703b536 FC |
104 | } |
105 | ||
20658947 | 106 | /** |
ff0960ac AM |
107 | * Constructor to specify the parser and indexer. The streaming interval |
108 | * will be 0. | |
109 | * | |
20658947 | 110 | * @param path |
ff0960ac | 111 | * The path to the trace file |
20658947 | 112 | * @param cacheSize |
ff0960ac | 113 | * The cache size |
ff4ed569 | 114 | * @param waitForCompletion |
ff0960ac | 115 | * Do we block the caller until the trace is indexed, or not. |
ff0960ac AM |
116 | * @param parser |
117 | * The trace parser. If left 'null', it will use a | |
118 | * {@link TmfEventParserStub}. | |
119 | * @throws TmfTraceException | |
120 | * If an error occurred opening the trace | |
8d2e2848 | 121 | */ |
ff0960ac AM |
122 | public TmfTraceStub(final String path, |
123 | final int cacheSize, | |
124 | final boolean waitForCompletion, | |
ff0960ac | 125 | final ITmfEventParser parser) throws TmfTraceException { |
5733be39 | 126 | super(null, ITmfEvent.class, path, cacheSize, 0); |
ff0960ac | 127 | setupTrace(path); |
5733be39 | 128 | fParser = ((parser != null) ? parser : new TmfEventParserStub(this)); |
07671572 | 129 | if (waitForCompletion) { |
51e75066 | 130 | indexTrace(true); |
07671572 | 131 | } |
d18dd09b ASL |
132 | } |
133 | ||
0f19a90f PT |
134 | /** |
135 | * Constructor to specify the resource, parser and indexer. The streaming | |
136 | * interval will be 0. | |
137 | * | |
138 | * @param resource | |
139 | * The trace resource | |
140 | * @param path | |
141 | * The path to the trace file | |
142 | * @param cacheSize | |
143 | * The cache size | |
144 | * @param waitForCompletion | |
145 | * Do we block the caller until the trace is indexed, or not. | |
146 | * @param parser | |
147 | * The trace parser. If left 'null', it will use a | |
148 | * {@link TmfEventParserStub}. | |
149 | * @throws TmfTraceException | |
150 | * If an error occurred opening the trace | |
151 | */ | |
152 | public TmfTraceStub(final IResource resource, | |
153 | final String path, | |
154 | final int cacheSize, | |
155 | final boolean waitForCompletion, | |
156 | final ITmfEventParser parser) throws TmfTraceException { | |
5733be39 | 157 | super(resource, ITmfEvent.class, path, cacheSize, 0); |
0f19a90f | 158 | setupTrace(path); |
5733be39 | 159 | fParser = ((parser != null) ? parser : new TmfEventParserStub(this)); |
0f19a90f PT |
160 | if (waitForCompletion) { |
161 | indexTrace(true); | |
162 | } | |
163 | } | |
164 | ||
20658947 | 165 | /** |
ff0960ac AM |
166 | * Copy constructor |
167 | * | |
168 | * @param trace | |
169 | * The trace to copy | |
170 | * @throws TmfTraceException | |
171 | * If an error occurred opening the trace | |
20658947 | 172 | */ |
ff0960ac AM |
173 | public TmfTraceStub(final TmfTraceStub trace) throws TmfTraceException { |
174 | super(trace); | |
175 | setupTrace(getPath()); // fPath will be set by the super-constructor | |
5733be39 | 176 | fParser = new TmfEventParserStub(this); |
20658947 | 177 | } |
085d898f | 178 | |
ff0960ac AM |
179 | |
180 | private void setupTrace(String path) throws TmfTraceException { | |
b4f71e4a | 181 | try { |
a94410d9 | 182 | fTrace = new RandomAccessFile(path, "r"); //$NON-NLS-1$ |
b4f71e4a FC |
183 | } catch (FileNotFoundException e) { |
184 | throw new TmfTraceException(e.getMessage()); | |
185 | } | |
73005152 | 186 | } |
085d898f | 187 | |
ff0960ac AM |
188 | // ------------------------------------------------------------------------ |
189 | // Initializers | |
190 | // ------------------------------------------------------------------------ | |
085d898f | 191 | |
20658947 | 192 | @Override |
6256d8ad | 193 | public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> type) throws TmfTraceException { |
b4f71e4a | 194 | try { |
a94410d9 | 195 | fTrace = new RandomAccessFile(path, "r"); //$NON-NLS-1$ |
b4f71e4a FC |
196 | } catch (FileNotFoundException e) { |
197 | throw new TmfTraceException(e.getMessage()); | |
198 | } | |
20658947 FC |
199 | super.initTrace(resource, path, type); |
200 | } | |
f17b2f70 | 201 | |
1703b536 | 202 | @Override |
6256d8ad | 203 | public void initialize(final IResource resource, final String path, final Class<? extends ITmfEvent> type) throws TmfTraceException { |
1703b536 FC |
204 | super.initialize(resource, path, type); |
205 | } | |
206 | ||
e31e01e8 | 207 | // ------------------------------------------------------------------------ |
d18dd09b | 208 | // Accessors |
e31e01e8 | 209 | // ------------------------------------------------------------------------ |
d18dd09b | 210 | |
ff0960ac AM |
211 | /** |
212 | * @return The file stream to the trace | |
213 | */ | |
d18dd09b ASL |
214 | public RandomAccessFile getStream() { |
215 | return fTrace; | |
216 | } | |
217 | ||
ff0960ac AM |
218 | /** |
219 | * Set the initial range offset. | |
220 | * | |
221 | * @param initOffset | |
222 | * The new initial range offset | |
223 | */ | |
66262ad8 BH |
224 | public void setInitialRangeOffset(ITmfTimestamp initOffset) { |
225 | fInitialRangeOffset = initOffset; | |
226 | } | |
227 | ||
228 | @Override | |
229 | public ITmfTimestamp getInitialRangeOffset() { | |
230 | if (fInitialRangeOffset != null) { | |
231 | return fInitialRangeOffset; | |
232 | } | |
233 | return super.getInitialRangeOffset(); | |
234 | } | |
235 | ||
e31e01e8 | 236 | // ------------------------------------------------------------------------ |
d18dd09b | 237 | // Operators |
e31e01e8 | 238 | // ------------------------------------------------------------------------ |
d18dd09b | 239 | |
085d898f | 240 | @Override |
1e1bef82 | 241 | public TmfContext seekEvent(final ITmfLocation location) { |
d18dd09b | 242 | try { |
09e86496 FC |
243 | fLock.lock(); |
244 | try { | |
245 | if (fTrace != null) { | |
246 | // Position the trace at the requested location and | |
247 | // returns the corresponding context | |
248 | long loc = 0; | |
249 | long rank = 0; | |
250 | if (location != null) { | |
5976d44a | 251 | loc = (Long) location.getLocationInfo(); |
09e86496 FC |
252 | rank = ITmfContext.UNKNOWN_RANK; |
253 | } | |
20658947 | 254 | if (loc != fTrace.getFilePointer()) { |
09e86496 | 255 | fTrace.seek(loc); |
20658947 | 256 | } |
09e86496 FC |
257 | final TmfContext context = new TmfContext(getCurrentLocation(), rank); |
258 | return context; | |
73005152 | 259 | } |
09e86496 FC |
260 | } catch (final IOException e) { |
261 | e.printStackTrace(); | |
262 | } catch (final NullPointerException e) { | |
263 | e.printStackTrace(); | |
73005152 | 264 | } |
3427112b FC |
265 | finally{ |
266 | fLock.unlock(); | |
267 | } | |
09e86496 | 268 | } catch (final NullPointerException e) { |
085d898f FC |
269 | e.printStackTrace(); |
270 | } | |
085d898f | 271 | return null; |
d18dd09b ASL |
272 | } |
273 | ||
c76c54bb | 274 | |
085d898f | 275 | @Override |
7e6347b0 | 276 | public TmfContext seekEvent(final double ratio) { |
085d898f | 277 | fLock.lock(); |
c76c54bb | 278 | try { |
73005152 | 279 | if (fTrace != null) { |
15e89960 | 280 | final ITmfLocation location = new TmfLongLocation(Long.valueOf(Math.round(ratio * fTrace.length()))); |
7e6347b0 | 281 | final TmfContext context = seekEvent(location); |
73005152 BH |
282 | context.setRank(ITmfContext.UNKNOWN_RANK); |
283 | return context; | |
284 | } | |
085d898f | 285 | } catch (final IOException e) { |
c76c54bb | 286 | e.printStackTrace(); |
73005152 BH |
287 | } finally { |
288 | fLock.unlock(); | |
c76c54bb | 289 | } |
085d898f | 290 | |
c76c54bb FC |
291 | return null; |
292 | } | |
293 | ||
294 | @Override | |
1e1bef82 | 295 | public double getLocationRatio(ITmfLocation location) { |
73005152 | 296 | fLock.lock(); |
c76c54bb | 297 | try { |
0283f7ff | 298 | if (fTrace != null) { |
5976d44a | 299 | if (location.getLocationInfo() instanceof Long) { |
0126a8ca | 300 | return ((Long) location.getLocationInfo()).doubleValue() / fTrace.length(); |
0283f7ff FC |
301 | } |
302 | } | |
085d898f | 303 | } catch (final IOException e) { |
c76c54bb | 304 | e.printStackTrace(); |
73005152 BH |
305 | } finally { |
306 | fLock.unlock(); | |
c76c54bb FC |
307 | } |
308 | return 0; | |
309 | } | |
310 | ||
4e3aa37d | 311 | @Override |
1e1bef82 | 312 | public ITmfLocation getCurrentLocation() { |
73005152 | 313 | fLock.lock(); |
d18dd09b | 314 | try { |
0283f7ff | 315 | if (fTrace != null) { |
cb8c854e | 316 | return new TmfLongLocation(fTrace.getFilePointer()); |
0283f7ff | 317 | } |
085d898f FC |
318 | } catch (final IOException e) { |
319 | e.printStackTrace(); | |
320 | } finally { | |
321 | fLock.unlock(); | |
322 | } | |
323 | return null; | |
324 | } | |
325 | ||
326 | @Override | |
6256d8ad | 327 | public ITmfEvent parseEvent(final ITmfContext context) { |
085d898f FC |
328 | fLock.lock(); |
329 | try { | |
330 | // parseNextEvent will update the context | |
5733be39 AM |
331 | if (fTrace != null && context != null) { |
332 | final ITmfEvent event = fParser.parseEvent(context); | |
085d898f | 333 | return event; |
73005152 | 334 | } |
73005152 BH |
335 | } finally { |
336 | fLock.unlock(); | |
d18dd09b ASL |
337 | } |
338 | return null; | |
339 | } | |
340 | ||
0f19a90f PT |
341 | @Override |
342 | public ITmfTimestamp createTimestamp(long ts) { | |
343 | return new TmfTimestamp(getTimestampTransform().transform(ts) / 1000000L, ITmfTimestamp.MILLISECOND_SCALE); | |
344 | } | |
345 | ||
b75d6b65 | 346 | @Override |
9b749023 | 347 | public synchronized void setNbEvents(final long nbEvents) { |
b75d6b65 FC |
348 | super.setNbEvents(nbEvents); |
349 | } | |
350 | ||
085d898f FC |
351 | @Override |
352 | public void setTimeRange(final TmfTimeRange range) { | |
353 | super.setTimeRange(range); | |
354 | } | |
d18dd09b | 355 | |
085d898f FC |
356 | @Override |
357 | public void setStartTime(final ITmfTimestamp startTime) { | |
358 | super.setStartTime(startTime); | |
ff4ed569 FC |
359 | } |
360 | ||
085d898f FC |
361 | @Override |
362 | public void setEndTime(final ITmfTimestamp endTime) { | |
363 | super.setEndTime(endTime); | |
ff4ed569 FC |
364 | } |
365 | ||
1703b536 FC |
366 | @Override |
367 | public void setStreamingInterval(final long interval) { | |
368 | super.setStreamingInterval(interval); | |
369 | } | |
370 | ||
085d898f | 371 | @Override |
9b749023 | 372 | public synchronized void dispose() { |
085d898f FC |
373 | fLock.lock(); |
374 | try { | |
375 | if (fTrace != null) { | |
376 | fTrace.close(); | |
377 | fTrace = null; | |
378 | } | |
379 | } catch (final IOException e) { | |
380 | // Ignore | |
381 | } finally { | |
382 | fLock.unlock(); | |
383 | } | |
384 | super.dispose(); | |
ff4ed569 FC |
385 | } |
386 | ||
2352aed9 | 387 | @Override |
a94410d9 MK |
388 | public IStatus validate(IProject project, String path) { |
389 | if (fileExists(path)) { | |
390 | return Status.OK_STATUS; | |
391 | } | |
94d4821e | 392 | return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "File does not exist: " + path); |
2352aed9 FC |
393 | } |
394 | ||
032ecd45 MAL |
395 | private static int fCheckpointSize = -1; |
396 | ||
397 | @Override | |
398 | public synchronized int getCheckpointSize() { | |
399 | if (fCheckpointSize == -1) { | |
400 | TmfCheckpoint c = new TmfCheckpoint(new TmfTimestamp(0L), new TmfLongLocation(0L), 0); | |
401 | ByteBuffer b = ByteBuffer.allocate(ITmfCheckpoint.MAX_SERIALIZE_SIZE); | |
402 | b.clear(); | |
403 | c.serialize(b); | |
404 | fCheckpointSize = b.position(); | |
405 | } | |
406 | ||
407 | return fCheckpointSize; | |
408 | } | |
409 | ||
410 | @Override | |
411 | public ITmfLocation restoreLocation(ByteBuffer bufferIn) { | |
412 | return new TmfLongLocation(bufferIn); | |
413 | } | |
b5ddd705 GB |
414 | |
415 | /** | |
416 | * Simulate trace opening, to be called by tests who need an actively opened | |
417 | * trace | |
418 | */ | |
419 | public void openTrace() { | |
420 | TmfSignalManager.dispatchSignal(new TmfTraceOpenedSignal(this, this, null)); | |
421 | selectTrace(); | |
422 | } | |
423 | ||
424 | /** | |
425 | * Simulate selecting the trace | |
426 | */ | |
427 | public void selectTrace() { | |
428 | TmfSignalManager.dispatchSignal(new TmfTraceSelectedSignal(this, this)); | |
429 | } | |
2b5c3b7e BH |
430 | |
431 | /** | |
432 | * @return a copy of the pending request list | |
433 | * @throws Exception if java reflection failed | |
434 | */ | |
435 | public List<TmfCoalescedEventRequest> getAllPendingRequests() throws Exception { | |
436 | Method m = TmfEventProvider.class.getDeclaredMethod("getPendingRequests"); | |
437 | m.setAccessible(true); | |
438 | LinkedList<?> list= (LinkedList<?>) m.invoke(this); | |
439 | LinkedList<TmfCoalescedEventRequest> retList = new LinkedList<>(); | |
440 | for (Object element : list) { | |
441 | retList.add((TmfCoalescedEventRequest) element); | |
442 | } | |
443 | return retList; | |
444 | } | |
445 | ||
446 | /** | |
447 | * Clears the pending request list | |
448 | * @throws Exception if java reflection failed | |
449 | */ | |
450 | public void clearAllPendingRequests() throws Exception { | |
451 | Method m = TmfEventProvider.class.getDeclaredMethod("clearPendingRequests"); | |
452 | m.setAccessible(true); | |
453 | m.invoke(this); | |
454 | } | |
455 | ||
456 | /** | |
457 | * Sets the timer flag | |
458 | * @param enabled | |
459 | * flag to set | |
460 | * @throws Exception if java reflection failed | |
461 | */ | |
462 | public void setTimerEnabledFlag(boolean enabled) throws Exception { | |
463 | Class<?>[] paramTypes = new Class[1]; | |
464 | paramTypes[0] = Boolean.class; | |
465 | Method m = TmfEventProvider.class.getDeclaredMethod("setTimerEnabled", paramTypes); | |
466 | ||
467 | Object[] params = new Object[1]; | |
468 | params[0] = Boolean.valueOf(enabled); | |
469 | m.setAccessible(true); | |
470 | m.invoke(this, params); | |
471 | } | |
472 | ||
9b749023 | 473 | } |