tmf: Add missing @since 2.1 in new methods
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / trace / TmfTraceUtils.java
CommitLineData
b8585c7c
AM
1/*******************************************************************************
2 * Copyright (c) 2014 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 * Alexandre Montplaisir - Initial API and implementation
11 *******************************************************************************/
12
13package org.eclipse.tracecompass.tmf.core.trace;
14
aa353506
AM
15import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
16
d26d67f5
BH
17import java.io.BufferedInputStream;
18import java.io.File;
19import java.io.FileInputStream;
20import java.io.IOException;
daf3c7eb
MK
21import java.util.ArrayList;
22import java.util.List;
dba71686 23import java.util.function.Predicate;
b8585c7c 24
df2597e0 25import org.eclipse.jdt.annotation.NonNull;
1d83ed07 26import org.eclipse.jdt.annotation.NonNullByDefault;
b8585c7c 27import org.eclipse.jdt.annotation.Nullable;
c15e897d 28import org.eclipse.tracecompass.common.core.StreamUtils;
b8585c7c 29import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
daf3c7eb 30import org.eclipse.tracecompass.tmf.core.component.ITmfEventProvider;
b1aad44e 31import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
35f39420 32import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
dba71686 33import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest;
b8585c7c 34
daf3c7eb
MK
35import com.google.common.collect.Iterables;
36
b8585c7c
AM
37/**
38 * Utility methods for ITmfTrace's.
39 *
40 * @author Alexandre Montplaisir
41 */
1d83ed07 42@NonNullByDefault
b8585c7c
AM
43public final class TmfTraceUtils {
44
d26d67f5
BH
45 private static final int MAX_NB_BINARY_BYTES = 2048;
46
b1aad44e
GB
47 private TmfTraceUtils() {
48 }
b8585c7c
AM
49
50 /**
daf3c7eb
MK
51 * Return the first result of the first analysis module belonging to this trace or its children,
52 * with the specified ID and class.
b8585c7c
AM
53 *
54 * @param trace
55 * The trace for which you want the modules
56 * @param moduleClass
57 * Returned modules must extend this class
58 * @param id
59 * The ID of the analysis module
60 * @return The analysis module with specified class and ID, or null if no
61 * such module exists.
62 */
63 public static @Nullable <T extends IAnalysisModule> T getAnalysisModuleOfClass(ITmfTrace trace,
64 Class<T> moduleClass, String id) {
65 Iterable<T> modules = getAnalysisModulesOfClass(trace, moduleClass);
66 for (T module : modules) {
67 if (id.equals(module.getId())) {
68 return module;
69 }
70 }
71 return null;
72 }
73
74 /**
daf3c7eb
MK
75 * Return the analysis modules that are of a given class. The modules will be
76 * cast to the requested class. If the trace has children, the childrens modules
77 * are also returned.
b8585c7c
AM
78 *
79 * @param trace
daf3c7eb
MK
80 * The trace for which you want the modules, the children trace modules
81 * are added as well.
b8585c7c
AM
82 * @param moduleClass
83 * Returned modules must extend this class
84 * @return List of modules of class moduleClass
85 */
df2597e0 86 public static <T> Iterable<@NonNull T> getAnalysisModulesOfClass(ITmfTrace trace, Class<T> moduleClass) {
b8585c7c 87 Iterable<IAnalysisModule> analysisModules = trace.getAnalysisModules();
daf3c7eb 88 List<@NonNull T> modules = new ArrayList<>();
b1aad44e 89 for (IAnalysisModule module : analysisModules) {
b8585c7c 90 if (moduleClass.isAssignableFrom(module.getClass())) {
aa353506 91 modules.add(checkNotNull(moduleClass.cast(module)));
b8585c7c
AM
92 }
93 }
daf3c7eb
MK
94 for (ITmfEventProvider child : trace.getChildren()) {
95 if (child instanceof ITmfTrace) {
96 ITmfTrace childTrace = (ITmfTrace) child;
97 Iterables.addAll(modules, getAnalysisModulesOfClass(childTrace, moduleClass));
98 }
99 }
b8585c7c
AM
100 return modules;
101 }
35f39420
AM
102
103 /**
b1aad44e
GB
104 * Return the first result of the first aspect that resolves as non null for
105 * the event received in parameter. If the returned value is not null, it
106 * can be safely cast to the aspect's class proper return type.
35f39420
AM
107 *
108 * @param trace
109 * The trace for which you want the event aspects
110 * @param aspectClass
b1aad44e
GB
111 * The class of the aspect(s) to resolve
112 * @param event
113 * The event for which to get the aspect
114 * @return The first result of the
115 * {@link ITmfEventAspect#resolve(ITmfEvent)} that returns non null
116 * for the event or {@code null} otherwise
35f39420 117 */
c15e897d 118 public static <T extends ITmfEventAspect<?>> @Nullable Object resolveEventAspectOfClassForEvent(
1d83ed07 119 ITmfTrace trace, Class<T> aspectClass, ITmfEvent event) {
c15e897d
AM
120 return StreamUtils.getStream(trace.getEventAspects())
121 .filter(aspect -> aspectClass.isAssignableFrom(aspect.getClass()))
122 .map(aspect -> aspect.resolve(event))
123 .filter(obj -> obj != null)
124 .findFirst().orElse(null);
35f39420 125 }
d26d67f5 126
b3867ecc 127 /**
c15e897d
AM
128 * Return the first result of the first aspect that resolves as a non-null
129 * Integer for the event received in parameter. If no matching aspects are
130 * found then null is returned.
b3867ecc
MAL
131 *
132 * @param trace
133 * The trace for which you want the event aspects
134 * @param aspectClass
135 * The class of the aspect(s) to resolve
136 * @param event
137 * The event for which to get the aspect
138 * @return Integer of the first result of the
139 * {@link ITmfEventAspect#resolve(ITmfEvent)} that returns non null
140 * for the event or {@code null} otherwise
141 * @since 2.0
142 */
c15e897d 143 public static <T extends ITmfEventAspect<Integer>> @Nullable Integer resolveIntEventAspectOfClassForEvent(
b3867ecc 144 ITmfTrace trace, Class<T> aspectClass, ITmfEvent event) {
c15e897d
AM
145 return StreamUtils.getStream(trace.getEventAspects())
146 .filter(aspect -> aspectClass.isAssignableFrom(aspect.getClass()))
147 /* Enforced by the T parameter bounding */
148 .map(aspect -> (Integer) aspect.resolve(event))
149 .filter(obj -> obj != null)
150 .findFirst().orElse(null);
b3867ecc
MAL
151 }
152
d26d67f5
BH
153 /**
154 * Checks for text file.
155 *
156 * Note that it checks for binary value 0 in the first MAX_NB_BINARY_BYTES
157 * bytes to determine if the file is text.
158 *
159 * @param file
160 * the file to check. Caller has to make sure that file exists.
161 * @return true if it is binary else false
162 * @throws IOException
163 * if IOException occurs
066b02aa 164 * @since 1.2
d26d67f5
BH
165 */
166 public static boolean isText(File file) throws IOException {
167 try (BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file))) {
168 int count = 0;
169 int val = bufferedInputStream.read();
170 while ((count < MAX_NB_BINARY_BYTES) && (val >= 0)) {
171 if (val == 0) {
172 return false;
173 }
174 count++;
175 val = bufferedInputStream.read();
176 }
177 }
178 return true;
179 }
dba71686
AM
180
181 // ------------------------------------------------------------------------
182 // Event matching methods
183 // ------------------------------------------------------------------------
184
185 /**
186 * Retrieve from a trace the next event, from a starting rank, matching the
187 * given predicate.
188 *
189 * @param trace
190 * The trace
191 * @param startRank
192 * The rank of the event at which to start searching. Use
193 * <code>0</code> to search from the start of the trace.
194 * @param predicate
195 * The predicate to test events against
196 * @return The first event matching the predicate, or null if the end of the
197 * trace was reached and no event was found
dc281431 198 * @since 2.1
dba71686
AM
199 */
200 public static @Nullable ITmfEvent getNextEventMatching(ITmfTrace trace, long startRank, Predicate<ITmfEvent> predicate) {
201 /* rank + 1 because we do not want to include the start event itself in the search */
202 EventMatchingRequest req = new EventMatchingRequest(startRank + 1, predicate, false);
203 trace.sendRequest(req);
204 try {
205 req.waitForCompletion();
206 } catch (InterruptedException e) {
207 return null;
208 }
209
210 return req.getFoundEvent();
211 }
212
213 /**
214 * Retrieve from a trace the previous event, from a given rank, matching the
215 * given predicate.
216 *
217 * @param trace
218 * The trace
219 * @param startRank
220 * The rank of the event at which to start searching backwards.
221 * @param predicate
222 * The predicate to test events against
223 * @return The first event found matching the predicate, or null if the
224 * beginning of the trace was reached and no event was found
dc281431 225 * @since 2.1
dba71686
AM
226 */
227 public static @Nullable ITmfEvent getPreviousEventMatching(ITmfTrace trace, long startRank, Predicate<ITmfEvent> predicate) {
228 /*
229 * Slightly less straightforward since we unfortunately cannot iterate
230 * backwards on events. Do a series of forward-queries.
231 */
232 final int targetStep = 100;
233
234 /*
235 * If we are close to the beginning of the trace, make sure we only look
236 * for the events before the startRank.
237 */
238 int step = (startRank < targetStep ? (int) startRank : targetStep);
239
240 long currentRank = startRank;
241 try {
242 while (currentRank > 0) {
243 currentRank = Math.max(currentRank - step, 0);
244
245 EventMatchingRequest req = new EventMatchingRequest(currentRank, step, predicate, true);
246 trace.sendRequest(req);
247 req.waitForCompletion();
248
249 ITmfEvent event = req.getFoundEvent();
250 if (event != null) {
251 /* We found an actual event, return it! */
252 return event;
253 }
254 /* Keep searching, next loop */
255
256 }
257 } catch (InterruptedException e) {
258 return null;
259 }
260
261 /*
262 * We searched up to the beginning of the trace and didn't find
263 * anything.
264 */
265 return null;
266
267 }
268
269 /**
270 * Event request looking for an event matching a Predicate.
271 */
272 private static class EventMatchingRequest extends TmfEventRequest {
273
274 private final Predicate<ITmfEvent> fPredicate;
275 private final boolean fReturnLast;
276
277 private @Nullable ITmfEvent fFoundEvent = null;
278
279 /**
280 * Basic constructor, will query the trace until the end.
281 *
282 * @param startRank
283 * The rank at which to start, use 0 for the beginning
284 * @param predicate
285 * The predicate to test against each event
286 * @param returnLast
287 * Should we return the last or first event found. If false,
288 * the request ends as soon as a matching event is found. If
289 * false, we will go through all events to find a possible
290 * last-match.
291 */
292 public EventMatchingRequest(long startRank, Predicate<ITmfEvent> predicate, boolean returnLast) {
293 super(ITmfEvent.class, startRank, ALL_DATA, ExecutionType.FOREGROUND);
294 fPredicate = predicate;
295 fReturnLast = returnLast;
296 }
297
298 /**
299 * Basic constructor, will query the trace the limit is reached.
300 *
301 * @param startRank
302 * The rank at which to start, use 0 for the beginning
303 * @param limit
304 * The limit on the number of events
305 * @param predicate
306 * The predicate to test against each event
307 * @param returnLast
308 * Should we return the last or first event found. If false,
309 * the request ends as soon as a matching event is found. If
310 * false, we will go through all events to find a possible
311 * last-match.
312 */
313 public EventMatchingRequest(long startRank, int limit, Predicate<ITmfEvent> predicate, boolean returnLast) {
314 super(ITmfEvent.class, startRank, limit, ExecutionType.FOREGROUND);
315 fPredicate = predicate;
316 fReturnLast = returnLast;
317 }
318
319 public @Nullable ITmfEvent getFoundEvent() {
320 return fFoundEvent;
321 }
322
323 @Override
324 public void handleData(ITmfEvent event) {
325 super.handleData(event);
326
327 if (fPredicate.test(event)) {
328 fFoundEvent = event;
329 if (!fReturnLast) {
330 this.done();
331 }
332 }
333 }
334 }
b8585c7c 335}
This page took 0.113115 seconds and 5 git commands to generate.