1 /*******************************************************************************
2 * Copyright (c) 2009, 2014 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 * Patrick Tasse - Updated for removal of context clone
12 *******************************************************************************/
14 package org
.eclipse
.tracecompass
.tmf
.tests
.stubs
.trace
;
16 import java
.io
.FileNotFoundException
;
17 import java
.io
.IOException
;
18 import java
.io
.RandomAccessFile
;
19 import java
.lang
.reflect
.Method
;
20 import java
.nio
.ByteBuffer
;
21 import java
.util
.LinkedList
;
22 import java
.util
.List
;
23 import java
.util
.concurrent
.locks
.ReentrantLock
;
25 import org
.eclipse
.core
.resources
.IProject
;
26 import org
.eclipse
.core
.resources
.IResource
;
27 import org
.eclipse
.core
.runtime
.IStatus
;
28 import org
.eclipse
.core
.runtime
.Status
;
29 import org
.eclipse
.jdt
.annotation
.NonNull
;
30 import org
.eclipse
.tracecompass
.internal
.tmf
.core
.Activator
;
31 import org
.eclipse
.tracecompass
.internal
.tmf
.core
.request
.TmfCoalescedEventRequest
;
32 import org
.eclipse
.tracecompass
.tmf
.core
.component
.TmfEventProvider
;
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
;
52 * <b><u>TmfTraceStub</u></b>
54 * Dummy test trace. Use in conjunction with TmfEventParserStub.
56 public class TmfTraceStub
extends TmfTrace
implements ITmfPersistentlyIndexable
{
58 // ------------------------------------------------------------------------
60 // ------------------------------------------------------------------------
63 private RandomAccessFile fTrace
;
65 // The associated event parser
66 private final @NonNull ITmfEventParser fParser
;
68 // The synchronization lock
69 private final ReentrantLock fLock
= new ReentrantLock();
71 private ITmfTimestamp fInitialRangeOffset
= null;
73 // ------------------------------------------------------------------------
75 // ------------------------------------------------------------------------
80 public TmfTraceStub() {
82 fParser
= new TmfEventParserStub(this);
86 * Constructor with which you can specify a custom streaming interval. The
87 * parser and indexer won't be specified.
90 * The path to the trace file
94 * The trace streaming interval
95 * @throws TmfTraceException
96 * If an error occurred opening the trace
98 public TmfTraceStub(final String path
,
100 final long interval
) throws TmfTraceException
{
101 super(null, ITmfEvent
.class, path
, cacheSize
, interval
);
103 fParser
= new TmfEventParserStub(this);
107 * Constructor to specify the parser and indexer. The streaming interval
111 * The path to the trace file
114 * @param waitForCompletion
115 * Do we block the caller until the trace is indexed, or not.
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
122 public TmfTraceStub(final String path
,
124 final boolean waitForCompletion
,
125 final ITmfEventParser parser
) throws TmfTraceException
{
126 super(null, ITmfEvent
.class, path
, cacheSize
, 0);
128 fParser
= ((parser
!= null) ? parser
: new TmfEventParserStub(this));
129 if (waitForCompletion
) {
135 * Constructor to specify the resource, parser and indexer. The streaming
136 * interval will be 0.
141 * The path to the trace file
144 * @param waitForCompletion
145 * Do we block the caller until the trace is indexed, or not.
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
152 public TmfTraceStub(final IResource resource
,
155 final boolean waitForCompletion
,
156 final ITmfEventParser parser
) throws TmfTraceException
{
157 super(resource
, ITmfEvent
.class, path
, cacheSize
, 0);
159 fParser
= ((parser
!= null) ? parser
: new TmfEventParserStub(this));
160 if (waitForCompletion
) {
170 * @throws TmfTraceException
171 * If an error occurred opening the trace
173 public TmfTraceStub(final TmfTraceStub trace
) throws TmfTraceException
{
175 setupTrace(getPath()); // fPath will be set by the super-constructor
176 fParser
= new TmfEventParserStub(this);
180 private void setupTrace(String path
) throws TmfTraceException
{
182 fTrace
= new RandomAccessFile(path
, "r"); //$NON-NLS-1$
183 } catch (FileNotFoundException e
) {
184 throw new TmfTraceException(e
.getMessage());
188 // ------------------------------------------------------------------------
190 // ------------------------------------------------------------------------
193 public void initTrace(final IResource resource
, final String path
, final Class
<?
extends ITmfEvent
> type
) throws TmfTraceException
{
195 fTrace
= new RandomAccessFile(path
, "r"); //$NON-NLS-1$
196 } catch (FileNotFoundException e
) {
197 throw new TmfTraceException(e
.getMessage());
199 super.initTrace(resource
, path
, type
);
203 public void initialize(final IResource resource
, final String path
, final Class
<?
extends ITmfEvent
> type
) throws TmfTraceException
{
204 super.initialize(resource
, path
, type
);
207 // ------------------------------------------------------------------------
209 // ------------------------------------------------------------------------
212 * @return The file stream to the trace
214 public RandomAccessFile
getStream() {
219 * Set the initial range offset.
222 * The new initial range offset
224 public void setInitialRangeOffset(ITmfTimestamp initOffset
) {
225 fInitialRangeOffset
= initOffset
;
229 public ITmfTimestamp
getInitialRangeOffset() {
230 if (fInitialRangeOffset
!= null) {
231 return fInitialRangeOffset
;
233 return super.getInitialRangeOffset();
236 // ------------------------------------------------------------------------
238 // ------------------------------------------------------------------------
241 public TmfContext
seekEvent(final ITmfLocation location
) {
245 if (fTrace
!= null) {
246 // Position the trace at the requested location and
247 // returns the corresponding context
250 if (location
!= null) {
251 loc
= (Long
) location
.getLocationInfo();
252 rank
= ITmfContext
.UNKNOWN_RANK
;
254 if (loc
!= fTrace
.getFilePointer()) {
257 final TmfContext context
= new TmfContext(getCurrentLocation(), rank
);
260 } catch (final IOException e
) {
262 } catch (final NullPointerException e
) {
268 } catch (final NullPointerException e
) {
276 public TmfContext
seekEvent(final double ratio
) {
279 if (fTrace
!= null) {
280 final ITmfLocation location
= new TmfLongLocation(Long
.valueOf(Math
.round(ratio
* fTrace
.length())));
281 final TmfContext context
= seekEvent(location
);
282 context
.setRank(ITmfContext
.UNKNOWN_RANK
);
285 } catch (final IOException e
) {
295 public double getLocationRatio(ITmfLocation location
) {
298 if (fTrace
!= null) {
299 if (location
.getLocationInfo() instanceof Long
) {
300 return ((Long
) location
.getLocationInfo()).doubleValue() / fTrace
.length();
303 } catch (final IOException e
) {
312 public ITmfLocation
getCurrentLocation() {
315 if (fTrace
!= null) {
316 return new TmfLongLocation(fTrace
.getFilePointer());
318 } catch (final IOException e
) {
327 public ITmfEvent
parseEvent(final ITmfContext context
) {
330 // parseNextEvent will update the context
331 if (fTrace
!= null && context
!= null) {
332 final ITmfEvent event
= fParser
.parseEvent(context
);
342 public ITmfTimestamp
createTimestamp(long ts
) {
343 return new TmfTimestamp(getTimestampTransform().transform(ts
) / 1000000L, ITmfTimestamp
.MILLISECOND_SCALE
);
347 public synchronized void setNbEvents(final long nbEvents
) {
348 super.setNbEvents(nbEvents
);
352 public void setTimeRange(final TmfTimeRange range
) {
353 super.setTimeRange(range
);
357 public void setStartTime(final ITmfTimestamp startTime
) {
358 super.setStartTime(startTime
);
362 public void setEndTime(final ITmfTimestamp endTime
) {
363 super.setEndTime(endTime
);
367 public void setStreamingInterval(final long interval
) {
368 super.setStreamingInterval(interval
);
372 public synchronized void dispose() {
375 if (fTrace
!= null) {
379 } catch (final IOException e
) {
388 public IStatus
validate(IProject project
, String path
) {
389 if (fileExists(path
)) {
390 return Status
.OK_STATUS
;
392 return new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, "File does not exist: " + path
);
395 private static int fCheckpointSize
= -1;
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
);
404 fCheckpointSize
= b
.position();
407 return fCheckpointSize
;
411 public ITmfLocation
restoreLocation(ByteBuffer bufferIn
) {
412 return new TmfLongLocation(bufferIn
);
416 * Simulate trace opening, to be called by tests who need an actively opened
419 public void openTrace() {
420 TmfSignalManager
.dispatchSignal(new TmfTraceOpenedSignal(this, this, null));
425 * Simulate selecting the trace
427 public void selectTrace() {
428 TmfSignalManager
.dispatchSignal(new TmfTraceSelectedSignal(this, this));
432 * @return a copy of the pending request list
433 * @throws Exception if java reflection failed
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
);
447 * Clears the pending request list
448 * @throws Exception if java reflection failed
450 public void clearAllPendingRequests() throws Exception
{
451 Method m
= TmfEventProvider
.class.getDeclaredMethod("clearPendingRequests");
452 m
.setAccessible(true);
457 * Sets the timer flag
460 * @throws Exception if java reflection failed
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
);
467 Object
[] params
= new Object
[1];
468 params
[0] = Boolean
.valueOf(enabled
);
469 m
.setAccessible(true);
470 m
.invoke(this, params
);