If a trace resource is a file (and not a directory), then the '''Open With''' menu item is available in the context-sensitive menu and can be used to open the trace source file with any applicable internal or external editor. In that case the trace will not be processed by the tracing application.
-=== Creating a Experiment ===
+=== Creating an Experiment ===
An experiment consists in an arbitrary number of aggregated traces for purpose of correlation. In the degenerate case, an experiment can consist of a single trace. The experiment provides a unified, time-ordered stream of the individual trace events.
Alternatively, traces can be added to an experiment using [[#Drag_and_Drop | Drag and Drop]].
+=== Creating an Experiment from Selection ===
+
+An experiment can be quickly created and opened automatically by selecting one or more traces and/or trace folders in the '''Project Explorer''' view, and then selecting the '''Open as Experiment...''' context menu. A sub-menu with the available experiment types is opened. Select the desired experiment type from the sub-menu. All selected traces and traces recursively found in selected trace folders will be added to the experiment.
+
+If a single trace or trace folder is selected, its name will be used for the experiment, otherwise a default name will be used, possibly appended with a number to avoid name clashes.
+
+If an experiment with the same name and traces already exists, it will be reopened (or selected if it is already opened). Otherwise, a new experiment will be created and opened.
+
=== Removing Traces from an Experiment ===
To remove one or more traces for an experiment select the trace(s) to remove under the Experiment folder and click the right mouse button. Select '''Remove''' from the context sensitive menu.
A trace has to be taken for each machine, guest and host, in the virtualized environment. The host trace is the most important to have, as missing guests will only give an incomplete view of the system, but missing hosts usually won't allow to identify the hypervisor, nor determine when a guest is preempted from the host CPUs. The virtual machine analysis only makes sense if the host trace is available.
-Once all the traces are imported in Trace Compass, they can be [[#Creating a Experiment | added to an experiment]]. The type of the experiment should by set to '''Virtual Machine Experiment''' by clicking on the right mouse button over the experiment name, then selecting '''Select Experiment Type...'''.
+Once all the traces are imported in Trace Compass, they can be [[#Creating an Experiment | added to an experiment]]. The type of the experiment should by set to '''Virtual Machine Experiment''' by clicking on the right mouse button over the experiment name, then selecting '''Select Experiment Type...'''.
[[Image:images/vmAnalysis/VM_experiment.png | Virtual Machine Experiment]]
/******************************************************************************
- * Copyright (c) 2016 Ericsson
+ * Copyright (c) 2016, 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
SWTBotUtils.openTrace(TRACE_PROJECT_NAME, fTestFile.getAbsolutePath(), CUSTOM_TEXT_LOG.getTraceType());
SWTBotTreeItem traceItem = SWTBotUtils.getTraceProjectItem(fBot, SWTBotUtils.selectTracesFolder(fBot, TRACE_PROJECT_NAME), TRACE_NAME);
- final List<String> EXPECTED_MENU_LABELS = ImmutableList.of("Open", "Open With", "", "Copy...", "Rename...", "Delete", "", "Delete Supplementary Files...", "", "Export Trace Package...", "", "Select Trace Type...", "", "Apply Time Offset...",
+ final List<String> EXPECTED_MENU_LABELS = ImmutableList.of("Open", "Open As Experiment...", "Open With", "", "Copy...", "Rename...", "Delete", "", "Delete Supplementary Files...", "", "Export Trace Package...", "", "Select Trace Type...", "", "Apply Time Offset...",
"Clear Time Offset", "", "Refresh");
List<String> menuItems = traceItem.contextMenu().menuItems();
assertEquals(EXPECTED_MENU_LABELS, menuItems);
final List<String> EXPECTED_MENU_LABELS = ImmutableList.of(
"Open Trace...",
+ "Open As Experiment...",
"",
"Import...",
"",
## Trace menu
# Open, Copy, Rename, Delete, Delete Supplementary Files, Select Trace Type
+command.open_as_experiment = Open As Experiment...
+command.open_as_experiment.mnemonic = x
+command.open_as_experiment.description = Open selected traces as an experiment
+
## Trace folder menu
# Import, Refresh
</with>
</visibleWhen>
</command>
+ <menu
+ label="%command.open_as_experiment"
+ mnemonic="%command.open_as_experiment.mnemonic"
+ tooltip="%command.open_as_experiment.description">
+ <dynamic
+ class="org.eclipse.tracecompass.internal.tmf.ui.project.handlers.OpenAsExperimentContributionItem"
+ id="org.eclipse.tracecompass.tmf.ui.command.open_as_experiment.dynamic">
+ </dynamic>
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <and>
+ <test
+ forcePluginActivation="true"
+ property="org.eclipse.linuxtools.tmf.ui.isSameProject">
+ </test>
+ <or>
+ <iterate
+ ifEmpty="false"
+ operator="and">
+ <or>
+ <instanceof
+ value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder">
+ </instanceof>
+ <and>
+ <instanceof
+ value="org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement">
+ </instanceof>
+ <not>
+ <test
+ forcePluginActivation="true"
+ property="org.eclipse.linuxtools.tmf.ui.isExperimentTrace">
+ </test>
+ </not>
+ </and>
+ </or>
+ </iterate>
+ </or>
+ </and>
+ </with>
+ </visibleWhen>
+ </menu>
</menuContribution>
<menuContribution
locationURI="popup:org.eclipse.ui.popup.any?after=additions">
id="org.eclipse.linuxtools.tmf.ui.openFile"
name="%command.OpenFile.name">
</command>
+ <command
+ categoryId="org.eclipse.ui.category.file"
+ defaultHandler="org.eclipse.tracecompass.internal.tmf.ui.project.handlers.OpenAsExperimentHandler"
+ description="%command.open_as_experiment.description"
+ id="org.eclipse.tracecompass.tmf.ui.command.open_as_experiment"
+ name="%command.open_as_experiment">
+ <commandParameter
+ id="org.eclipse.linuxtools.tmf.ui.commandparameter.select_trace_type.type"
+ name="%command.select_trace_type.type"
+ optional="false">
+ </commandParameter>
+ </command>
<command
categoryId="org.eclipse.linuxtools.tmf.ui.commands.category"
description="%command.offset_traces.description"
properties="isExperimentTrace,hasSupplementaryFiles,traceType"
type="org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectModelElement">
</propertyTester>
+ <propertyTester
+ class="org.eclipse.tracecompass.internal.tmf.ui.project.handlers.TracePropertyTester"
+ id="org.eclipse.linuxtools.tmf.ui.tracePropertyTester"
+ namespace="org.eclipse.linuxtools.tmf.ui"
+ properties="isSameProject"
+ type="org.eclipse.jface.viewers.ISelection">
+ </propertyTester>
<propertyTester
class="org.eclipse.tracecompass.internal.tmf.ui.project.handlers.EditorInputPropertyTester"
id="org.eclipse.tracecompass.tmf.ui.editorInputPropertyTester"
/*******************************************************************************
- * Copyright (c) 2011, 2014 Ericsson
+ * Copyright (c) 2011, 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
public static String TmfActionProvider_OpenWith;
+ public static String OpenAsExperimentHandler_DefaultExperimentName;
+ public static String OpenAsExperimentHandler_ValidationErrorTitle;
+ public static String OpenAsExperimentHandler_ValidationErrorMessage;
+
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
--- /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
+ *
+ * Contributors:
+ * Patrick Tasse - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.tmf.ui.project.handlers;
+
+import java.util.Collections;
+
+import org.eclipse.jface.action.IContributionItem;
+
+/**
+ * Contribution item for the Open As Experiment... sub-menu.
+ */
+public class OpenAsExperimentContributionItem extends SelectElementTypeContributionItem {
+
+ private static final String OPEN_AS_EXPERIMENT_COMMAND_ID = "org.eclipse.tracecompass.tmf.ui.command.open_as_experiment"; //$NON-NLS-1$
+
+ @Override
+ protected IContributionItem[] getContributionItems() {
+ return getContributionItems(Collections.EMPTY_SET, true);
+ }
+
+ @Override
+ protected String getContributionItemCommandId() {
+ return OPEN_AS_EXPERIMENT_COMMAND_ID;
+ }
+}
--- /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
+ *
+ * Contributors:
+ * Patrick Tasse - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.tmf.ui.project.handlers;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tracecompass.internal.tmf.ui.project.operations.SelectTracesOperation;
+import org.eclipse.tracecompass.internal.tmf.ui.project.operations.TmfWorkspaceModifyOperation;
+import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType;
+import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentFolder;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfOpenTraceHelper;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceTypeUIUtils;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfTracesFolder;
+import org.eclipse.tracecompass.tmf.ui.project.model.TraceUtils;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * Handler for the Open As Experiment command
+ */
+public class OpenAsExperimentHandler extends AbstractHandler {
+
+ // ------------------------------------------------------------------------
+ // Constants
+ // ------------------------------------------------------------------------
+
+ private static final String TYPE_PARAMETER = "org.eclipse.linuxtools.tmf.ui.commandparameter.select_trace_type.type"; //$NON-NLS-1$
+
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+
+ final String experimentType = event.getParameter(TYPE_PARAMETER);
+ final TraceTypeHelper traceTypeHelper = TmfTraceType.getTraceType(experimentType);
+ if (traceTypeHelper == null) {
+ return null;
+ }
+
+ IStructuredSelection selection = HandlerUtil.getCurrentStructuredSelection(event);
+
+ String experimentName = Messages.OpenAsExperimentHandler_DefaultExperimentName;
+ Set<@NonNull TmfTraceElement> traces = new HashSet<>();
+ TmfProjectElement project = null;
+ for (Object element : selection.toList()) {
+ if (element instanceof TmfTracesFolder) {
+ TmfTracesFolder tracesFolder = (TmfTracesFolder) element;
+ traces.addAll(tracesFolder.getTraces());
+ project = tracesFolder.getProject();
+ } else if (element instanceof TmfTraceFolder) {
+ TmfTraceFolder traceFolder = (TmfTraceFolder) element;
+ traces.addAll(traceFolder.getTraces());
+ project = traceFolder.getProject();
+ if (selection.size() == 1) {
+ experimentName = traceFolder.getName();
+ }
+ } else if (element instanceof TmfTraceElement) {
+ TmfTraceElement traceElement = (TmfTraceElement) element;
+ traces.add(traceElement);
+ project = traceElement.getProject();
+ if (selection.size() == 1) {
+ experimentName = traceElement.getName();
+ }
+ }
+ }
+ if (project == null) {
+ return null;
+ }
+ final TmfExperimentFolder experimentsFolder = project.getExperimentsFolder();
+ if (experimentsFolder == null) {
+ return null;
+ }
+
+ final IFolder experimentFolder = getExperimentFolder(experimentName, experimentsFolder, traces);
+ boolean exists = experimentFolder.exists();
+
+ if (!exists) {
+ try {
+ experimentFolder.create(false, true, null);
+ } catch (CoreException e) {
+ TraceUtils.displayErrorMsg(e.toString(), e.toString());
+ return null;
+ }
+ }
+
+ TmfExperimentElement experimentElement = experimentsFolder.getExperiment(experimentFolder);
+ if (experimentElement == null) {
+ return null;
+ }
+
+ if (!exists) {
+ TmfWorkspaceModifyOperation operation = new TmfWorkspaceModifyOperation() {
+ @Override
+ public void execute(IProgressMonitor monitor) throws CoreException {
+ SelectTracesOperation selectTracesOperation = new SelectTracesOperation(experimentElement, traces.toArray(new @NonNull TmfTraceElement[traces.size()]), Collections.EMPTY_MAP);
+ selectTracesOperation.run(monitor);
+ }
+ };
+
+ try {
+ PlatformUI.getWorkbench().getProgressService().run(true, true, operation);
+ } catch (InterruptedException e) {
+ return null;
+ } catch (InvocationTargetException e) {
+ TraceUtils.displayErrorMsg(e.toString(), e.getTargetException().toString());
+ return null;
+ }
+ }
+
+ IStatus status = traceTypeHelper.validate(experimentFolder.getLocation().toOSString());
+ if (!status.isOK()) {
+ TraceUtils.displayErrorMsg(Messages.OpenAsExperimentHandler_ValidationErrorTitle, NLS.bind(Messages.OpenAsExperimentHandler_ValidationErrorMessage, status.getMessage()));
+ return null;
+ }
+
+ if (exists && !experimentElement.getTraceType().equals(traceTypeHelper.getTraceTypeId())) {
+ experimentElement.closeEditors();
+ TmfWorkspaceModifyOperation operation = new TmfWorkspaceModifyOperation() {
+ @Override
+ public void execute(IProgressMonitor monitor) throws CoreException {
+ experimentElement.deleteSupplementaryResources();
+ TmfTraceTypeUIUtils.setTraceType(experimentFolder, traceTypeHelper, false);
+ }
+ };
+
+ try {
+ PlatformUI.getWorkbench().getProgressService().run(true, true, operation);
+ } catch (InterruptedException e) {
+ return null;
+ } catch (InvocationTargetException e) {
+ TraceUtils.displayErrorMsg(e.toString(), e.getTargetException().toString());
+ return null;
+ }
+ }
+
+ TmfOpenTraceHelper.openTraceFromElement(experimentElement);
+
+ return null;
+ }
+
+ private static IFolder getExperimentFolder(String experimentName, final TmfExperimentFolder experimentsFolder, Set<@NonNull TmfTraceElement> traces) {
+ IFolder folder = experimentsFolder.getResource().getFolder(experimentName);
+ int i = 2;
+ while (folder.exists()) {
+ TmfExperimentElement experimentElement = experimentsFolder.getExperiment(folder);
+ if (experimentElement != null) {
+ Set<TmfTraceElement> existingTraces = new HashSet<>();
+ for (TmfTraceElement trace : experimentElement.getTraces()) {
+ existingTraces.add(trace.getElementUnderTraceFolder());
+ }
+ if (existingTraces.equals(traces)) {
+ return folder;
+ }
+ }
+ folder = experimentsFolder.getResource().getFolder(experimentName + '(' + Integer.toString(i++) + ')');
+ }
+ return folder;
+ }
+}
return list.toArray(new IContributionItem[list.size()]);
}
- private static void addContributionItem(List<IContributionItem> list,
+ /**
+ * Returns the command id to use for contribution items
+ *
+ * @return the command id
+ */
+ protected String getContributionItemCommandId() {
+ return SELECT_TRACE_TYPE_COMMAND_ID;
+ }
+
+ private void addContributionItem(List<IContributionItem> list,
String traceTypeId, String label, boolean selected, MenuManager subMenu) {
Map<String, String> params = new HashMap<>();
params.put(TYPE_PARAMETER, traceTypeId);
CommandContributionItemParameter param = new CommandContributionItemParameter(
PlatformUI.getWorkbench().getActiveWorkbenchWindow(), // serviceLocator
"my.parameterid", // id //$NON-NLS-1$
- SELECT_TRACE_TYPE_COMMAND_ID, // commandId
+ getContributionItemCommandId(), // commandId
CommandContributionItem.STYLE_PUSH // style
);
param.parameters = params;
/*******************************************************************************
- * Copyright (c) 2012, 2014 Ericsson
+ * Copyright (c) 2012, 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
import java.util.Iterator;
import org.eclipse.core.expressions.PropertyTester;
+import org.eclipse.core.resources.IProject;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement;
+import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectModelElement;
import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement;
import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder;
private static final String IS_EXPERIMENT_TRACE = "isExperimentTrace"; //$NON-NLS-1$
private static final String HAS_SUPPLEMENTARY_FILES = "hasSupplementaryFiles"; //$NON-NLS-1$
private static final String TRACE_TYPE = "traceType"; //$NON-NLS-1$
+ private static final String IS_SAME_PROJECT = "isSameProject"; //$NON-NLS-1$
// ------------------------------------------------------------------------
// Constructor
return false;
}
+ // Check if the selected elements are all in the same project
+ if (IS_SAME_PROJECT.equals(property)) {
+ if (receiver instanceof IStructuredSelection) {
+ IProject sameProject = null;
+ for (Object element : ((IStructuredSelection) receiver).toList()) {
+ if (element instanceof TmfProjectModelElement) {
+ IProject project = ((TmfProjectModelElement) element).getProject().getResource();
+ if (sameProject == null) {
+ sameProject = project;
+ } else if (!sameProject.equals(project)) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+
return false;
}
###############################################################################
-# Copyright (c) 2013, 2014 Ericsson
+# Copyright (c) 2013, 2017 Ericsson
#
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# TMF Action Provider
TmfActionProvider_OpenWith=Open With
+
+OpenAsExperimentHandler_DefaultExperimentName=Experiment
+OpenAsExperimentHandler_ValidationErrorTitle=Validation Error
+OpenAsExperimentHandler_ValidationErrorMessage=Experiment has failed validation: {0}
\ No newline at end of file
/*******************************************************************************
- * Copyright (c) 2011, 2014 Ericsson
+ * Copyright (c) 2011, 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
* Returns a list of trace elements under the folder element, recursively.
* @return list of trace model elements
*/
- public List<TmfTraceElement> getTraces() {
+ public List<@NonNull TmfTraceElement> getTraces() {
List<ITmfProjectModelElement> children = getChildren();
- List<TmfTraceElement> traces = new ArrayList<>();
+ List<@NonNull TmfTraceElement> traces = new ArrayList<>();
for (ITmfProjectModelElement child : children) {
if (child instanceof TmfTraceElement) {
traces.add((TmfTraceElement) child);