blob: c4520abc49cb8e9672d2d596b6aea70e7d1bb54c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2021 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.tracecompass.internal.tmf.core.annotations;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.internal.provisional.tmf.core.model.annotations.AnnotationCategoriesModel;
import org.eclipse.tracecompass.internal.provisional.tmf.core.model.annotations.AnnotationModel;
import org.eclipse.tracecompass.internal.provisional.tmf.core.model.annotations.IOutputAnnotationProvider;
import org.eclipse.tracecompass.internal.tmf.core.markers.MarkerConfigXmlParser;
import org.eclipse.tracecompass.internal.tmf.core.markers.MarkerSet;
import org.eclipse.tracecompass.tmf.core.dataprovider.DataProviderParameterUtils;
import org.eclipse.tracecompass.tmf.core.response.ITmfResponse.Status;
import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
/**
* Trace Annotation provider for providing custom (frame) annotations. It
* encapsulates the individual annotation providers per marker set.
*/
public class CustomOutputAnnotationProvider implements IOutputAnnotationProvider {
private static final String INVALID_MARKER_ID = "Invalid marker ID %s"; //$NON-NLS-1$
private static final String NO_MARKER_ID = "no markerID"; //$NON-NLS-1$
private final Map<String, CustomAnnotationProvider> fProviders = Collections.synchronizedMap(new HashMap<>());
private final ITmfTrace fTrace;
static {
MarkerConfigXmlParser.initMarkerSets();
}
/**
* Constructor
*/
public CustomOutputAnnotationProvider(ITmfTrace trace) {
fTrace = trace;
}
@Override
public TmfModelResponse<AnnotationCategoriesModel> fetchAnnotationCategories(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
Object markerID = fetchParameters.get(DataProviderParameterUtils.REQUESTED_MARKER_SET_KEY);
/* Ignore if trace is not the first element of its trace set. */
if (!isFirstTrace()) {
return new TmfModelResponse<>(null, Status.COMPLETED, ""); //$NON-NLS-1$
}
if (markerID == null) {
return new TmfModelResponse<>(null, Status.FAILED, NO_MARKER_ID);
}
MarkerSet ms = getMarkerSet(markerID);
if (ms == null) {
return new TmfModelResponse<>(null, Status.FAILED, formatError(markerID));
}
return getAnnotationProvider(null, ms).fetchAnnotationCategories(fetchParameters, monitor);
}
@Override
public TmfModelResponse<AnnotationModel> fetchAnnotations(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
Object markerID = fetchParameters.get(DataProviderParameterUtils.REQUESTED_MARKER_SET_KEY);
Object hostID = fetchParameters.get(DataProviderParameterUtils.REQUESTED_TRACE_KEY);
Optional<ITmfTrace> requestedTrace = getTrace(hostID);
/*
* Ignore if trace is not the requested trace, or if no requested trace,
* if the trace is not the first element of its trace set.
*/
if ((requestedTrace.isPresent() && !requestedTrace.get().equals(fTrace)) ||
(!requestedTrace.isPresent() && !isFirstTrace())) {
return new TmfModelResponse<>(null, Status.COMPLETED, ""); //$NON-NLS-1$
}
if (markerID == null) {
return new TmfModelResponse<>(null, Status.FAILED, NO_MARKER_ID);
}
MarkerSet ms = getMarkerSet(markerID);
if (ms == null) {
return new TmfModelResponse<>(null, Status.FAILED, formatError(markerID));
}
return getAnnotationProvider(requestedTrace.isPresent() ? requestedTrace.get() : null, ms).fetchAnnotations(fetchParameters, monitor);
}
private CustomAnnotationProvider getAnnotationProvider(@Nullable ITmfTrace trace, MarkerSet ms) {
return fProviders.computeIfAbsent(ms.getId(), msId -> new CustomAnnotationProvider(trace, ms));
}
private static @Nullable MarkerSet getMarkerSet(Object markerID) {
Optional<@Nullable MarkerSet> markerOptional = MarkerConfigXmlParser.getMarkerSets().stream()
.filter(markerSet -> Objects.equals(markerID, markerSet.getId()))
.findAny();
if (markerOptional.isPresent()) {
return markerOptional.get();
}
return null;
}
private static Optional<ITmfTrace> getTrace(Object hostID) {
return TmfTraceManager.getInstance().getOpenedTraces().stream().flatMap(trace -> TmfTraceManager.getTraceSetWithExperiment(trace).stream()).filter(t -> Objects.equals(t.getHostId(), hostID)).findAny();
}
/*
* Returns true if, for any opened trace, this provider's trace is the first
* element in the opened trace's trace set.
*/
private boolean isFirstTrace() {
return TmfTraceManager.getInstance().getOpenedTraces().stream()
.anyMatch(t -> TmfTraceManager.getTraceSet(t).stream().findFirst().get().equals(fTrace));
}
private static String formatError(Object markerID) {
return String.format(INVALID_MARKER_ID, markerID);
}
}