--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 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.tmf.ui.project.model;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.eclipse.jdt.annotation.NonNull;
+
+import com.google.common.base.Joiner;
+
+/**
+ * Class for project elements of type compound analysis modules.
+ *
+ * This element aggregates analyses with the same type that come from various
+ * traces contained in an experiment. This allows to show trace analyses and
+ * their views under the experiment's view element.
+ *
+ * @author Bernd Hufmann
+ * @since 3.0
+ */
+public class TmfAggregateAnalysisElement extends TmfAnalysisElement {
+
+ private final @NonNull Set<TmfAnalysisElement> fContainedAnalyses = new HashSet<>();
+ private final @NonNull TmfCommonProjectElement fExperimentParent;
+
+ /**
+ * Constructor
+ *
+ * @param experiment
+ * The element to use for experiment activation.
+ *
+ * @param module
+ * The analysis module helper.
+ * This helper is used in super and acts as a delegate
+ * helper representing all contained analyses elements.
+ */
+ protected TmfAggregateAnalysisElement(@NonNull TmfCommonProjectElement experiment, @NonNull TmfAnalysisElement module) {
+ super (module.getName(), module.getResource(), module.getParent(), module.getAnalysisHelper());
+ fExperimentParent = experiment;
+ fContainedAnalyses.add(module);
+ }
+ @Override
+ protected void refreshChildren() {
+ // refresh all children analysis as well
+ for (TmfAnalysisElement analysis : fContainedAnalyses) {
+ analysis.refreshChildren();
+ }
+ super.refreshChildren();
+ }
+
+ @Override
+ public boolean canExecute() {
+ for (TmfAnalysisElement analysis : fContainedAnalyses) {
+ if (analysis.canExecute()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Add an analysis element that is combined in the compound element.
+ *
+ * @param element
+ * analysis element to add
+ */
+ public void addAnalyses(@NonNull TmfAnalysisElement element) {
+ fContainedAnalyses.add(element);
+ }
+
+ /**
+ * Remove an analysis element that is combined in the compound element.
+ *
+ * @param element
+ * analysis element to remove
+ */
+ public void removeAnalyses(@NonNull TmfAnalysisElement element) {
+ fContainedAnalyses.remove(element);
+ }
+
+ /**
+ * Checks if aggregated list is empty or not
+ *
+ * @return <code>true<code> if empty else <code>false</code>
+ */
+ public boolean isEmpty() {
+ return fContainedAnalyses.isEmpty();
+ }
+
+ // ------------------------------------------------------------------------
+ // Operations
+ // ------------------------------------------------------------------------
+ /**
+ * Gets the help message for this analysis
+ *
+ * @return The help message
+ */
+ @Override
+ public String getHelpMessage() {
+ Set<String> messages = new HashSet<>();
+ for (TmfAnalysisElement analysis : fContainedAnalyses) {
+ messages.add(analysis.getHelpMessage());
+ }
+ if (messages.size() > 0) {
+ return Joiner.on(',').join(messages.stream().collect(Collectors.toList()));
+ }
+ return super.getHelpMessage();
+ }
+
+ /**
+ * Make sure the trace this analysis is associated to is the currently
+ * selected one
+ */
+ @Override
+ public void activateParentTrace() {
+ TmfOpenTraceHelper.openTraceFromElement(fExperimentParent);
+ }
+}
};
private final @NonNull IAnalysisModuleHelper fAnalysisHelper;
- private boolean fCanExecute = true;
+ private volatile boolean fCanExecute = true;
private static final String ANALYSIS_PROPERTIES_CATEGORY = Messages.TmfAnalysisElement_AnalysisProperties;
private static final String HELPER_PROPERTIES_CATEGORY = Messages.TmfAnalysisElement_HelperProperties;
@Override
public Styler getStyler() {
- if (!fCanExecute) {
+ if (!canExecute()) {
return ANALYSIS_CANT_EXECUTE_STYLER;
}
return null;
}
}
+ /**
+ * Checks whether the analysis can be executed or not.
+ *
+ * @return <code>true</code> if analysis can be executed else
+ * <code>false</code>
+ * @since 3.0
+ */
+ public boolean canExecute() {
+ return fCanExecute;
+ }
+
+ /**
+ * Gets the analysis helper for this analysis.
+ *
+ * @return the analysis module helper
+ * @since 3.0
+ */
+ @NonNull protected IAnalysisModuleHelper getAnalysisHelper() {
+ return fAnalysisHelper;
+ }
+
// ------------------------------------------------------------------------
// IPropertySource2
// ------------------------------------------------------------------------
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
IPath tracePath = getResource().getFullPath();
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ if (this.getParent() instanceof TmfExperimentElement) {
+ return;
+ }
+
if (fViewsElement == null) {
/* Add the "Views" node */
IFolder viewsNodeRes = root.getFolder(tracePath.append(TmfViewsElement.PATH_ELEMENT));
*/
public ITmfTrace getTrace() {
for (ITmfTrace trace : TmfTraceManager.getInstance().getOpenedTraces()) {
- if (trace.getResource().equals(getResource())) {
- return trace;
+ for (ITmfTrace t : TmfTraceManager.getTraceSetWithExperiment(trace)) {
+ if (getResource().equals(t.getResource())) {
+ return t;
+ }
}
}
return null;
.collect(Collectors.toList());
}
+ /**
+ * @since 3.0
+ * @return list of children analysis elements
+ */
+ public List<TmfAnalysisElement> getChildrenAvailableAnalysis() {
+ return Collections.EMPTY_LIST;
+ }
+
// ------------------------------------------------------------------------
// Supplementary files operations
// ------------------------------------------------------------------------
package org.eclipse.tracecompass.tmf.ui.project.model;
-import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
}
/* super.refreshChildren() above should have set this */
- TmfViewsElement viewsElement = checkNotNull(getChildElementViews());
+ TmfViewsElement viewsElement = getChildElementViews();
+ if (viewsElement == null) {
+ return;
+ }
Map<String, TmfAnalysisElement> analysisMap = new HashMap<>();
for (TmfAnalysisElement analysis : getAvailableAnalysis()) {
analysisMap.put(analysis.getAnalysisId(), analysis);
+ analysis.refreshChildren();
}
for (IAnalysisModuleHelper module : TmfAnalysisManager.getAnalysisModules().values()) {
if (!analysisMap.containsKey(module.getId()) && module.appliesToExperiment() && (experiment.getAnalysisModule(module.getId()) != null)) {
}
}
+ @Override
+ public List<TmfAnalysisElement> getChildrenAvailableAnalysis() {
+ List<TmfTraceElement> traces = getChildren().stream()
+ .filter(elem -> (elem instanceof TmfTraceElement))
+ .map(elem -> ((TmfTraceElement) elem).getElementUnderTraceFolder())
+ .collect(Collectors.toList());
+
+ List<TmfAnalysisElement> analyses = new ArrayList<>();
+ for (TmfTraceElement traceElem : traces) {
+ if (traceElem.getChildElementViews() != null) {
+ analyses.addAll(traceElem.getAvailableAnalysis());
+ }
+ }
+ return analyses;
+ }
+
private List<IResource> getTraceResources() {
IFolder folder = getResource();
final List<IResource> list = new ArrayList<>();
}
});
+ /* Remove all trace analyses from experiment view */
+ List<TmfAnalysisElement> analysisElements = trace.getElementUnderTraceFolder().getAvailableAnalysis();
+ TmfViewsElement view = getChildElementViews();
+
+ if (view != null) {
+ view.removeChildrenAnalysis(analysisElements);
+ }
+
/* Finally, remove the trace from experiment */
removeChild(trace);
deleteTraceResource(trace.getResource());
package org.eclipse.tracecompass.tmf.ui.project.model;
import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
+import java.util.Optional;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
* Project model element for the "Views" node.
*
* For now it contains the list of the standard analyses, with their outputs
- * (views) under each. The plan is to eventually only show the views under this
- * node, since the user cannot really interact with the analyses themselves.
+ * (views) under each. For experiments all analyses from children traces are
+ * aggregated and shown under the "Views" node.
+ *
+ * The plan is to eventually only show the views under this node, since the
+ * user cannot really interact with the analyses themselves.
*
* @author Alexandre Montplaisir
* @since 2.0
IPath nodePath = getResource().getFullPath();
- /* Add all new analysis modules or refresh outputs of existing ones */
- for (IAnalysisModuleHelper module : TmfAnalysisManager.getAnalysisModules(traceClass).values()) {
+ TmfCommonProjectElement parent = getParent();
+
+ if (parent instanceof TmfTraceElement) {
+ /* Add all new analysis modules or refresh outputs of existing ones */
+ for (IAnalysisModuleHelper module : TmfAnalysisManager.getAnalysisModules(traceClass).values()) {
- /* If the analysis is not a child of the trace, create it */
- TmfAnalysisElement analysis = childrenMap.remove(module.getId());
- if (analysis == null) {
- IFolder analysisRes = ResourcesPlugin.getWorkspace().getRoot().getFolder(nodePath.append(module.getId()));
- analysis = new TmfAnalysisElement(module.getName(), analysisRes, this, module);
- addChild(analysis);
+ /* If the analysis is not a child of the trace, create it */
+ TmfAnalysisElement analysis = childrenMap.remove(module.getId());
+ if (analysis == null) {
+ IFolder analysisRes = ResourcesPlugin.getWorkspace().getRoot().getFolder(nodePath.append(module.getId()));
+ analysis = new TmfAnalysisElement(module.getName(), analysisRes, this, module);
+ addChild(analysis);
+ }
+ analysis.refreshChildren();
+ }
+
+ /* Remove analysis that are not children of this trace anymore */
+ for (TmfAnalysisElement analysis : childrenMap.values()) {
+ removeChild(analysis);
+ }
+ } else if (parent != null) {
+ /* In experiment case collect trace analyses in the aggregate analyses element */
+ Map<String, TmfAggregateAnalysisElement> analysisMap = new LinkedHashMap<>();
+
+ /* Add all new analysis modules or refresh outputs of existing ones */
+ for (IAnalysisModuleHelper module : TmfAnalysisManager.getAnalysisModules(traceClass).values()) {
+
+ /* If the analysis is not a child of the trace, create it */
+ TmfAnalysisElement analysis = childrenMap.remove(module.getId());
+ TmfAggregateAnalysisElement aggregateAnalysisElement = null;
+ if (analysis == null) {
+ IFolder analysisRes = ResourcesPlugin.getWorkspace().getRoot().getFolder(nodePath.append(module.getId()));
+ analysis = new TmfAnalysisElement(module.getName(), analysisRes, this, module);
+ aggregateAnalysisElement = new TmfAggregateAnalysisElement(parent, analysis);
+ addChild(aggregateAnalysisElement);
+ } else {
+ if (analysis instanceof TmfAggregateAnalysisElement) {
+ aggregateAnalysisElement = (TmfAggregateAnalysisElement) analysis;
+ } else {
+ aggregateAnalysisElement = new TmfAggregateAnalysisElement(parent, analysis);
+ }
+ removeChild(analysis);
+ addChild(aggregateAnalysisElement);
+ }
+ analysisMap.put(analysis.getAnalysisId(), aggregateAnalysisElement);
+ }
+
+ /* Now add available all trace analyses */
+ for (TmfAnalysisElement analysis : getParent().getChildrenAvailableAnalysis()) {
+ /* If the analysis is not a child of the trace, create it */
+ TmfAnalysisElement a = childrenMap.remove(analysis.getAnalysisId());
+
+ TmfAggregateAnalysisElement childAnalysis = null;
+
+ if (a instanceof TmfAggregateAnalysisElement) {
+ childAnalysis = (TmfAggregateAnalysisElement) a;
+ } else {
+ childAnalysis = analysisMap.get(analysis.getAnalysisId());
+ }
+
+ if (childAnalysis == null) {
+ childAnalysis = new TmfAggregateAnalysisElement(parent, analysis);
+ addChild(childAnalysis);
+ } else {
+ childAnalysis.addAnalyses(analysis);
+ }
+ analysisMap.put(analysis.getAnalysisId(), childAnalysis);
}
- analysis.refreshChildren();
- }
- /* Remove analysis that are not children of this trace anymore */
- for (TmfAnalysisElement analysis : childrenMap.values()) {
- removeChild(analysis);
+ /* Remove analysis that are not children of this trace anymore */
+ for (TmfAnalysisElement analysis : childrenMap.values()) {
+ removeChild(analysis);
+ }
}
}
public Image getIcon() {
return TmfProjectModelIcons.VIEWS_ICON;
}
+
+ /**
+ * Remove children analysis from aggregated traces
+ *
+ * @param analysisElements
+ * list of analysis elements to remove
+ *
+ * @since 3.0
+ */
+ public void removeChildrenAnalysis(List<TmfAnalysisElement> analysisElements) {
+ for (TmfAnalysisElement tmfAnalysisElement : analysisElements) {
+ if (tmfAnalysisElement != null) {
+ TmfAggregateAnalysisElement aggrElement = getAggregateAnalysisElement(tmfAnalysisElement);
+ if (aggrElement != null) {
+ aggrElement.removeAnalyses(tmfAnalysisElement);
+ if (aggrElement.isEmpty()) {
+ removeChild(aggrElement);
+ }
+ }
+ }
+ }
+ }
+
+ private TmfAggregateAnalysisElement getAggregateAnalysisElement(TmfAnalysisElement element) {
+ Optional<TmfAggregateAnalysisElement> aggrElem = getChildren().stream()
+ .filter(elem -> (elem instanceof TmfAggregateAnalysisElement))
+ .map(elem -> ((TmfAggregateAnalysisElement) elem))
+ .filter(elem -> elem.getAnalysisHelper().getId().equals(element.getAnalysisHelper().getId()))
+ .findFirst();
+ if (aggrElem.isPresent()) {
+ return aggrElem.get();
+ }
+ return null;
+ }
}