| /******************************************************************************* |
| * Copyright (c) 2016, 2018 EfficiOS Inc., Alexandre Montplaisir |
| * |
| * 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.tmf.ui.project.model; |
| |
| import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; |
| |
| import java.util.concurrent.ExecutorService; |
| import java.util.concurrent.Executors; |
| |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.jdt.annotation.NonNullByDefault; |
| import org.eclipse.jdt.annotation.Nullable; |
| import org.eclipse.jface.viewers.StyledString.Styler; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.graphics.TextStyle; |
| import org.eclipse.tracecompass.tmf.core.analysis.ondemand.IOnDemandAnalysis; |
| import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; |
| |
| /** |
| * Project model element for individual on-demand analyses that apply to the |
| * related trace. |
| * |
| * @author Alexandre Montplaisir |
| * @since 2.0 |
| */ |
| @NonNullByDefault |
| public abstract class TmfOnDemandAnalysisElement extends TmfProjectModelElement |
| implements ITmfStyledProjectModelElement { |
| |
| /** |
| * Checking if the analysis can run may take some time (running external |
| * scripts, etc.) so we do this outside of the UI thread. The executor will |
| * reserve one thread to check all on-demand analyses sequentially. |
| */ |
| private static final ExecutorService EXECUTOR = checkNotNull(Executors.newFixedThreadPool(1)); |
| |
| /** |
| * Worker thread sent to the executor |
| */ |
| private static class AnalysisChecker implements Runnable { |
| |
| private final TmfOnDemandAnalysisElement fElem; |
| |
| public AnalysisChecker(TmfOnDemandAnalysisElement elem) { |
| fElem = elem; |
| } |
| |
| @Override |
| public void run() { |
| ITmfTrace trace = fElem.getParent().getParent().getTrace(); |
| if (trace != null) { |
| fElem.fCanRun = fElem.getAnalysis().canExecute(trace); |
| fElem.refresh(); |
| } |
| } |
| } |
| |
| /** |
| * Styler to strike-out the analysis when it is not available |
| */ |
| private static final Styler STRIKED_OUT_STYLER = new Styler() { |
| @Override |
| public void applyStyles(@Nullable TextStyle textStyle) { |
| if (textStyle != null) { |
| textStyle.strikeout = true; |
| } |
| } |
| }; |
| |
| private final IOnDemandAnalysis fAnalysis; |
| |
| private volatile boolean fKnowIfCanRun = false; |
| private volatile boolean fCanRun = false; |
| |
| /** |
| * Constructor |
| * |
| * @param analysisName |
| * Name of the element |
| * @param resource |
| * Workspace resource |
| * @param parent |
| * Parent element, should be the "on-demand analyses" one |
| * @param analysis |
| * The actual analysis represented by this element |
| */ |
| protected TmfOnDemandAnalysisElement(String analysisName, IResource resource, |
| TmfOnDemandAnalysesElement parent, IOnDemandAnalysis analysis) { |
| super(analysisName, resource, parent); |
| fAnalysis = analysis; |
| } |
| |
| @Override |
| public TmfOnDemandAnalysesElement getParent() { |
| return checkNotNull((TmfOnDemandAnalysesElement) super.getParent()); |
| } |
| |
| @Override |
| public abstract Image getIcon(); |
| |
| @Override |
| protected synchronized void refreshChildren() { |
| /* No children, but determine if we can run or not. */ |
| if (!fKnowIfCanRun) { |
| fKnowIfCanRun = true; |
| EXECUTOR.execute(new AnalysisChecker(this)); |
| } |
| } |
| |
| @Override |
| public @Nullable Styler getStyler() { |
| if (!fCanRun) { |
| return STRIKED_OUT_STYLER; |
| } |
| return null; |
| } |
| |
| /** |
| * Get the analysis represented by this model element |
| * |
| * @return The real analysis |
| */ |
| public IOnDemandAnalysis getAnalysis() { |
| return fAnalysis; |
| } |
| |
| /** |
| * Return if the analysis can be run or not. Determines if we should enable |
| * the run actions. |
| * |
| * @return If this analysis can run |
| */ |
| public boolean canRun() { |
| return fCanRun; |
| } |
| } |