blob: 8c820df251a6e2eb6580a78c9ccdc49c81a3d195 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.tracecompass.internal.tmf.core.model.timegraph;
import java.util.List;
import java.util.logging.Level;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.FlowScopeLog;
import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.FlowScopeLogBuilder;
import org.eclipse.tracecompass.internal.tmf.core.model.tree.AbstractTreeDataProvider;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
import org.eclipse.tracecompass.tmf.core.model.CommonStatusMessage;
import org.eclipse.tracecompass.tmf.core.model.filters.SelectionTimeQueryFilter;
import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphDataProvider;
import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphEntryModel;
import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphRowModel;
import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphStateFilter;
import org.eclipse.tracecompass.tmf.core.response.ITmfResponse;
import org.eclipse.tracecompass.tmf.core.response.ITmfResponse.Status;
import org.eclipse.tracecompass.tmf.core.response.TmfModelResponse;
import org.eclipse.tracecompass.tmf.core.statesystem.TmfStateSystemAnalysisModule;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import com.google.common.collect.Multimap;
/**
* Class to abstract {@link ITimeGraphDataProvider} methods and fields. Handles
* the exceptions that can be thrown by the concrete classes, and logs the time
* taken to build the time graph models.
*
* @param <A>
* Generic type for the encapsulated
* {@link TmfStateSystemAnalysisModule}
* @param <M>
* Generic type for the returned {@link ITimeGraphEntryModel}.
* @author Loic Prieur-Drevon
* @since 4.0
*/
public abstract class AbstractTimeGraphDataProvider<A extends TmfStateSystemAnalysisModule, M extends ITimeGraphEntryModel>
extends AbstractTreeDataProvider<A, M> implements ITimeGraphDataProvider<M> {
/**
* Constructor
*
* @param trace
* the trace this provider represents
* @param analysisModule
* the analysis encapsulated by this provider
*/
public AbstractTimeGraphDataProvider(ITmfTrace trace, A analysisModule) {
super(trace, analysisModule);
}
@Override
public final TmfModelResponse<List<ITimeGraphRowModel>> fetchRowModel(SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor) {
A module = getAnalysisModule();
if (!module.waitForInitialization()) {
return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.ANALYSIS_INITIALIZATION_FAILED);
}
ITmfStateSystem ss = module.getStateSystem();
if (ss == null) {
return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.STATE_SYSTEM_FAILED);
}
long currentEnd = ss.getCurrentEndTime();
boolean complete = ss.waitUntilBuilt(0) || filter.getEnd() <= currentEnd;
try (FlowScopeLog scope = new FlowScopeLogBuilder(LOGGER, Level.FINE, "AbstractTimeGraphDataProvider#fetchRowModel") //$NON-NLS-1$
.setCategory(getClass().getSimpleName()).build()) {
List<ITimeGraphRowModel> models = getRowModel(ss, filter, monitor);
if (models == null) {
// getRowModel returns null if the query was cancelled.
return new TmfModelResponse<>(null, ITmfResponse.Status.CANCELLED, CommonStatusMessage.TASK_CANCELLED);
}
return new TmfModelResponse<>(models, complete ? Status.COMPLETED : Status.RUNNING,
complete ? CommonStatusMessage.COMPLETED : CommonStatusMessage.RUNNING);
} catch (StateSystemDisposedException | TimeRangeException | IndexOutOfBoundsException e) {
return new TmfModelResponse<>(null, Status.FAILED, String.valueOf(e.getMessage()));
}
}
@Override
public @NonNull Multimap<@NonNull String, @NonNull String> getFilterData(long entryId, long time, @Nullable IProgressMonitor monitor) {
return ITimeGraphStateFilter.mergeMultimaps(ITimeGraphDataProvider.super.getFilterData(entryId, time, monitor),
getEntryMetadata(entryId));
}
/**
* Abstract method to be implemented by the providers to return rows. Lets the
* abstract class handle waiting for {@link ITmfStateSystem} initialization and
* progress, as well as error handling
*
* @param ss
* the {@link TmfStateSystemAnalysisModule}'s {@link ITmfStateSystem}
* @param filter
* the query's filter
* @param monitor
* progress monitor
* @return the list of row models, null if the query was cancelled
* @throws StateSystemDisposedException
* if the state system was closed during the query or could not be
* queried.
*/
protected abstract @Nullable List<ITimeGraphRowModel> getRowModel(ITmfStateSystem ss,
SelectionTimeQueryFilter filter, @Nullable IProgressMonitor monitor)
throws StateSystemDisposedException;
}