1 /*******************************************************************************
2 * Copyright (c) 2011, 2016 Ericsson, École Polytechnique de Montréal
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Patrick Tasse - Initial API and implementation
11 * Matthew Khouzam - Added import functionalities
12 * Geneviève Bastien - Added support for experiment types
13 * Bernd Hufmann - Updated custom trace type ID handling
14 *******************************************************************************/
16 package org
.eclipse
.tracecompass
.tmf
.core
.project
.model
;
19 import java
.util
.ArrayList
;
20 import java
.util
.Collections
;
21 import java
.util
.Comparator
;
22 import java
.util
.HashMap
;
23 import java
.util
.LinkedHashMap
;
24 import java
.util
.LinkedList
;
25 import java
.util
.List
;
27 import java
.util
.Map
.Entry
;
28 import java
.util
.TreeSet
;
30 import org
.eclipse
.core
.resources
.IResource
;
31 import org
.eclipse
.core
.runtime
.CoreException
;
32 import org
.eclipse
.core
.runtime
.IConfigurationElement
;
33 import org
.eclipse
.core
.runtime
.IStatus
;
34 import org
.eclipse
.core
.runtime
.Platform
;
35 import org
.eclipse
.jdt
.annotation
.NonNull
;
36 import org
.eclipse
.osgi
.util
.NLS
;
37 import org
.eclipse
.tracecompass
.internal
.tmf
.core
.Activator
;
38 import org
.eclipse
.tracecompass
.internal
.tmf
.core
.project
.model
.Messages
;
39 import org
.eclipse
.tracecompass
.tmf
.core
.TmfCommonConstants
;
40 import org
.eclipse
.tracecompass
.tmf
.core
.parsers
.custom
.CustomTxtTrace
;
41 import org
.eclipse
.tracecompass
.tmf
.core
.parsers
.custom
.CustomTxtTraceDefinition
;
42 import org
.eclipse
.tracecompass
.tmf
.core
.parsers
.custom
.CustomXmlTrace
;
43 import org
.eclipse
.tracecompass
.tmf
.core
.parsers
.custom
.CustomXmlTraceDefinition
;
44 import org
.eclipse
.tracecompass
.tmf
.core
.signal
.TmfSignalManager
;
45 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
46 import org
.eclipse
.tracecompass
.tmf
.core
.util
.Pair
;
49 * Utility class for accessing TMF trace type extensions from the platform's
50 * extensions registry.
52 * @author Patrick Tasse
53 * @author Matthew Khouzam
55 public final class TmfTraceType
{
57 // ------------------------------------------------------------------
59 // ------------------------------------------------------------------
61 /** Extension point ID */
62 public static final String TMF_TRACE_TYPE_ID
= "org.eclipse.linuxtools.tmf.core.tracetype"; //$NON-NLS-1$
64 /** Extension point element 'Category' */
65 public static final String CATEGORY_ELEM
= "category"; //$NON-NLS-1$
67 /** Extension point element 'Type' */
68 public static final String TYPE_ELEM
= "type"; //$NON-NLS-1$
70 /** Extension point element 'Experiment' */
71 public static final String EXPERIMENT_ELEM
= "experiment"; //$NON-NLS-1$
73 /** Extension point attribute 'ID' */
74 public static final String ID_ATTR
= "id"; //$NON-NLS-1$
76 /** Extension point attribute 'name' */
77 public static final String NAME_ATTR
= "name"; //$NON-NLS-1$
79 /** Extension point attribute 'category' */
80 public static final String CATEGORY_ATTR
= "category"; //$NON-NLS-1$
82 /** Extension point attribute 'trace_type' */
83 public static final String TRACE_TYPE_ATTR
= "trace_type"; //$NON-NLS-1$
85 /** Extension point attribute 'event_type' */
86 public static final String EVENT_TYPE_ATTR
= "event_type"; //$NON-NLS-1$
88 /** Extension point attribute 'experiment_type' */
89 public static final String EXPERIMENT_TYPE_ATTR
= "experiment_type"; //$NON-NLS-1$
91 /** Extension point attribute 'isDirectory' */
92 public static final String IS_DIR_ATTR
= "isDirectory"; //$NON-NLS-1$
94 /** Default experiment type */
95 public static final String DEFAULT_EXPERIMENT_TYPE
= "org.eclipse.linuxtools.tmf.core.experiment.generic"; //$NON-NLS-1$
97 // The mapping of available trace type IDs to their corresponding
98 // configuration element
99 private static final Map
<String
, IConfigurationElement
> TRACE_TYPE_ATTRIBUTES
= new HashMap
<>();
100 private static final Map
<String
, IConfigurationElement
> TRACE_CATEGORIES
= new HashMap
<>();
101 private static final Map
<String
, @NonNull TraceTypeHelper
> TRACE_TYPES
= new LinkedHashMap
<>();
104 populateCategoriesAndTraceTypes();
105 populateCustomTraceTypes();
110 * Enum to say whether a type applies to a trace or experiment
112 * @author Geneviève Bastien
114 public enum TraceElementType
{
115 /** Trace type applies to trace */
117 /** Trace type applies to experiment */
121 // ------------------------------------------------------------------
123 // ------------------------------------------------------------------
125 private TmfTraceType() {
128 // ------------------------------------------------------------------
130 // ------------------------------------------------------------------
133 * Retrieves the category name from the platform extension registry based on
138 * @return the category name or empty string if not found
139 * @deprecated Use {@link Platform#getExtensionRegistry()} and various
140 * public constants in {@link TmfTraceType} if achieving this is
144 public static String
getCategoryName(String categoryId
) {
145 IConfigurationElement
[] elements
= Platform
.getExtensionRegistry()
146 .getConfigurationElementsFor(TMF_TRACE_TYPE_ID
);
147 for (IConfigurationElement element
: elements
) {
148 if (element
.getName().equals(CATEGORY_ELEM
) && element
.getAttribute(ID_ATTR
).equals(categoryId
)) {
149 return element
.getAttribute(NAME_ATTR
);
152 return ""; //$NON-NLS-1$
156 * Retrieves all configuration elements from the platform extension registry
157 * for the trace type extension that apply to traces and not experiments.
159 * @return an array of trace type configuration elements
160 * @deprecated Use {@link Platform#getExtensionRegistry()} and various
161 * public constants in {@link TmfTraceType} if achieving this is
165 public static IConfigurationElement
[] getTypeElements() {
166 IConfigurationElement
[] elements
= Platform
.getExtensionRegistry()
167 .getConfigurationElementsFor(TMF_TRACE_TYPE_ID
);
168 List
<IConfigurationElement
> typeElements
= new LinkedList
<>();
169 for (IConfigurationElement element
: elements
) {
170 if (element
.getName().equals(TYPE_ELEM
)) {
171 typeElements
.add(element
);
174 return typeElements
.toArray(new IConfigurationElement
[typeElements
.size()]);
178 * Get an iterable view of the existing trace type IDs.
180 * @return The currently registered trace type IDs
181 * @deprecated Use a combination of {@link #getTraceTypeHelpers()} and
182 * {@link TraceTypeHelper#getTraceTypeId()} instead.
185 public static Iterable
<String
> getTraceTypeIDs() {
186 return TRACE_TYPES
.keySet();
190 * Get an iterable view of the existing trace type helpers.
192 * @return The currently registered trace type helpers
194 public static Iterable
<@NonNull TraceTypeHelper
> getTraceTypeHelpers() {
195 return TRACE_TYPES
.values();
199 * Returns a list of trace type labels "category : name", ...
201 * Returns only trace types, not experiment types
203 * @return a list of trace type labels
205 public static String
[] getAvailableTraceTypes() {
206 return getAvailableTraceTypes(null);
210 * Returns a list of trace type labels "category : name", ... sorted by
213 * Returns only trace types, not experiment types
216 * Comparator class (type String) or null for alphabetical order.
217 * @return a list of trace type labels sorted according to the given
220 public static String
[] getAvailableTraceTypes(Comparator
<String
> comparator
) {
222 // Generate the list of Category:TraceType to populate the ComboBox
223 List
<String
> traceTypes
= new ArrayList
<>();
225 for (TraceTypeHelper tt
: getTraceTypeHelpers()) {
226 if (tt
.isEnabled() && !tt
.isExperimentType()) {
227 traceTypes
.add(tt
.getLabel());
231 if (comparator
== null) {
232 Collections
.sort(traceTypes
);
234 Collections
.sort(traceTypes
, comparator
);
238 return traceTypes
.toArray(new String
[traceTypes
.size()]);
242 * Gets all the custom trace types
244 * @return the list of custom trace types
245 * @deprecated Use {@link CustomTxtTraceDefinition#loadAll()} and
246 * {@link CustomXmlTraceDefinition#loadAll()} if achieving this
250 public static List
<String
> getCustomTraceTypes() {
252 List
<String
> traceTypes
= new ArrayList
<>();
253 for (CustomTxtTraceDefinition def
: CustomTxtTraceDefinition
.loadAll()) {
254 String traceTypeName
= def
.definitionName
;
255 traceTypes
.add(traceTypeName
);
257 for (CustomXmlTraceDefinition def
: CustomXmlTraceDefinition
.loadAll()) {
258 String traceTypeName
= def
.definitionName
;
259 traceTypes
.add(traceTypeName
);
264 private static void populateCustomTraceTypes() {
265 // add the custom trace types
266 for (CustomTxtTraceDefinition def
: CustomTxtTraceDefinition
.loadAll()) {
267 CustomTxtTrace trace
= new CustomTxtTrace(def
);
268 String traceTypeId
= trace
.getTraceTypeId();
269 TraceTypeHelper tt
= new TraceTypeHelper(traceTypeId
, def
.categoryName
, def
.definitionName
, trace
, false, TraceElementType
.TRACE
);
270 TRACE_TYPES
.put(traceTypeId
, tt
);
271 // Deregister trace as signal handler because it is only used for
273 TmfSignalManager
.deregister(trace
);
275 for (CustomXmlTraceDefinition def
: CustomXmlTraceDefinition
.loadAll()) {
276 CustomXmlTrace trace
= new CustomXmlTrace(def
);
277 String traceTypeId
= trace
.getTraceTypeId();
278 TraceTypeHelper tt
= new TraceTypeHelper(traceTypeId
, def
.categoryName
, def
.definitionName
, trace
, false, TraceElementType
.TRACE
);
279 TRACE_TYPES
.put(traceTypeId
, tt
);
280 // Deregister trace as signal handler because it is only used for
282 TmfSignalManager
.deregister(trace
);
287 * Add or replace a custom trace type
290 * The custom trace class, either {@link CustomTxtTrace} or
291 * {@link CustomXmlTrace}
293 * The custom parser category
294 * @param definitionName
295 * The custom parser definition name to add or replace
297 public static void addCustomTraceType(Class
<?
extends ITmfTrace
> traceClass
, String category
, String definitionName
) {
298 String traceTypeId
= null;
299 ITmfTrace trace
= null;
301 if (traceClass
.equals(CustomTxtTrace
.class)) {
302 CustomTxtTraceDefinition def
= CustomTxtTraceDefinition
.load(category
, definitionName
);
304 trace
= new CustomTxtTrace(def
);
305 traceTypeId
= trace
.getTraceTypeId();
307 } else if (traceClass
.equals(CustomXmlTrace
.class)) {
308 CustomXmlTraceDefinition def
= CustomXmlTraceDefinition
.load(category
, definitionName
);
310 trace
= new CustomXmlTrace(def
);
311 traceTypeId
= trace
.getTraceTypeId();
315 if (traceTypeId
!= null && trace
!= null) {
316 TraceTypeHelper helper
= TRACE_TYPES
.get(traceTypeId
);
317 if (helper
!= null) {
318 helper
.getTrace().dispose();
320 TraceTypeHelper tt
= new TraceTypeHelper(traceTypeId
, category
, definitionName
, trace
, false, TraceElementType
.TRACE
);
321 TRACE_TYPES
.put(traceTypeId
, tt
);
322 // Deregister trace as signal handler because it is only used for
324 TmfSignalManager
.deregister(trace
);
329 * Remove a custom trace type
332 * The custom trace class, either {@link CustomTxtTrace} or
333 * {@link CustomXmlTrace}
335 * The custom parser category
336 * @param definitionName
337 * The custom parser definition name to add or replace
339 public static void removeCustomTraceType(Class
<?
extends ITmfTrace
> traceClass
, String category
, String definitionName
) {
340 String traceTypeId
= null;
341 if (traceClass
.equals(CustomTxtTrace
.class)) {
342 traceTypeId
= CustomTxtTrace
.buildTraceTypeId(category
, definitionName
);
343 } else if (traceClass
.equals(CustomXmlTrace
.class)) {
344 traceTypeId
= CustomXmlTrace
.buildTraceTypeId(category
, definitionName
);
346 if (traceTypeId
!= null) {
347 TraceTypeHelper helper
= TRACE_TYPES
.remove(traceTypeId
);
348 if (helper
!= null) {
349 helper
.getTrace().dispose();
355 * Gets a trace type for a given canonical id
358 * the ID of the trace
359 * @return the return type
361 public static TraceTypeHelper
getTraceType(String id
) {
362 return TRACE_TYPES
.get(id
);
365 private static void enableTraceTypes() {
366 List
<String
> preferences
= TraceTypePreferences
.getPreferenceValue();
367 TRACE_TYPES
.values().forEach(helper
-> {
368 if (!helper
.isExperimentType()) {
369 helper
.setEnabled(!preferences
.contains(helper
.getTraceTypeId()));
374 private static void populateCategoriesAndTraceTypes() {
375 if (TRACE_TYPES
.isEmpty()) {
376 // Populate the Categories and Trace Types
377 IConfigurationElement
[] config
= Platform
.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType
.TMF_TRACE_TYPE_ID
);
378 for (IConfigurationElement ce
: config
) {
379 String elementName
= ce
.getName();
380 if (elementName
.equals(TmfTraceType
.TYPE_ELEM
)) {
381 String traceTypeId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
382 TRACE_TYPE_ATTRIBUTES
.put(traceTypeId
, ce
);
383 } else if (elementName
.equals(TmfTraceType
.CATEGORY_ELEM
)) {
384 String categoryId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
385 TRACE_CATEGORIES
.put(categoryId
, ce
);
386 } else if (elementName
.equals(TmfTraceType
.EXPERIMENT_ELEM
)) {
387 String experimentTypeId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
388 TRACE_TYPE_ATTRIBUTES
.put(experimentTypeId
, ce
);
391 // create the trace types
392 for (Entry
<String
, IConfigurationElement
> entry
: TRACE_TYPE_ATTRIBUTES
.entrySet()) {
393 IConfigurationElement ce
= entry
.getValue();
394 final String category
= getCategory(ce
);
395 final String attribute
= ce
.getAttribute(TmfTraceType
.NAME_ATTR
);
396 ITmfTrace trace
= null;
397 TraceElementType elementType
= TraceElementType
.TRACE
;
399 if (ce
.getName().equals(TmfTraceType
.TYPE_ELEM
)) {
400 trace
= (ITmfTrace
) ce
.createExecutableExtension(TmfTraceType
.TRACE_TYPE_ATTR
);
401 } else if (ce
.getName().equals(TmfTraceType
.EXPERIMENT_ELEM
)) {
402 trace
= (ITmfTrace
) ce
.createExecutableExtension(TmfTraceType
.EXPERIMENT_TYPE_ATTR
);
403 elementType
= TraceElementType
.EXPERIMENT
;
408 // Deregister trace as signal handler because it is only
409 // used for validation
410 TmfSignalManager
.deregister(trace
);
412 final String dirString
= ce
.getAttribute(TmfTraceType
.IS_DIR_ATTR
);
413 boolean isDir
= Boolean
.parseBoolean(dirString
);
415 final String typeId
= entry
.getKey();
416 TraceTypeHelper tt
= new TraceTypeHelper(typeId
, category
, attribute
, trace
, isDir
, elementType
);
417 TRACE_TYPES
.put(typeId
, tt
);
418 } catch (CoreException e
) {
419 Activator
.logError("Unexpected error during populating trace types", e
); //$NON-NLS-1$
426 private static String
getCategory(IConfigurationElement ce
) {
427 final String categoryId
= ce
.getAttribute(TmfTraceType
.CATEGORY_ATTR
);
428 if (categoryId
!= null) {
429 IConfigurationElement category
= TRACE_CATEGORIES
.get(categoryId
);
430 if (category
!= null && !category
.getName().equals("")) { //$NON-NLS-1$
431 return category
.getAttribute(TmfTraceType
.NAME_ATTR
);
434 return ""; //$NON-NLS-1$
438 * Returns the list of trace categories
440 * @return the list of trace categories
441 * @deprecated Use {@link #getTraceTypeHelpers()} and
442 * {@link TraceTypeHelper#getCategoryName()} to retrieve all
446 public static List
<String
> getTraceCategories() {
447 List
<String
> categoryNames
= new ArrayList
<>();
448 for (TraceTypeHelper helper
: TRACE_TYPES
.values()) {
449 final String categoryName
= helper
.getCategoryName();
450 if (!categoryNames
.contains(categoryName
)) {
451 categoryNames
.add(categoryName
);
454 return categoryNames
;
458 * Get the trace type helper classes from category name. Return only the
459 * trace types, not the experiment types
461 * @param categoryName
462 * the categoryName to lookup
463 * @return a list of trace type helper classes {@link TraceTypeHelper}
464 * @deprecated Use {@link #getTraceTypeHelpers()} and
465 * {@link TraceTypeHelper#getCategoryName()} to retrieve all
469 public static List
<TraceTypeHelper
> getTraceTypes(String categoryName
) {
470 List
<TraceTypeHelper
> traceNames
= new ArrayList
<>();
471 for (TraceTypeHelper traceTypeHelper
: TRACE_TYPES
.values()) {
472 if (!traceTypeHelper
.isExperimentType()) {
473 final String storedCategoryName
= traceTypeHelper
.getCategoryName();
474 if (storedCategoryName
.equals(categoryName
)) {
475 traceNames
.add(traceTypeHelper
);
483 * Validate a trace type
485 * @param traceTypeName
486 * the trace category (canonical name)
488 * the file name (and path)
489 * @return true if the trace is of a valid type
490 * @deprecated Use TmfTraceType.getTraceTypeHelpers and
491 * {@link TraceTypeHelper#validate(String)} or
492 * {@link TraceTypeHelper#validateWithConfidence(String)}
495 public static boolean validate(String traceTypeName
, String fileName
) {
496 if (traceTypeName
!= null && !traceTypeName
.isEmpty()) {
497 final TraceTypeHelper traceTypeHelper
= TRACE_TYPES
.get(traceTypeName
);
498 if (traceTypeHelper
== null || !traceTypeHelper
.validate(fileName
).isOK()) {
508 * @param traceToValidate
509 * the trace category (canonical name)
510 * @return true if the trace is of a valid type
511 * @deprecated Use TmfTraceType.getTraceTypeHelpers and
512 * {@link TraceTypeHelper#validate(String)} or
513 * {@link TraceTypeHelper#validateWithConfidence(String)}
516 public static boolean validate(TraceValidationHelper traceToValidate
) {
517 return validate(traceToValidate
.getTraceType(), traceToValidate
.getTraceToScan());
521 * Get a configuration element for a given name
525 * @return the configuration element, can be null
527 public static IConfigurationElement
getTraceAttributes(String traceType
) {
528 return TRACE_TYPE_ATTRIBUTES
.get(traceType
);
532 * Find the id of a trace type by its label "category : name"
535 * the trace type label
536 * @return the trace type id
538 public static String
getTraceTypeId(String label
) {
539 for (Entry
<String
, TraceTypeHelper
> entry
: TRACE_TYPES
.entrySet()) {
540 if (entry
.getValue().getLabel().equals(label
)) {
541 return entry
.getKey();
548 * Checks if a trace is a valid directory trace
551 * the file name (and path)
552 * @return <code>true</code> if the trace is a valid directory trace else
555 public static boolean isDirectoryTrace(String path
) {
556 final Iterable
<TraceTypeHelper
> traceTypeHelpers
= getTraceTypeHelpers();
557 for (TraceTypeHelper traceTypeHelper
: traceTypeHelpers
) {
558 if (traceTypeHelper
.isDirectoryTraceType() &&
559 (traceTypeHelper
.validate(path
).getSeverity() != IStatus
.ERROR
)) {
569 * @return <code>true</code> if it is a directory trace type,
570 * <code>false</code> otherwise
572 public static boolean isDirectoryTraceType(String traceType
) {
573 if (traceType
!= null) {
574 TraceTypeHelper traceTypeHelper
= getTraceType(traceType
);
575 if (traceTypeHelper
!= null) {
576 return traceTypeHelper
.isDirectoryTraceType();
580 throw new IllegalArgumentException("Invalid trace type string: " + traceType
); //$NON-NLS-1$
584 * Get the trace type id for a resource
588 * @return the trace type id or null if it is not set
589 * @throws CoreException
590 * if the trace type id cannot be accessed
592 public static String
getTraceTypeId(IResource resource
) throws CoreException
{
593 String traceTypeId
= resource
.getPersistentProperties().get(TmfCommonConstants
.TRACETYPE
);
594 return buildCompatibilityTraceTypeId(traceTypeId
);
598 * This methods builds a trace type ID from a given ID taking into
599 * consideration any format changes that were done for the IDs of custom
600 * text or XML traces. For example, such format change took place when
601 * moving to Trace Compass. Trace type IDs that are part of the plug-in
602 * extension for trace types won't be changed.
604 * This method is useful for IDs that were persisted in the workspace before
605 * the format changes (e.g. in the persistent properties of a trace
608 * It ensures backwards compatibility of the workspace for custom text and
612 * the legacy trace type ID
613 * @return the trace type ID in Trace Compass format
615 public static String
buildCompatibilityTraceTypeId(String traceTypeId
) {
616 // Fix custom trace type id with old class name or without category name
617 // for backward compatibility
618 if (traceTypeId
!= null) {
619 String newTraceType
= CustomTxtTrace
.buildCompatibilityTraceTypeId(traceTypeId
);
620 if (newTraceType
.equals(traceTypeId
)) {
621 newTraceType
= CustomXmlTrace
.buildCompatibilityTraceTypeId(traceTypeId
);
629 * This method figures out the trace type of a given trace.
632 * The path of trace to import (file or directory for directory traces)
633 * @param traceTypeHint
634 * the ID of a trace (like "o.e.l.specifictrace" )
635 * @return a list of {@link TraceTypeHelper} sorted by confidence (highest first)
637 * @throws TmfTraceImportException
638 * if there are errors in the trace file or no trace type found
639 * for a directory trace
642 public static @NonNull List
<TraceTypeHelper
> selectTraceType(String path
, String traceTypeHint
) throws TmfTraceImportException
{
644 Comparator
<Pair
<Integer
, TraceTypeHelper
>> comparator
= new Comparator
<Pair
<Integer
, TraceTypeHelper
>>() {
646 public int compare(Pair
<Integer
, TraceTypeHelper
> o1
, Pair
<Integer
, TraceTypeHelper
> o2
) {
647 int res
= -o1
.getFirst().compareTo(o2
.getFirst()); // invert so that highest confidence is first
649 res
= o1
.getSecond().getName().compareTo(o2
.getSecond().getName());
655 TreeSet
<Pair
<Integer
, TraceTypeHelper
>> validCandidates
= new TreeSet
<>(comparator
);
656 final Iterable
<TraceTypeHelper
> traceTypeHelpers
= TmfTraceType
.getTraceTypeHelpers();
657 for (TraceTypeHelper traceTypeHelper
: traceTypeHelpers
) {
658 if (!traceTypeHelper
.isEnabled() || traceTypeHelper
.isExperimentType()) {
661 int confidence
= traceTypeHelper
.validateWithConfidence(path
);
662 if (confidence
>= 0) {
663 // insert in the tree map, ordered by confidence (highest confidence first) then name
664 Pair
<Integer
, TraceTypeHelper
> element
= new Pair
<>(confidence
, traceTypeHelper
);
665 validCandidates
.add(element
);
669 List
<TraceTypeHelper
> returned
= new ArrayList
<>();
670 if (validCandidates
.isEmpty()) {
671 File traceFile
= new File(path
);
672 if (traceFile
.isFile()) {
675 final String errorMsg
= NLS
.bind(Messages
.TmfOpenTraceHelper_NoTraceTypeMatch
, path
);
676 throw new TmfTraceImportException(errorMsg
);
679 if (validCandidates
.size() != 1) {
680 List
<Pair
<Integer
, TraceTypeHelper
>> candidates
= new ArrayList
<>(validCandidates
);
681 List
<Pair
<Integer
, TraceTypeHelper
>> reducedCandidates
= reduce(candidates
);
682 for (Pair
<Integer
, TraceTypeHelper
> candidatePair
: reducedCandidates
) {
683 TraceTypeHelper candidate
= candidatePair
.getSecond();
684 if (candidate
.getTraceTypeId().equals(traceTypeHint
)) {
685 returned
.add(candidate
);
689 if (returned
.size() == 0) {
690 if (reducedCandidates
.size() == 0) {
691 throw new TmfTraceImportException("Error reducing trace type candidates"); //$NON-NLS-1$
692 } else if (reducedCandidates
.size() == 1) {
693 // Don't select the trace type if it has the lowest confidence
694 if (reducedCandidates
.get(0).getFirst() > 0) {
695 returned
.add(reducedCandidates
.get(0).getSecond());
698 for (Pair
<Integer
, TraceTypeHelper
> candidatePair
: reducedCandidates
) {
699 // Don't select the trace type if it has the lowest confidence
700 if (candidatePair
.getFirst() > 0) {
701 returned
.add(candidatePair
.getSecond());
707 // Don't select the trace type if it has the lowest confidence
708 if (validCandidates
.first().getFirst() > 0) {
709 returned
.add(validCandidates
.first().getSecond());
715 private static List
<Pair
<Integer
, TraceTypeHelper
>> reduce(List
<Pair
<Integer
, TraceTypeHelper
>> candidates
) {
716 List
<Pair
<Integer
, TraceTypeHelper
>> retVal
= new ArrayList
<>();
718 // get all the tracetypes that are unique in that stage
719 for (Pair
<Integer
, TraceTypeHelper
> candidatePair
: candidates
) {
720 TraceTypeHelper candidate
= candidatePair
.getSecond();
721 if (isUnique(candidate
, candidates
)) {
722 retVal
.add(candidatePair
);
729 * Only return the leaves of the trace types. Ignore custom trace types.
731 private static boolean isUnique(TraceTypeHelper trace
, List
<Pair
<Integer
, TraceTypeHelper
>> set
) {
732 if (trace
.getTraceClass().equals(CustomTxtTrace
.class) ||
733 trace
.getTraceClass().equals(CustomXmlTrace
.class)) {
736 // check if the trace type is the leaf. we make an instance of the trace
737 // type and if it is only an instance of itself, it is a leaf
738 final ITmfTrace tmfTrace
= trace
.getTrace();
740 for (Pair
<Integer
, TraceTypeHelper
> child
: set
) {
741 final ITmfTrace traceCandidate
= child
.getSecond().getTrace();
742 if (tmfTrace
.getClass().isInstance(traceCandidate
)) {