/*******************************************************************************
* Copyright (c) 2011, 2016 Ericsson, École Polytechnique de Montréal
*
* 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
* Matthew Khouzam - Added import functionalities
* Geneviève Bastien - Added support for experiment types
* Bernd Hufmann - Updated custom trace type ID handling
*******************************************************************************/
package org.eclipse.tracecompass.tmf.core.project.model;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeSet;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.osgi.util.NLS;
import org.eclipse.tracecompass.internal.tmf.core.Activator;
import org.eclipse.tracecompass.internal.tmf.core.project.model.Messages;
import org.eclipse.tracecompass.tmf.core.TmfCommonConstants;
import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTrace;
import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition;
import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTrace;
import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition;
import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.util.Pair;
/**
* Utility class for accessing TMF trace type extensions from the platform's
* extensions registry.
*
* @author Patrick Tasse
* @author Matthew Khouzam
*/
public final class TmfTraceType {
// ------------------------------------------------------------------
// Constants
// ------------------------------------------------------------------
/** Extension point ID */
public static final String TMF_TRACE_TYPE_ID = "org.eclipse.linuxtools.tmf.core.tracetype"; //$NON-NLS-1$
/** Extension point element 'Category' */
public static final String CATEGORY_ELEM = "category"; //$NON-NLS-1$
/** Extension point element 'Type' */
public static final String TYPE_ELEM = "type"; //$NON-NLS-1$
/** Extension point element 'Experiment' */
public static final String EXPERIMENT_ELEM = "experiment"; //$NON-NLS-1$
/** Extension point attribute 'ID' */
public static final String ID_ATTR = "id"; //$NON-NLS-1$
/** Extension point attribute 'name' */
public static final String NAME_ATTR = "name"; //$NON-NLS-1$
/** Extension point attribute 'category' */
public static final String CATEGORY_ATTR = "category"; //$NON-NLS-1$
/** Extension point attribute 'trace_type' */
public static final String TRACE_TYPE_ATTR = "trace_type"; //$NON-NLS-1$
/** Extension point attribute 'event_type' */
public static final String EVENT_TYPE_ATTR = "event_type"; //$NON-NLS-1$
/** Extension point attribute 'experiment_type' */
public static final String EXPERIMENT_TYPE_ATTR = "experiment_type"; //$NON-NLS-1$
/** Extension point attribute 'isDirectory' */
public static final String IS_DIR_ATTR = "isDirectory"; //$NON-NLS-1$
/** Default experiment type */
public static final String DEFAULT_EXPERIMENT_TYPE = "org.eclipse.linuxtools.tmf.core.experiment.generic"; //$NON-NLS-1$
// The mapping of available trace type IDs to their corresponding
// configuration element
private static final Map<String, IConfigurationElement> TRACE_TYPE_ATTRIBUTES = new HashMap<>();
private static final Map<String, IConfigurationElement> TRACE_CATEGORIES = new HashMap<>();
private static final Map<String, TraceTypeHelper> TRACE_TYPES = new LinkedHashMap<>();
static {
populateCategoriesAndTraceTypes();
populateCustomTraceTypes();
}
/**
* Enum to say whether a type applies to a trace or experiment
*
* @author Geneviève Bastien
*/
public enum TraceElementType {
/** Trace type applies to trace */
TRACE,
/** Trace type applies to experiment */
EXPERIMENT,
}
// ------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------
private TmfTraceType() {
}
// ------------------------------------------------------------------
// Operations
// ------------------------------------------------------------------
/**
* Retrieves the category name from the platform extension registry based on
* the category ID
*
* @param categoryId
* The category ID
* @return the category name or empty string if not found
* @deprecated Use {@link Platform#getExtensionRegistry()} and various
* public constants in {@link TmfTraceType} if achieving this is
* needed.
*/
@Deprecated
public static String getCategoryName(String categoryId) {
IConfigurationElement[] elements = Platform.getExtensionRegistry()
.getConfigurationElementsFor(TMF_TRACE_TYPE_ID);
for (IConfigurationElement element : elements) {
if (element.getName().equals(CATEGORY_ELEM) && element.getAttribute(ID_ATTR).equals(categoryId)) {
return element.getAttribute(NAME_ATTR);
}
}
return ""; //$NON-NLS-1$
}
/**
* Retrieves all configuration elements from the platform extension registry
* for the trace type extension that apply to traces and not experiments.
*
* @return an array of trace type configuration elements
* @deprecated Use {@link Platform#getExtensionRegistry()} and various
* public constants in {@link TmfTraceType} if achieving this is
* needed.
*/
@Deprecated
public static IConfigurationElement[] getTypeElements() {
IConfigurationElement[] elements = Platform.getExtensionRegistry()
.getConfigurationElementsFor(TMF_TRACE_TYPE_ID);
List<IConfigurationElement> typeElements = new LinkedList<>();
for (IConfigurationElement element : elements) {
if (element.getName().equals(TYPE_ELEM)) {
typeElements.add(element);
}
}
return typeElements.toArray(new IConfigurationElement[typeElements.size()]);
}
/**
* Get an iterable view of the existing trace type IDs.
*
* @return The currently registered trace type IDs
* @deprecated Use a combination of {@link #getTraceTypeHelpers()} and
* {@link TraceTypeHelper#getTraceTypeId()} instead.
*/
@Deprecated
public static Iterable<String> getTraceTypeIDs() {
return TRACE_TYPES.keySet();
}
/**
* Get an iterable view of the existing trace type helpers.
*
* @return The currently registered trace type helpers
*/
public static Iterable<TraceTypeHelper> getTraceTypeHelpers() {
return TRACE_TYPES.values();
}
/**
* Returns a list of trace type labels "category : name", ...
*
* Returns only trace types, not experiment types
*
* @return a list of trace type labels
*/
public static String[] getAvailableTraceTypes() {
return getAvailableTraceTypes(null);
}
/**
* Returns a list of trace type labels "category : name", ... sorted by
* given comparator.
*
* Returns only trace types, not experiment types
*
* @param comparator
* Comparator class (type String) or null for alphabetical order.
* @return a list of trace type labels sorted according to the given
* comparator
*/
public static String[] getAvailableTraceTypes(Comparator<String> comparator) {
// Generate the list of Category:TraceType to populate the ComboBox
List<String> traceTypes = new ArrayList<>();
for (TraceTypeHelper tt : TRACE_TYPES.values()) {
if (!tt.isExperimentType()) {
traceTypes.add(tt.getLabel());
}
}
if (comparator == null) {
Collections.sort(traceTypes);
} else {
Collections.sort(traceTypes, comparator);
}
// Format result
return traceTypes.toArray(new String[traceTypes.size()]);
}
/**
* Gets all the custom trace types
*
* @return the list of custom trace types
* @deprecated Use {@link CustomTxtTraceDefinition#loadAll()} and
* {@link CustomXmlTraceDefinition#loadAll()} if achieving this
* is needed.
*/
@Deprecated
public static List<String> getCustomTraceTypes() {
List<String> traceTypes = new ArrayList<>();
for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {
String traceTypeName = def.definitionName;
traceTypes.add(traceTypeName);
}
for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) {
String traceTypeName = def.definitionName;
traceTypes.add(traceTypeName);
}
return traceTypes;
}
private static void populateCustomTraceTypes() {
// add the custom trace types
for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {
CustomTxtTrace trace = new CustomTxtTrace(def);
String traceTypeId = trace.getTraceTypeId();
TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, def.categoryName, def.definitionName, trace, false, TraceElementType.TRACE);
TRACE_TYPES.put(traceTypeId, tt);
// Deregister trace as signal handler because it is only used for
// validation
TmfSignalManager.deregister(trace);
}
for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) {
CustomXmlTrace trace = new CustomXmlTrace(def);
String traceTypeId = trace.getTraceTypeId();
TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, def.categoryName, def.definitionName, trace, false, TraceElementType.TRACE);
TRACE_TYPES.put(traceTypeId, tt);
// Deregister trace as signal handler because it is only used for
// validation
TmfSignalManager.deregister(trace);
}
}
/**
* Add or replace a custom trace type
*
* @param traceClass
* The custom trace class, either {@link CustomTxtTrace} or
* {@link CustomXmlTrace}
* @param category
* The custom parser category
* @param definitionName
* The custom parser definition name to add or replace
*/
public static void addCustomTraceType(Class<? extends ITmfTrace> traceClass, String category, String definitionName) {
String traceTypeId = null;
ITmfTrace trace = null;
if (traceClass.equals(CustomTxtTrace.class)) {
CustomTxtTraceDefinition def = CustomTxtTraceDefinition.load(category, definitionName);
if (def != null) {
trace = new CustomTxtTrace(def);
traceTypeId = trace.getTraceTypeId();
}
} else if (traceClass.equals(CustomXmlTrace.class)) {
CustomXmlTraceDefinition def = CustomXmlTraceDefinition.load(category, definitionName);
if (def != null) {
trace = new CustomXmlTrace(def);
traceTypeId = trace.getTraceTypeId();
}
}
if (traceTypeId != null && trace != null) {
TraceTypeHelper helper = TRACE_TYPES.get(traceTypeId);
if (helper != null) {
helper.getTrace().dispose();
}
TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, category, definitionName, trace, false, TraceElementType.TRACE);
TRACE_TYPES.put(traceTypeId, tt);
// Deregister trace as signal handler because it is only used for
// validation
TmfSignalManager.deregister(trace);
}
}
/**
* Remove a custom trace type
*
* @param traceClass
* The custom trace class, either {@link CustomTxtTrace} or
* {@link CustomXmlTrace}
* @param category
* The custom parser category
* @param definitionName
* The custom parser definition name to add or replace
*/
public static void removeCustomTraceType(Class<? extends ITmfTrace> traceClass, String category, String definitionName) {
String traceTypeId = null;
if (traceClass.equals(CustomTxtTrace.class)) {
traceTypeId = CustomTxtTrace.buildTraceTypeId(category, definitionName);
} else if (traceClass.equals(CustomXmlTrace.class)) {
traceTypeId = CustomXmlTrace.buildTraceTypeId(category, definitionName);
}
if (traceTypeId != null) {
TraceTypeHelper helper = TRACE_TYPES.remove(traceTypeId);
if (helper != null) {
helper.getTrace().dispose();
}
}
}
/**
* Gets a trace type for a given canonical id
*
* @param id
* the ID of the trace
* @return the return type
*/
public static TraceTypeHelper getTraceType(String id) {
return TRACE_TYPES.get(id);
}
private static void populateCategoriesAndTraceTypes() {
if (TRACE_TYPES.isEmpty()) {
// Populate the Categories and Trace Types
IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType.TMF_TRACE_TYPE_ID);
for (IConfigurationElement ce : config) {
String elementName = ce.getName();
if (elementName.equals(TmfTraceType.TYPE_ELEM)) {
String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR);
TRACE_TYPE_ATTRIBUTES.put(traceTypeId, ce);
} else if (elementName.equals(TmfTraceType.CATEGORY_ELEM)) {
String categoryId = ce.getAttribute(TmfTraceType.ID_ATTR);
TRACE_CATEGORIES.put(categoryId, ce);
} else if (elementName.equals(TmfTraceType.EXPERIMENT_ELEM)) {
String experimentTypeId = ce.getAttribute(TmfTraceType.ID_ATTR);
TRACE_TYPE_ATTRIBUTES.put(experimentTypeId, ce);
}
}
// create the trace types
for (Entry<String, IConfigurationElement> entry : TRACE_TYPE_ATTRIBUTES.entrySet()) {
IConfigurationElement ce = entry.getValue();
final String category = getCategory(ce);
final String attribute = ce.getAttribute(TmfTraceType.NAME_ATTR);
ITmfTrace trace = null;
TraceElementType elementType = TraceElementType.TRACE;
try {
if (ce.getName().equals(TmfTraceType.TYPE_ELEM)) {
trace = (ITmfTrace) ce.createExecutableExtension(TmfTraceType.TRACE_TYPE_ATTR);
} else if (ce.getName().equals(TmfTraceType.EXPERIMENT_ELEM)) {
trace = (ITmfTrace) ce.createExecutableExtension(TmfTraceType.EXPERIMENT_TYPE_ATTR);
elementType = TraceElementType.EXPERIMENT;
}
if (trace == null) {
break;
}
// Deregister trace as signal handler because it is only
// used for validation
TmfSignalManager.deregister(trace);
final String dirString = ce.getAttribute(TmfTraceType.IS_DIR_ATTR);
boolean isDir = Boolean.parseBoolean(dirString);
final String typeId = entry.getKey();
TraceTypeHelper tt = new TraceTypeHelper(typeId, category, attribute, trace, isDir, elementType);
TRACE_TYPES.put(typeId, tt);
} catch (CoreException e) {
Activator.logError("Unexpected error during populating trace types", e); //$NON-NLS-1$
}
}
}
}
private static String getCategory(IConfigurationElement ce) {
final String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR);
if (categoryId != null) {
IConfigurationElement category = TRACE_CATEGORIES.get(categoryId);
if (category != null && !category.getName().equals("")) { //$NON-NLS-1$
return category.getAttribute(TmfTraceType.NAME_ATTR);
}
}
return ""; //$NON-NLS-1$
}
/**
* Returns the list of trace categories
*
* @return the list of trace categories
* @deprecated Use {@link #getTraceTypeHelpers()} and
* {@link TraceTypeHelper#getCategoryName()} to retrieve all
* category names.
*/
@Deprecated
public static List<String> getTraceCategories() {
List<String> categoryNames = new ArrayList<>();
for (TraceTypeHelper helper : TRACE_TYPES.values()) {
final String categoryName = helper.getCategoryName();
if (!categoryNames.contains(categoryName)) {
categoryNames.add(categoryName);
}
}
return categoryNames;
}
/**
* Get the trace type helper classes from category name. Return only the
* trace types, not the experiment types
*
* @param categoryName
* the categoryName to lookup
* @return a list of trace type helper classes {@link TraceTypeHelper}
* @deprecated Use {@link #getTraceTypeHelpers()} and
* {@link TraceTypeHelper#getCategoryName()} to retrieve all
* category names.
*/
@Deprecated
public static List<TraceTypeHelper> getTraceTypes(String categoryName) {
List<TraceTypeHelper> traceNames = new ArrayList<>();
for (TraceTypeHelper traceTypeHelper : TRACE_TYPES.values()) {
if (!traceTypeHelper.isExperimentType()) {
final String storedCategoryName = traceTypeHelper.getCategoryName();
if (storedCategoryName.equals(categoryName)) {
traceNames.add(traceTypeHelper);
}
}
}
return traceNames;
}
/**
* Validate a trace type
*
* @param traceTypeName
* the trace category (canonical name)
* @param fileName
* the file name (and path)
* @return true if the trace is of a valid type
* @deprecated Use TmfTraceType.getTraceTypeHelpers and
* {@link TraceTypeHelper#validate(String)} or
* {@link TraceTypeHelper#validateWithConfidence(String)}
*/
@Deprecated
public static boolean validate(String traceTypeName, String fileName) {
if (traceTypeName != null && !traceTypeName.isEmpty()) {
final TraceTypeHelper traceTypeHelper = TRACE_TYPES.get(traceTypeName);
if (traceTypeHelper == null || !traceTypeHelper.validate(fileName).isOK()) {
return false;
}
}
return true;
}
/**
* Validate a trace
*
* @param traceToValidate
* the trace category (canonical name)
* @return true if the trace is of a valid type
* @deprecated Use TmfTraceType.getTraceTypeHelpers and
* {@link TraceTypeHelper#validate(String)} or
* {@link TraceTypeHelper#validateWithConfidence(String)}
*/
@Deprecated
public static boolean validate(TraceValidationHelper traceToValidate) {
return validate(traceToValidate.getTraceType(), traceToValidate.getTraceToScan());
}
/**
* Get a configuration element for a given name
*
* @param traceType
* the name canonical
* @return the configuration element, can be null
*/
public static IConfigurationElement getTraceAttributes(String traceType) {
return TRACE_TYPE_ATTRIBUTES.get(traceType);
}
/**
* Find the id of a trace type by its label "category : name"
*
* @param label
* the trace type label
* @return the trace type id
*/
public static String getTraceTypeId(String label) {
for (Entry<String, TraceTypeHelper> entry : TRACE_TYPES.entrySet()) {
if (entry.getValue().getLabel().equals(label)) {
return entry.getKey();
}
}
return null;
}
/**
* Checks if a trace is a valid directory trace
*
* @param path
* the file name (and path)
* @return <code>true</code> if the trace is a valid directory trace else
* <code>false</code>
*/
public static boolean isDirectoryTrace(String path) {
final Iterable<TraceTypeHelper> traceTypeHelpers = getTraceTypeHelpers();
for (TraceTypeHelper traceTypeHelper : traceTypeHelpers) {
if (traceTypeHelper.isDirectoryTraceType() &&
(traceTypeHelper.validate(path).getSeverity() != IStatus.ERROR)) {
return true;
}
}
return false;
}
/**
* @param traceType
* the trace type
* @return <code>true</code> it is a directory trace type else else
* <code>false</code>
*/
public static boolean isDirectoryTraceType(String traceType) {
if (traceType != null) {
TraceTypeHelper traceTypeHelper = getTraceType(traceType);
if (traceTypeHelper != null) {
return traceTypeHelper.isDirectoryTraceType();
}
return false;
}
throw new IllegalArgumentException("Invalid trace type string: " + traceType); //$NON-NLS-1$
}
/**
* Get the trace type id for a resource
*
* @param resource
* the resource
* @return the trace type id or null if it is not set
* @throws CoreException
* if the trace type id cannot be accessed
*/
public static String getTraceTypeId(IResource resource) throws CoreException {
String traceTypeId = resource.getPersistentProperties().get(TmfCommonConstants.TRACETYPE);
return buildCompatibilityTraceTypeId(traceTypeId);
}
/**
* This methods builds a trace type ID from a given ID taking into
* consideration any format changes that were done for the IDs of custom
* text or XML traces. For example, such format change took place when
* moving to Trace Compass. Trace type IDs that are part of the plug-in
* extension for trace types won't be changed.
*
* This method is useful for IDs that were persisted in the workspace before
* the format changes (e.g. in the persistent properties of a trace
* resource).
*
* It ensures backwards compatibility of the workspace for custom text and
* XML traces.
*
* @param traceTypeId
* the legacy trace type ID
* @return the trace type ID in Trace Compass format
*/
public static String buildCompatibilityTraceTypeId(String traceTypeId) {
// Fix custom trace type id with old class name or without category name
// for backward compatibility
if (traceTypeId != null) {
String newTraceType = CustomTxtTrace.buildCompatibilityTraceTypeId(traceTypeId);
if (newTraceType.equals(traceTypeId)) {
newTraceType = CustomXmlTrace.buildCompatibilityTraceTypeId(traceTypeId);
}
return newTraceType;
}
return traceTypeId;
}
/**
* This method figures out the trace type of a given trace.
*
* @param path
* The path of trace to import (file or directory for directory traces)
* @param traceTypeHint
* the ID of a trace (like "o.e.l.specifictrace" )
* @return a list of {@link TraceTypeHelper} sorted by confidence (highest first)
*
* @throws TmfTraceImportException
* if there are errors in the trace file or no trace type found
* for a directory trace
* @since 2.0
*/
public static @NonNull List<TraceTypeHelper> selectTraceType(String path, String traceTypeHint) throws TmfTraceImportException {
Comparator<Pair<Integer, TraceTypeHelper>> comparator = new Comparator<Pair<Integer, TraceTypeHelper>>() {
@Override
public int compare(Pair<Integer, TraceTypeHelper> o1, Pair<Integer, TraceTypeHelper> o2) {
int res = -o1.getFirst().compareTo(o2.getFirst()); // invert so that highest confidence is first
if (res == 0) {
res = o1.getSecond().getName().compareTo(o2.getSecond().getName());
}
return res;
}
};
TreeSet<Pair<Integer, TraceTypeHelper>> validCandidates = new TreeSet<>(comparator);
final Iterable<TraceTypeHelper> traceTypeHelpers = TmfTraceType.getTraceTypeHelpers();
for (TraceTypeHelper traceTypeHelper : traceTypeHelpers) {
if (traceTypeHelper.isExperimentType()) {
continue;
}
int confidence = traceTypeHelper.validateWithConfidence(path);
if (confidence >= 0) {
// insert in the tree map, ordered by confidence (highest confidence first) then name
Pair<Integer, TraceTypeHelper> element = new Pair<>(confidence, traceTypeHelper);
validCandidates.add(element);
}
}
List<TraceTypeHelper> returned = new ArrayList<>();
if (validCandidates.isEmpty()) {
File traceFile = new File(path);
if (traceFile.isFile()) {
return returned;
}
final String errorMsg = NLS.bind(Messages.TmfOpenTraceHelper_NoTraceTypeMatch, path);
throw new TmfTraceImportException(errorMsg);
}
if (validCandidates.size() != 1) {
List<Pair<Integer, TraceTypeHelper>> candidates = new ArrayList<>(validCandidates);
List<Pair<Integer, TraceTypeHelper>> reducedCandidates = reduce(candidates);
for (Pair<Integer, TraceTypeHelper> candidatePair : reducedCandidates) {
TraceTypeHelper candidate = candidatePair.getSecond();
if (candidate.getTraceTypeId().equals(traceTypeHint)) {
returned.add(candidate);
break;
}
}
if (returned.size() == 0) {
if (reducedCandidates.size() == 0) {
throw new TmfTraceImportException("Error reducing trace type candidates"); //$NON-NLS-1$
} else if (reducedCandidates.size() == 1) {
// Don't select the trace type if it has the lowest confidence
if (reducedCandidates.get(0).getFirst() > 0) {
returned.add(reducedCandidates.get(0).getSecond());
}
} else {
for (Pair<Integer, TraceTypeHelper> candidatePair : reducedCandidates) {
// Don't select the trace type if it has the lowest confidence
if (candidatePair.getFirst() > 0) {
returned.add(candidatePair.getSecond());
}
}
}
}
} else {
// Don't select the trace type if it has the lowest confidence
if (validCandidates.first().getFirst() > 0) {
returned.add(validCandidates.first().getSecond());
}
}
return returned;
}
private static List<Pair<Integer, TraceTypeHelper>> reduce(List<Pair<Integer, TraceTypeHelper>> candidates) {
List<Pair<Integer, TraceTypeHelper>> retVal = new ArrayList<>();
// get all the tracetypes that are unique in that stage
for (Pair<Integer, TraceTypeHelper> candidatePair : candidates) {
TraceTypeHelper candidate = candidatePair.getSecond();
if (isUnique(candidate, candidates)) {
retVal.add(candidatePair);
}
}
return retVal;
}
/*
* Only return the leaves of the trace types. Ignore custom trace types.
*/
private static boolean isUnique(TraceTypeHelper trace, List<Pair<Integer, TraceTypeHelper>> set) {
if (trace.getTraceClass().equals(CustomTxtTrace.class) ||
trace.getTraceClass().equals(CustomXmlTrace.class)) {
return true;
}
// check if the trace type is the leaf. we make an instance of the trace
// type and if it is only an instance of itself, it is a leaf
final ITmfTrace tmfTrace = trace.getTrace();
int count = -1;
for (Pair<Integer, TraceTypeHelper> child : set) {
final ITmfTrace traceCandidate = child.getSecond().getTrace();
if (tmfTrace.getClass().isInstance(traceCandidate)) {
count++;
}
}
return count == 0;
}
}