diff --git a/analyses/org.eclipse.tracecompass.incubator.inandout.core/build.properties b/analyses/org.eclipse.tracecompass.incubator.inandout.core/build.properties
index c2f6da1ba..2eed3aa9d 100644
--- a/analyses/org.eclipse.tracecompass.incubator.inandout.core/build.properties
+++ b/analyses/org.eclipse.tracecompass.incubator.inandout.core/build.properties
@@ -16,6 +16,7 @@ bin.includes = META-INF/,\
plugin.properties,\
.,\
plugin.xml,\
- icons/
+ icons/,\
+ schema/
additional.bundles = org.eclipse.jdt.annotation
jars.extra.classpath = platform:/plugin/org.eclipse.jdt.annotation
diff --git a/analyses/org.eclipse.tracecompass.incubator.inandout.core/plugin.xml b/analyses/org.eclipse.tracecompass.incubator.inandout.core/plugin.xml
index d0eb89bab..d199acab4 100644
--- a/analyses/org.eclipse.tracecompass.incubator.inandout.core/plugin.xml
+++ b/analyses/org.eclipse.tracecompass.incubator.inandout.core/plugin.xml
@@ -20,4 +20,11 @@
+
+
+
+
diff --git a/analyses/org.eclipse.tracecompass.incubator.inandout.core/schema/in-and-out-analysis.json b/analyses/org.eclipse.tracecompass.incubator.inandout.core/schema/in-and-out-analysis.json
new file mode 100644
index 000000000..248c1b327
--- /dev/null
+++ b/analyses/org.eclipse.tracecompass.incubator.inandout.core/schema/in-and-out-analysis.json
@@ -0,0 +1,59 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://org.eclipse.tracecompass/in-and-out-analysis.json",
+ "title": "InAndOut Analysis",
+ "description": "Custom Execution Analysis schema",
+ "type": "object",
+ "properties": {
+ "name" : {
+ "type": "string",
+ "description": "The name of this InAndOut configuration"
+ },
+ "description" : {
+ "type": "string",
+ "description": "The descrition of this InAndOut configuration"
+ },
+ "specifiers": {
+ "description": "array specifiers",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "label": {
+ "type": "string",
+ "descritpion": "The label of the identifier"
+ },
+ "inRegex": {
+ "type": "string",
+ "descritpion": "The IN regular expression"
+ },
+ "outRegex": {
+ "type": "string",
+ "descritpion": "The OUT regular expression"
+ },
+ "contextInRegex": {
+ "type": "string",
+ "descritpion": "The context IN regular expression"
+ },
+ "contextOutRegex": {
+ "type": "string",
+ "descritpion": "The context OUT regular expression"
+ },
+ "classifier": {
+ "type": "string",
+ "descritpion": "The classifier"
+ },
+ "required": [
+ "label",
+ "inRegex",
+ "outRegex",
+ "contextInRegex",
+ "contextOutRegex",
+ "classifier"
+ ]
+ }
+ }
+ }
+ },
+ "required": ["name", "specifiers"]
+}
diff --git a/analyses/org.eclipse.tracecompass.incubator.inandout.core/src/org/eclipse/tracecompass/incubator/internal/inandout/core/analysis/InAndOutAnalysisModule.java b/analyses/org.eclipse.tracecompass.incubator.inandout.core/src/org/eclipse/tracecompass/incubator/internal/inandout/core/analysis/InAndOutAnalysisModule.java
index 849bede33..399bd5109 100644
--- a/analyses/org.eclipse.tracecompass.incubator.inandout.core/src/org/eclipse/tracecompass/incubator/internal/inandout/core/analysis/InAndOutAnalysisModule.java
+++ b/analyses/org.eclipse.tracecompass.incubator.inandout.core/src/org/eclipse/tracecompass/incubator/internal/inandout/core/analysis/InAndOutAnalysisModule.java
@@ -23,9 +23,18 @@
import java.util.List;
import java.util.Objects;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.analysis.profiling.core.instrumented.InstrumentedCallStackAnalysis;
import org.eclipse.tracecompass.incubator.internal.inandout.core.Activator;
+import org.eclipse.tracecompass.tmf.core.analysis.IAnalysisModule;
+import org.eclipse.tracecompass.tmf.core.config.ITmfConfiguration;
+import org.eclipse.tracecompass.tmf.core.config.TmfConfiguration;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfConfigurationException;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
@@ -50,6 +59,42 @@ public class InAndOutAnalysisModule extends InstrumentedCallStackAnalysis {
*/
public static final String JSON = ".config.json"; //$NON-NLS-1$
+ private @Nullable ITmfConfiguration fConfiguration;
+ private @Nullable List<@NonNull SegmentSpecifier> fSpecifiers;
+
+ @Override
+ public @NonNull String getName() {
+ ITmfConfiguration config = fConfiguration;
+ if (config != null) {
+ return config.getName();
+ }
+ return super.getName();
+ }
+
+ @Override
+ public @NonNull String getHelpText() {
+ ITmfConfiguration config = fConfiguration;
+ if (config != null) {
+ return config.getDescription();
+ }
+ return super.getHelpText();
+ }
+
+ @Override
+ public void setConfiguration(ITmfConfiguration configuration) throws TmfConfigurationException {
+ if (configuration == null) {
+ throw new TmfConfigurationException("Can't set a null configuration"); //$NON-NLS-1$
+ }
+ SegmentSpecifierConfiguration config = SegmentSpecifierConfiguration.fromJsonMap(configuration.getParameters());
+ fConfiguration = configuration;
+ fSpecifiers = config.getSpecifiers();
+ }
+
+ @Override
+ public @Nullable ITmfConfiguration getConfiguration() {
+ return fConfiguration;
+ }
+
/**
* Reference (default) specifier configured.
*/
@@ -57,16 +102,26 @@ public class InAndOutAnalysisModule extends InstrumentedCallStackAnalysis {
@Override
public @NonNull String getId() {
- return ID;
+ ITmfConfiguration config = fConfiguration;
+ if (config == null || fSpecifiers == null) {
+ return ID;
+ }
+ return ID + config.getId();
}
@Override
public boolean canExecute(@NonNull ITmfTrace trace) {
- File config = getConfig(trace);
- return config.exists() && super.canExecute(trace);
+ ITmfConfiguration configuration = fConfiguration;
+ if (configuration == null) {
+ // Eclipse Trace Compass
+ File config = getConfig(trace);
+ return config.exists() && super.canExecute(trace);
+ }
+ return true;
}
private static File getConfig(@NonNull ITmfTrace trace) {
+ // Eclipse Trace Compass
String folder = TmfTraceManager.getSupplementaryFileDir(trace);
File config = new File(folder + File.separator + ID + JSON);
if (!config.exists()) {
@@ -80,9 +135,13 @@ private static File getConfig(@NonNull ITmfTrace trace) {
@Override
protected @NonNull ITmfStateProvider createStateProvider() {
ITmfTrace trace = Objects.requireNonNull(getTrace(), "Trace should not be null at this point"); //$NON-NLS-1$
- File configFile = getConfig(trace);
- List<@NonNull SegmentSpecifier> list = read(configFile);
- return new InAndOutAnalysisStateProvider(trace, list);
+ List<@NonNull SegmentSpecifier> specifiers = fSpecifiers;
+ if (specifiers == null) {
+ // Eclipse Trace Compass
+ File configFile = getConfig(trace);
+ specifiers = read(configFile);
+ }
+ return new InAndOutAnalysisStateProvider(trace, specifiers);
}
/**
@@ -116,10 +175,118 @@ private static File getConfig(@NonNull ITmfTrace trace) {
* the specifiers
*/
public static void write(File file, List<@NonNull SegmentSpecifier> specifiers) {
+ // Eclipse Trace Compass
try (Writer writer = new FileWriter(file)) {
writer.append(new Gson().toJson(specifiers));
} catch (IOException e) {
Activator.getInstance().logError(e.getMessage(), e);
}
}
+
+ /**
+ * Create the InAndOutAnalysisModule for a given configuration and trace
+ *
+ * @param config
+ * the input {@link ITmfConfiguration}
+ * @param trace
+ * the trace to apply it to
+ * @param writeConfig
+ * write the config (do only once)
+ * @return InAndOutAnalysisModule
+ * @throws TmfConfigurationException
+ * if an error occurs
+ */
+ public static InAndOutAnalysisModule create(@NonNull ITmfConfiguration config, @NonNull ITmfTrace trace, boolean writeConfig) throws TmfConfigurationException {
+ /*
+ * Apply configuration to each trace (no need to check trace type here)
+ */
+ InAndOutAnalysisModule module = new InAndOutAnalysisModule();
+ module.setConfiguration(config);
+ if (writeConfig) {
+ IPath traceConfigPath = getTraceRootFolder(trace, config.getSourceTypeId());
+ TmfConfiguration.writeConfiguration(config, traceConfigPath);
+ }
+ try {
+ if (module.setTrace(trace)) {
+ IAnalysisModule oldModule = trace.addAnalysisModule(module);
+ if (oldModule != null) {
+ oldModule.dispose();
+ oldModule.clearPersistentData();
+ }
+ } else {
+ module.dispose();
+ throw new TmfConfigurationException("InAndOut analysis module can't be created"); //$NON-NLS-1$
+ }
+ } catch (TmfAnalysisException | TmfTraceException e) {
+ module.dispose();
+ throw new TmfConfigurationException("Exception when setting trace", e); //$NON-NLS-1$
+ }
+ return module;
+ }
+
+ /**
+ * Removes configuration from trace:
+ * - delete configuration file
+ * - remove analysis module from trace object
+ *
+ * @param config
+ * the configuration to remove
+ * @param trace
+ * the
+ * @throws TmfConfigurationException if an error occurs
+ */
+ public static void remove(ITmfConfiguration config, @NonNull ITmfTrace trace) throws TmfConfigurationException {
+ IPath traceConfig = getTraceRootFolder(trace, config.getSourceTypeId());
+ traceConfig = traceConfig.append(File.separator).append(config.getId()).addFileExtension(TmfConfiguration.JSON_EXTENSION);
+ File configFile = traceConfig.toFile();
+ if ((!configFile.exists()) || !configFile.delete()) {
+ throw new TmfConfigurationException("InAndOut configuration file can't be deleted from trace: configId=" + config.getId()); //$NON-NLS-1$
+ }
+
+ // Remove and clear persistent data
+ try {
+ IAnalysisModule module = trace.removeAnalysisModule(ID + config.getId());
+ if (module != null) {
+ module.dispose();
+ module.clearPersistentData();
+ }
+ } catch (TmfTraceException e) {
+ throw new TmfConfigurationException("Error removing analysis module from trace: analysis ID=" + ID + config.getId(), e); //$NON-NLS-1$
+ }
+ }
+
+ @SuppressWarnings("null")
+ private static @NonNull IPath getTraceRootFolder(@NonNull ITmfTrace trace, String subFolder) {
+ String supplFolder = TmfTraceManager.getSupplementaryFileDir(trace);
+ IPath supplPath = new Path(supplFolder);
+ supplPath = supplPath.addTrailingSeparator().append(subFolder);
+ return supplPath;
+ }
+
+ /**
+ * Reads the configurations for a given trace
+ *
+ * @param trace
+ * the trace to read configurations from
+ * @return list of configurations if any
+ * @throws TmfConfigurationException
+ * if an error occurs
+ */
+ public static @NonNull List readConfigurations(@NonNull ITmfTrace trace) throws TmfConfigurationException {
+ IPath rootPath = getTraceRootFolder(trace, SegmentSpecifierConfiguration.IN_AND_OUT_CONFIG_SOURCE_TYPE_ID);
+ File folder = rootPath.toFile();
+ List list = new ArrayList<>();
+ if (folder.exists()) {
+ File[] listOfFiles = folder.listFiles();
+ for (File file : listOfFiles) {
+ IPath path = new Path(file.getName());
+ if (path.getFileExtension().equals(TmfConfiguration.JSON_EXTENSION)) {
+ ITmfConfiguration config = TmfConfiguration.fromJsonFile(file);
+ list.add(config);
+ }
+ }
+ }
+ return list;
+ }
+
}
diff --git a/analyses/org.eclipse.tracecompass.incubator.inandout.core/src/org/eclipse/tracecompass/incubator/internal/inandout/core/analysis/InAndOutDataProviderFactory.java b/analyses/org.eclipse.tracecompass.incubator.inandout.core/src/org/eclipse/tracecompass/incubator/internal/inandout/core/analysis/InAndOutDataProviderFactory.java
new file mode 100644
index 000000000..05a313b01
--- /dev/null
+++ b/analyses/org.eclipse.tracecompass.incubator.inandout.core/src/org/eclipse/tracecompass/incubator/internal/inandout/core/analysis/InAndOutDataProviderFactory.java
@@ -0,0 +1,269 @@
+/*******************************************************************************
+ * Copyright (c) 2024 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.incubator.internal.inandout.core.analysis;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.tracecompass.incubator.internal.inandout.core.Activator;
+import org.eclipse.tracecompass.tmf.core.config.ITmfConfiguration;
+import org.eclipse.tracecompass.tmf.core.config.ITmfConfigurationSourceType;
+import org.eclipse.tracecompass.tmf.core.config.ITmfDataProviderConfigurator;
+import org.eclipse.tracecompass.tmf.core.config.TmfConfiguration;
+import org.eclipse.tracecompass.tmf.core.config.TmfConfigurationSourceType;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderDescriptor.ProviderType;
+import org.eclipse.tracecompass.tmf.core.dataprovider.IDataProviderFactory;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfConfigurationException;
+import org.eclipse.tracecompass.tmf.core.model.DataProviderDescriptor;
+import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataModel;
+import org.eclipse.tracecompass.tmf.core.model.tree.ITmfTreeDataProvider;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
+import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
+import org.eclipse.tracecompass.tmf.core.signal.TmfTraceClosedSignal;
+import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
+import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
+import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
+import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
+import org.osgi.framework.Bundle;
+
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.Table;
+
+/**
+ * Data provider factory for InAndOut analysis. It doesn't have any output but is able
+ * to create custom InAndOut analyses.
+ */
+@NonNullByDefault
+public class InAndOutDataProviderFactory implements IDataProviderFactory, ITmfDataProviderConfigurator {
+
+ /** Data Provider factory ID */
+ public static final String ID = "org.eclipse.tracecompass.incubator.inandout.core.analysis.inAndOutdataProviderFactory"; //$NON-NLS-1$
+
+ private static final ITmfConfigurationSourceType CONFIG_SOURCE_TYPE;
+ private static final String NAME = "In And Out Analysis"; //$NON-NLS-1$
+ private static final String DESCRIPTION = "Configure In And Out analysis using file description"; //$NON-NLS-1$
+
+ private static final String CONFIGURATOR_NAME = "InAndOut Configurator"; //$NON-NLS-1$
+ private static final String CONFIGURATOR_DESCRIPTION = "Configure custom InAndOut analysis"; //$NON-NLS-1$
+
+ private static final String CUSTOM_IN_AND_OUT_ANALYSIS_NAME = "InAndOut Analysis ({0})"; //$NON-NLS-1$
+ private static final String CUSTOM_IN_AND_OUT_ANALYSIS_DESCRIPTION = "Custom InAndOut analysis configured by \" {0}\""; //$NON-NLS-1$
+
+ private static final Table fTmfConfigurationTable = HashBasedTable.create();
+
+ static {
+ Bundle bundle = Platform.getBundle(Activator.PLUGIN_ID);
+ IPath defaultPath = new Path(SegmentSpecifierConfiguration.IN_AND_OUT_CONFIG_SOURCE_SCHEMA);
+ URL url = FileLocator.find(bundle, defaultPath, null);
+ File schemaFile = null;
+ try {
+ schemaFile = new File(FileLocator.toFileURL(url).toURI());
+ } catch (URISyntaxException | IOException e) {
+ Activator.getInstance().logError("Failed to read schema file: " + SegmentSpecifierConfiguration.IN_AND_OUT_CONFIG_SOURCE_SCHEMA, e); //$NON-NLS-1$
+ }
+ CONFIG_SOURCE_TYPE = new TmfConfigurationSourceType.Builder()
+ .setId(SegmentSpecifierConfiguration.IN_AND_OUT_CONFIG_SOURCE_TYPE_ID)
+ .setDescription(DESCRIPTION)
+ .setName(NAME)
+ .setSchemaFile(schemaFile)
+ .build();
+ }
+
+ // Data provider descriptor meant to be used to create new InAndOut configurations and hence new data providers
+ private static final IDataProviderDescriptor DESCRIPTOR = new DataProviderDescriptor.Builder()
+ .setId(ID)
+ .setName(CONFIGURATOR_NAME)
+ .setDescription(CONFIGURATOR_DESCRIPTION)
+ .setProviderType(ProviderType.NONE)
+ .build();
+
+ /**
+ * Default constructor
+ */
+ public InAndOutDataProviderFactory() {
+ TmfSignalManager.register(this);
+ }
+
+ @Override
+ public @Nullable ITmfTreeDataProvider extends ITmfTreeDataModel> createProvider(ITmfTrace trace) {
+ return null;
+ }
+
+ @Override
+ public Collection getDescriptors(ITmfTrace trace) {
+ List list = new ArrayList<>();
+ list.add(DESCRIPTOR);
+ for (ITmfConfiguration config : fTmfConfigurationTable.column(trace).values()) {
+ list.add(getDescriptorFromConfig(config));
+ }
+ return list;
+ }
+
+ @SuppressWarnings("null")
+ @Override
+ public @NonNull List<@NonNull ITmfConfigurationSourceType> getConfigurationSourceTypes() {
+ return List.of(CONFIG_SOURCE_TYPE);
+ }
+
+ @Override
+ public @NonNull IDataProviderDescriptor createDataProviderDescriptors(ITmfTrace trace, ITmfConfiguration configuration) throws TmfConfigurationException {
+
+ if (configuration.getName().equals(TmfConfiguration.UNKNOWN)) {
+ throw new TmfConfigurationException("Missing configuration name of InAndOut analysis"); //$NON-NLS-1$
+ }
+
+ if (configuration.getSourceTypeId().equals(TmfConfiguration.UNKNOWN)) {
+ throw new TmfConfigurationException("Missing configuration type for InAndOut analysis"); //$NON-NLS-1$
+ }
+
+ String description = configuration.getDescription();
+ if (configuration.getDescription().equals(TmfConfiguration.UNKNOWN)) {
+ description = "InAndOut Analysis defined by configuration " + configuration.getName(); //$NON-NLS-1$
+ }
+
+ TmfConfiguration.Builder builder = new TmfConfiguration.Builder();
+ builder.setId(configuration.getId())
+ .setSourceTypeId(configuration.getSourceTypeId())
+ .setName(configuration.getName())
+ .setDescription(description)
+ .setParameters(configuration.getParameters())
+ .build();
+
+ ITmfConfiguration config = builder.build();
+
+ applyConfiguration(trace, config, true);
+ if (fTmfConfigurationTable.contains(config.getId(), trace)) {
+ throw new TmfConfigurationException("Configuration already existis with label: " + config.getName()); //$NON-NLS-1$
+ }
+ fTmfConfigurationTable.put(config.getId(), trace, config);
+ return getDescriptorFromConfig(config);
+ }
+
+ @Override
+ public void removeDataProviderDescriptor(ITmfTrace trace, IDataProviderDescriptor descriptor) throws TmfConfigurationException {
+
+ ITmfConfiguration creationConfiguration = descriptor.getConfiguration();
+ if (creationConfiguration == null) {
+ throw new TmfConfigurationException("Data provider was not created by a configuration"); //$NON-NLS-1$
+ }
+
+ String configId = creationConfiguration.getId();
+ ITmfConfiguration config = fTmfConfigurationTable.get(configId, trace);
+ if (config == null) {
+ return;
+ }
+ config = fTmfConfigurationTable.remove(configId, trace);
+ removeConfiguration(trace, config);
+ }
+
+ /**
+ * Signal handler for opened trace signal. Will populate trace
+ * configurations
+ *
+ * @param signal
+ * the signal to handle
+ */
+ @TmfSignalHandler
+ public void traceOpened(TmfTraceOpenedSignal signal) {
+ ITmfTrace trace = signal.getTrace();
+ if (trace == null) {
+ return;
+ }
+ try {
+ if (trace instanceof TmfExperiment) {
+ for (ITmfTrace tr : TmfTraceManager.getTraceSet(trace)) {
+ @SuppressWarnings("null")
+ // Read configurations from sub-trace
+ List configs = InAndOutAnalysisModule.readConfigurations(tr);
+ readAndApplyConfiguration(trace, configs);
+ }
+ } else {
+ @SuppressWarnings("null")
+ // Read configurations trace
+ List configs = InAndOutAnalysisModule.readConfigurations(trace);
+ readAndApplyConfiguration(trace, configs);
+ }
+ } catch (TmfConfigurationException e) {
+ Activator.getInstance().logError("Error applying configurations for trace " + trace.getName(), e); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Handles trace closed signal
+ *
+ * @param signal
+ * the close signal to handle
+ */
+ @TmfSignalHandler
+ public void traceClosed(TmfTraceClosedSignal signal) {
+ ITmfTrace trace = signal.getTrace();
+ fTmfConfigurationTable.column(trace).clear();
+ }
+
+ private void readAndApplyConfiguration(ITmfTrace trace, List configs) throws TmfConfigurationException {
+ for (ITmfConfiguration config : configs) {
+ if (!fTmfConfigurationTable.contains(config.getId(), trace)) {
+ fTmfConfigurationTable.put(config.getId(), trace, config);
+ applyConfiguration(trace, config, false);
+ }
+ }
+ }
+
+ private void applyConfiguration(ITmfTrace trace, ITmfConfiguration config, boolean writeConfig) throws TmfConfigurationException {
+ if (trace instanceof TmfExperiment) {
+ for (ITmfTrace tr : TmfTraceManager.getTraceSet(trace)) {
+ applyConfiguration(tr, config, writeConfig);
+ }
+ // Only apply for traces in experiment
+ return;
+ }
+ // Apply configuration to any trace (no need to check trace type here)
+ InAndOutAnalysisModule.create(config, trace, writeConfig);
+ }
+
+ private void removeConfiguration(ITmfTrace trace, ITmfConfiguration config) throws TmfConfigurationException {
+ if (trace instanceof TmfExperiment) {
+ for (ITmfTrace tr : TmfTraceManager.getTraceSet(trace)) {
+ removeConfiguration(tr, config);
+ }
+ // only remove for traces in experiment
+ return;
+ }
+ InAndOutAnalysisModule.remove(config, trace);
+ }
+
+ @SuppressWarnings("null")
+ private static IDataProviderDescriptor getDescriptorFromConfig(ITmfConfiguration config) {
+ return new DataProviderDescriptor.Builder()
+ .setParentId(ID)
+ .setId(InAndOutAnalysisModule.ID + config.getId())
+ .setName(NLS.bind(CUSTOM_IN_AND_OUT_ANALYSIS_NAME, config.getName()))
+ .setDescription(NLS.bind(CUSTOM_IN_AND_OUT_ANALYSIS_DESCRIPTION, config.getName()))
+ .setProviderType(ProviderType.NONE)
+ .setConfiguration(config)
+ .build();
+ }
+}
diff --git a/analyses/org.eclipse.tracecompass.incubator.inandout.core/src/org/eclipse/tracecompass/incubator/internal/inandout/core/analysis/SegmentSpecifierConfiguration.java b/analyses/org.eclipse.tracecompass.incubator.inandout.core/src/org/eclipse/tracecompass/incubator/internal/inandout/core/analysis/SegmentSpecifierConfiguration.java
new file mode 100644
index 000000000..80271ddbf
--- /dev/null
+++ b/analyses/org.eclipse.tracecompass.incubator.inandout.core/src/org/eclipse/tracecompass/incubator/internal/inandout/core/analysis/SegmentSpecifierConfiguration.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2024 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.incubator.internal.inandout.core.analysis;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.incubator.internal.inandout.core.Activator;
+import org.eclipse.tracecompass.tmf.core.exceptions.TmfConfigurationException;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
+import com.google.gson.annotations.Expose;
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Model of Segment specifiers
+ */
+@NonNullByDefault
+public class SegmentSpecifierConfiguration {
+
+ /** Configuration source*/
+ public static final String IN_AND_OUT_CONFIG_SOURCE_TYPE_ID = "org.eclipse.tracecompass.incubator.internal.inandout.core.config"; //$NON-NLS-1$
+
+ /** The configuration schema */
+ public static final String IN_AND_OUT_CONFIG_SOURCE_SCHEMA= "schema/in-and-out-analysis.json"; //$NON-NLS-1$
+
+
+ @Expose
+ @SerializedName(value = "specifiers")
+ private @Nullable List fSpecifiers;
+
+ SegmentSpecifierConfiguration() {
+ fSpecifiers = Collections.emptyList();
+ }
+
+ /**
+ * Get the list of {@link SegmentSpecifier}
+ *
+ * @return List of {@link SegmentSpecifier}
+ */
+ public @Nullable List getSpecifiers() {
+ return fSpecifiers;
+ }
+
+ /**
+ * Converts custom JSON parameters to InAndOut specifiers
+ *
+ * @param parameters
+ * the custom parameters map
+ * @return a SegmenSpecifierConiguration instance
+ * @throws TmfConfigurationException
+ * if an error occurred
+ */
+ public static SegmentSpecifierConfiguration fromJsonMap(Map parameters) throws TmfConfigurationException {
+ try {
+ String jsonParameters = new Gson().toJson(parameters, Map.class);
+ @SuppressWarnings("null")
+ SegmentSpecifierConfiguration config = new Gson().fromJson(jsonParameters, SegmentSpecifierConfiguration.class);
+ return config;
+ } catch (JsonSyntaxException e) {
+ Activator.getInstance().logError(e.getMessage(), e);
+ throw new TmfConfigurationException("Can't parse json. ", e); //$NON-NLS-1$
+ }
+ }
+}
diff --git a/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/src/org/eclipse/tracecompass/incubator/internal/trace/server/jersey/rest/core/services/DataProviderService.java b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/src/org/eclipse/tracecompass/incubator/internal/trace/server/jersey/rest/core/services/DataProviderService.java
index 3c4dd333f..1a5bfe9f5 100644
--- a/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/src/org/eclipse/tracecompass/incubator/internal/trace/server/jersey/rest/core/services/DataProviderService.java
+++ b/trace-server/org.eclipse.tracecompass.incubator.trace.server.jersey.rest.core/src/org/eclipse/tracecompass/incubator/internal/trace/server/jersey/rest/core/services/DataProviderService.java
@@ -205,6 +205,10 @@
@SuppressWarnings("restriction")
@Path("/experiments/{expUUID}/outputs")
public class DataProviderService {
+
+ // InAndOut analysis ID
+ private static final String INANDOUT_ANALYSIS_ID = "org.eclipse.tracecompass.incubator.inandout.analysis"; //$NON-NLS-1$
+
private static final @NonNull Logger LOGGER = TraceCompassLog.getLogger(DataProviderService.class);
private final DataProviderManager manager = DataProviderManager.getInstance();
@@ -234,11 +238,18 @@ public Response getProviders(@Parameter(description = EXP_UUID) @PathParam("expU
list.sort(Comparator.comparing(IDataProviderDescriptor::getName));
/*
- * Bug 576402:
- * Filter out all "Event Matching Analysis" related data providers, e.g. "Latency vs Time",
- * because are part in every experiment but won't provide any data.
+ * Remove unwanted data providers:
+ *
+ * - Bug 576402:
+ * Filter out all "Event Matching Analysis" related data providers, e.g. "Latency vs Time",
+ * because are part in every experiment but won't provide any data.
+ *
+ * - Legacy InAndOut
+ * Remove default InAndOutAnalysis used in legacy Trace Compass with Eclipse UI
+ * For trace server, InAndOutAnlaysis is done using the createDataProvider endpoint below.
*/
- list.removeIf(dp -> dp.getId().endsWith(EventMatchingLatencyAnalysis.ID));
+ list.removeIf(dp -> dp.getId().endsWith(EventMatchingLatencyAnalysis.ID) || dp.getId().endsWith(INANDOUT_ANALYSIS_ID));
+
return Response.ok(list).build();
}
diff --git a/trace-server/org.eclipse.tracecompass.incubator.trace.server.product/traceserver.product b/trace-server/org.eclipse.tracecompass.incubator.trace.server.product/traceserver.product
index bbdfe2d82..4f84437c4 100644
--- a/trace-server/org.eclipse.tracecompass.incubator.trace.server.product/traceserver.product
+++ b/trace-server/org.eclipse.tracecompass.incubator.trace.server.product/traceserver.product
@@ -180,6 +180,7 @@ Java and all Java-based trademarks are trademarks of Oracle Corporation in the U
+