tmf: fix regression in trace type detection
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / project / model / TmfTraceType.java
CommitLineData
4bf17f4a 1/*******************************************************************************
281def42 2 * Copyright (c) 2011, 2016 Ericsson, École Polytechnique de Montréal
cfd22ad0 3 *
4bf17f4a 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
cfd22ad0 8 *
4bf17f4a 9 * Contributors:
10 * Patrick Tasse - Initial API and implementation
d04ec5a7 11 * Matthew Khouzam - Added import functionalities
1ec2ca01 12 * Geneviève Bastien - Added support for experiment types
c9b31f60 13 * Bernd Hufmann - Updated custom trace type ID handling
4bf17f4a 14 *******************************************************************************/
15
2bdf0193 16package org.eclipse.tracecompass.tmf.core.project.model;
4bf17f4a 17
281def42 18import java.io.File;
d04ec5a7 19import java.util.ArrayList;
252c602c
BH
20import java.util.Collections;
21import java.util.Comparator;
d04ec5a7 22import java.util.HashMap;
d04ec5a7 23import java.util.LinkedHashMap;
4bf17f4a 24import java.util.LinkedList;
25import java.util.List;
d04ec5a7 26import java.util.Map;
88424bb7 27import java.util.Map.Entry;
281def42 28import java.util.TreeSet;
4bf17f4a 29
4b3b667b 30import org.eclipse.core.resources.IResource;
05627bda 31import org.eclipse.core.runtime.CoreException;
4bf17f4a 32import org.eclipse.core.runtime.IConfigurationElement;
d16bb0dd 33import org.eclipse.core.runtime.IStatus;
4bf17f4a 34import org.eclipse.core.runtime.Platform;
281def42
BH
35import org.eclipse.jdt.annotation.NonNull;
36import org.eclipse.osgi.util.NLS;
d77f31da 37import org.eclipse.tracecompass.internal.tmf.core.Activator;
281def42 38import org.eclipse.tracecompass.internal.tmf.core.project.model.Messages;
2bdf0193
AM
39import org.eclipse.tracecompass.tmf.core.TmfCommonConstants;
40import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTrace;
41import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition;
42import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTrace;
43import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition;
44import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
45import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
281def42 46import org.eclipse.tracecompass.tmf.core.util.Pair;
4bf17f4a 47
b544077e 48/**
d04ec5a7
MK
49 * Utility class for accessing TMF trace type extensions from the platform's
50 * extensions registry.
cfd22ad0 51 *
b544077e 52 * @author Patrick Tasse
d04ec5a7 53 * @author Matthew Khouzam
b544077e 54 */
d04ec5a7 55public final class TmfTraceType {
4bf17f4a 56
a4a116c3
PT
57 // ------------------------------------------------------------------
58 // Constants
59 // ------------------------------------------------------------------
60
47aafe74 61 /** Extension point ID */
a926c25c 62 public static final String TMF_TRACE_TYPE_ID = "org.eclipse.linuxtools.tmf.core.tracetype"; //$NON-NLS-1$
4bf17f4a 63
47aafe74 64 /** Extension point element 'Category' */
4bf17f4a 65 public static final String CATEGORY_ELEM = "category"; //$NON-NLS-1$
47aafe74
AM
66
67 /** Extension point element 'Type' */
4bf17f4a 68 public static final String TYPE_ELEM = "type"; //$NON-NLS-1$
47aafe74 69
1ec2ca01
GB
70 /** Extension point element 'Experiment' */
71 public static final String EXPERIMENT_ELEM = "experiment"; //$NON-NLS-1$
72
47aafe74 73 /** Extension point attribute 'ID' */
4bf17f4a 74 public static final String ID_ATTR = "id"; //$NON-NLS-1$
47aafe74
AM
75
76 /** Extension point attribute 'name' */
4bf17f4a 77 public static final String NAME_ATTR = "name"; //$NON-NLS-1$
47aafe74
AM
78
79 /** Extension point attribute 'category' */
4bf17f4a 80 public static final String CATEGORY_ATTR = "category"; //$NON-NLS-1$
47aafe74
AM
81
82 /** Extension point attribute 'trace_type' */
4bf17f4a 83 public static final String TRACE_TYPE_ATTR = "trace_type"; //$NON-NLS-1$
47aafe74
AM
84
85 /** Extension point attribute 'event_type' */
4bf17f4a 86 public static final String EVENT_TYPE_ATTR = "event_type"; //$NON-NLS-1$
47aafe74 87
1ec2ca01
GB
88 /** Extension point attribute 'experiment_type' */
89 public static final String EXPERIMENT_TYPE_ATTR = "experiment_type"; //$NON-NLS-1$
90
d8aba2e2
BH
91 /** Extension point attribute 'isDirectory' */
92 public static final String IS_DIR_ATTR = "isDirectory"; //$NON-NLS-1$
93
1ec2ca01
GB
94 /** Default experiment type */
95 public static final String DEFAULT_EXPERIMENT_TYPE = "org.eclipse.linuxtools.tmf.core.experiment.generic"; //$NON-NLS-1$
96
d04ec5a7
MK
97 // The mapping of available trace type IDs to their corresponding
98 // configuration element
a4a116c3
PT
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, TraceTypeHelper> TRACE_TYPES = new LinkedHashMap<>();
d04ec5a7 102
a4a116c3
PT
103 static {
104 populateCategoriesAndTraceTypes();
105 populateCustomTraceTypes();
106 }
d04ec5a7 107
376fdfbd
GB
108 /**
109 * Enum to say whether a type applies to a trace or experiment
110 *
111 * @author Geneviève Bastien
112 */
113 public enum TraceElementType {
114 /** Trace type applies to trace */
115 TRACE,
116 /** Trace type applies to experiment */
117 EXPERIMENT,
118 }
119
a4a116c3
PT
120 // ------------------------------------------------------------------
121 // Constructor
122 // ------------------------------------------------------------------
123
124 private TmfTraceType() {
125 }
126
127 // ------------------------------------------------------------------
128 // Operations
129 // ------------------------------------------------------------------
130
d04ec5a7
MK
131 /**
132 * Retrieves the category name from the platform extension registry based on
133 * the category ID
134 *
135 * @param categoryId
136 * The category ID
b544077e
BH
137 * @return the category name or empty string if not found
138 */
4bf17f4a 139 public static String getCategoryName(String categoryId) {
140 IConfigurationElement[] elements = Platform.getExtensionRegistry()
141 .getConfigurationElementsFor(TMF_TRACE_TYPE_ID);
142 for (IConfigurationElement element : elements) {
09154cfe 143 if (element.getName().equals(CATEGORY_ELEM) && element.getAttribute(ID_ATTR).equals(categoryId)) {
4bf17f4a 144 return element.getAttribute(NAME_ATTR);
145 }
146 }
147 return ""; //$NON-NLS-1$
148 }
149
b544077e 150 /**
cfd22ad0 151 * Retrieves all configuration elements from the platform extension registry
376fdfbd 152 * for the trace type extension that apply to traces and not experiments.
cfd22ad0
MD
153 *
154 * @return an array of trace type configuration elements
b544077e 155 */
4bf17f4a 156 public static IConfigurationElement[] getTypeElements() {
157 IConfigurationElement[] elements = Platform.getExtensionRegistry()
158 .getConfigurationElementsFor(TMF_TRACE_TYPE_ID);
507b1336 159 List<IConfigurationElement> typeElements = new LinkedList<>();
4bf17f4a 160 for (IConfigurationElement element : elements) {
161 if (element.getName().equals(TYPE_ELEM)) {
162 typeElements.add(element);
163 }
164 }
beae214a 165 return typeElements.toArray(new IConfigurationElement[typeElements.size()]);
4bf17f4a 166 }
d04ec5a7 167
47aafe74
AM
168 /**
169 * Get an iterable view of the existing trace type IDs.
170 *
171 * @return The currently registered trace type IDs
172 */
a4a116c3
PT
173 public static Iterable<String> getTraceTypeIDs() {
174 return TRACE_TYPES.keySet();
47aafe74
AM
175 }
176
252c602c
BH
177 /**
178 * Get an iterable view of the existing trace type helpers.
179 *
180 * @return The currently registered trace type helpers
181 */
a4a116c3
PT
182 public static Iterable<TraceTypeHelper> getTraceTypeHelpers() {
183 return TRACE_TYPES.values();
252c602c
BH
184 }
185
d04ec5a7 186 /**
2b0005f0 187 * Returns a list of trace type labels "category : name", ...
d04ec5a7 188 *
376fdfbd
GB
189 * Returns only trace types, not experiment types
190 *
2b0005f0 191 * @return a list of trace type labels
d04ec5a7 192 */
a4a116c3 193 public static String[] getAvailableTraceTypes() {
252c602c
BH
194 return getAvailableTraceTypes(null);
195 }
196
197 /**
88424bb7
MK
198 * Returns a list of trace type labels "category : name", ... sorted by
199 * given comparator.
252c602c 200 *
376fdfbd
GB
201 * Returns only trace types, not experiment types
202 *
252c602c
BH
203 * @param comparator
204 * Comparator class (type String) or null for alphabetical order.
88424bb7
MK
205 * @return a list of trace type labels sorted according to the given
206 * comparator
252c602c 207 */
a4a116c3 208 public static String[] getAvailableTraceTypes(Comparator<String> comparator) {
d04ec5a7
MK
209
210 // Generate the list of Category:TraceType to populate the ComboBox
507b1336 211 List<String> traceTypes = new ArrayList<>();
d04ec5a7 212
88424bb7 213 for (TraceTypeHelper tt : TRACE_TYPES.values()) {
376fdfbd 214 if (!tt.isExperimentType()) {
2b0005f0 215 traceTypes.add(tt.getLabel());
376fdfbd 216 }
d04ec5a7 217 }
d04ec5a7 218
252c602c
BH
219 if (comparator == null) {
220 Collections.sort(traceTypes);
221 } else {
222 Collections.sort(traceTypes, comparator);
223 }
224
d04ec5a7
MK
225 // Format result
226 return traceTypes.toArray(new String[traceTypes.size()]);
227 }
228
229 /**
d04ec5a7
MK
230 * Gets all the custom trace types
231 *
232 * @return the list of custom trace types
d04ec5a7 233 */
52885aeb
PT
234 public static List<String> getCustomTraceTypes() {
235
507b1336 236 List<String> traceTypes = new ArrayList<>();
52885aeb
PT
237 for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {
238 String traceTypeName = def.definitionName;
239 traceTypes.add(traceTypeName);
240 }
241 for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) {
242 String traceTypeName = def.definitionName;
243 traceTypes.add(traceTypeName);
d04ec5a7 244 }
52885aeb
PT
245 return traceTypes;
246 }
d04ec5a7 247
a4a116c3 248 private static void populateCustomTraceTypes() {
d04ec5a7
MK
249 // add the custom trace types
250 for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {
2b0005f0
PT
251 CustomTxtTrace trace = new CustomTxtTrace(def);
252 String traceTypeId = trace.getTraceTypeId();
4b3b667b 253 TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, def.categoryName, def.definitionName, trace, false, TraceElementType.TRACE);
a4a116c3 254 TRACE_TYPES.put(traceTypeId, tt);
88424bb7
MK
255 // Deregister trace as signal handler because it is only used for
256 // validation
72807127 257 TmfSignalManager.deregister(trace);
d04ec5a7
MK
258 }
259 for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) {
2b0005f0
PT
260 CustomXmlTrace trace = new CustomXmlTrace(def);
261 String traceTypeId = trace.getTraceTypeId();
4b3b667b 262 TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, def.categoryName, def.definitionName, trace, false, TraceElementType.TRACE);
a4a116c3 263 TRACE_TYPES.put(traceTypeId, tt);
88424bb7
MK
264 // Deregister trace as signal handler because it is only used for
265 // validation
72807127 266 TmfSignalManager.deregister(trace);
d04ec5a7 267 }
52885aeb
PT
268 }
269
270 /**
271 * Add or replace a custom trace type
272 *
4b3b667b
PT
273 * @param traceClass
274 * The custom trace class, either {@link CustomTxtTrace} or
275 * {@link CustomXmlTrace}
276 * @param category
277 * The custom parser category
278 * @param definitionName
279 * The custom parser definition name to add or replace
280 */
281 public static void addCustomTraceType(Class<? extends ITmfTrace> traceClass, String category, String definitionName) {
52885aeb 282 String traceTypeId = null;
c9b31f60 283 ITmfTrace trace = null;
52885aeb 284
4b3b667b 285 if (traceClass.equals(CustomTxtTrace.class)) {
332527a4 286 CustomTxtTraceDefinition def = CustomTxtTraceDefinition.load(category, definitionName);
52885aeb
PT
287 if (def != null) {
288 trace = new CustomTxtTrace(def);
2b0005f0 289 traceTypeId = trace.getTraceTypeId();
52885aeb 290 }
4b3b667b 291 } else if (traceClass.equals(CustomXmlTrace.class)) {
332527a4 292 CustomXmlTraceDefinition def = CustomXmlTraceDefinition.load(category, definitionName);
52885aeb
PT
293 if (def != null) {
294 trace = new CustomXmlTrace(def);
2b0005f0 295 traceTypeId = trace.getTraceTypeId();
52885aeb
PT
296 }
297 }
298
299 if (traceTypeId != null && trace != null) {
a4a116c3 300 TraceTypeHelper helper = TRACE_TYPES.get(traceTypeId);
52885aeb
PT
301 if (helper != null) {
302 helper.getTrace().dispose();
303 }
376fdfbd 304 TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, category, definitionName, trace, false, TraceElementType.TRACE);
a4a116c3 305 TRACE_TYPES.put(traceTypeId, tt);
88424bb7
MK
306 // Deregister trace as signal handler because it is only used for
307 // validation
52885aeb
PT
308 TmfSignalManager.deregister(trace);
309 }
310 }
311
4b3b667b
PT
312 /**
313 * Remove a custom trace type
314 *
315 * @param traceClass
316 * The custom trace class, either {@link CustomTxtTrace} or
317 * {@link CustomXmlTrace}
318 * @param category
319 * The custom parser category
320 * @param definitionName
321 * The custom parser definition name to add or replace
322 */
323 public static void removeCustomTraceType(Class<? extends ITmfTrace> traceClass, String category, String definitionName) {
c9b31f60
BH
324 String traceTypeId = null;
325 if (traceClass.equals(CustomTxtTrace.class)) {
326 traceTypeId = CustomTxtTrace.buildTraceTypeId(category, definitionName);
327 } else if (traceClass.equals(CustomXmlTrace.class)) {
328 traceTypeId = CustomXmlTrace.buildTraceTypeId(category, definitionName);
329 }
330 if (traceTypeId != null) {
331 TraceTypeHelper helper = TRACE_TYPES.remove(traceTypeId);
332 if (helper != null) {
333 helper.getTrace().dispose();
334 }
52885aeb 335 }
d04ec5a7
MK
336 }
337
338 /**
339 * Gets a trace type for a given canonical id
340 *
341 * @param id
342 * the ID of the trace
343 * @return the return type
d04ec5a7 344 */
a4a116c3
PT
345 public static TraceTypeHelper getTraceType(String id) {
346 return TRACE_TYPES.get(id);
d04ec5a7
MK
347 }
348
a4a116c3
PT
349 private static void populateCategoriesAndTraceTypes() {
350 if (TRACE_TYPES.isEmpty()) {
d04ec5a7
MK
351 // Populate the Categories and Trace Types
352 IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType.TMF_TRACE_TYPE_ID);
353 for (IConfigurationElement ce : config) {
354 String elementName = ce.getName();
355 if (elementName.equals(TmfTraceType.TYPE_ELEM)) {
356 String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR);
a4a116c3 357 TRACE_TYPE_ATTRIBUTES.put(traceTypeId, ce);
d04ec5a7
MK
358 } else if (elementName.equals(TmfTraceType.CATEGORY_ELEM)) {
359 String categoryId = ce.getAttribute(TmfTraceType.ID_ATTR);
a4a116c3 360 TRACE_CATEGORIES.put(categoryId, ce);
376fdfbd
GB
361 } else if (elementName.equals(TmfTraceType.EXPERIMENT_ELEM)) {
362 String experimentTypeId = ce.getAttribute(TmfTraceType.ID_ATTR);
a4a116c3 363 TRACE_TYPE_ATTRIBUTES.put(experimentTypeId, ce);
d04ec5a7
MK
364 }
365 }
366 // create the trace types
88424bb7
MK
367 for (Entry<String, IConfigurationElement> entry : TRACE_TYPE_ATTRIBUTES.entrySet()) {
368 IConfigurationElement ce = entry.getValue();
d04ec5a7
MK
369 final String category = getCategory(ce);
370 final String attribute = ce.getAttribute(TmfTraceType.NAME_ATTR);
371 ITmfTrace trace = null;
376fdfbd 372 TraceElementType elementType = TraceElementType.TRACE;
d04ec5a7 373 try {
376fdfbd
GB
374 if (ce.getName().equals(TmfTraceType.TYPE_ELEM)) {
375 trace = (ITmfTrace) ce.createExecutableExtension(TmfTraceType.TRACE_TYPE_ATTR);
376 } else if (ce.getName().equals(TmfTraceType.EXPERIMENT_ELEM)) {
377 trace = (ITmfTrace) ce.createExecutableExtension(TmfTraceType.EXPERIMENT_TYPE_ATTR);
378 elementType = TraceElementType.EXPERIMENT;
379 }
a8ddd783
GB
380 if (trace == null) {
381 break;
376fdfbd 382 }
a8ddd783
GB
383 // Deregister trace as signal handler because it is only
384 // used for validation
385 TmfSignalManager.deregister(trace);
386
387 final String dirString = ce.getAttribute(TmfTraceType.IS_DIR_ATTR);
388 boolean isDir = Boolean.parseBoolean(dirString);
389
88424bb7 390 final String typeId = entry.getKey();
a8ddd783 391 TraceTypeHelper tt = new TraceTypeHelper(typeId, category, attribute, trace, isDir, elementType);
a4a116c3 392 TRACE_TYPES.put(typeId, tt);
d04ec5a7 393 } catch (CoreException e) {
d77f31da 394 Activator.logError("Unexpected error during populating trace types", e); //$NON-NLS-1$
d04ec5a7 395 }
d8aba2e2 396
d04ec5a7
MK
397 }
398 }
399 }
400
a4a116c3 401 private static String getCategory(IConfigurationElement ce) {
d04ec5a7
MK
402 final String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR);
403 if (categoryId != null) {
a4a116c3 404 IConfigurationElement category = TRACE_CATEGORIES.get(categoryId);
d04ec5a7
MK
405 if (category != null && !category.getName().equals("")) { //$NON-NLS-1$
406 return category.getAttribute(TmfTraceType.NAME_ATTR);
407 }
408 }
2b0005f0 409 return ""; //$NON-NLS-1$
d04ec5a7
MK
410 }
411
412 /**
413 * Returns the list of trace categories
414 *
415 * @return the list of trace categories
d04ec5a7 416 */
a4a116c3 417 public static List<String> getTraceCategories() {
507b1336 418 List<String> categoryNames = new ArrayList<>();
a94e5eff
JCK
419 for (TraceTypeHelper helper : TRACE_TYPES.values()) {
420 final String categoryName = helper.getCategoryName();
d04ec5a7
MK
421 if (!categoryNames.contains(categoryName)) {
422 categoryNames.add(categoryName);
423 }
424 }
425 return categoryNames;
426 }
427
428 /**
376fdfbd
GB
429 * Get the trace type helper classes from category name. Return only the
430 * trace types, not the experiment types
d04ec5a7 431 *
cd9821de
BH
432 * @param categoryName
433 * the categoryName to lookup
434 * @return a list of trace type helper classes {@link TraceTypeHelper}
d04ec5a7 435 */
a4a116c3 436 public static List<TraceTypeHelper> getTraceTypes(String categoryName) {
507b1336 437 List<TraceTypeHelper> traceNames = new ArrayList<>();
88424bb7
MK
438 for (TraceTypeHelper traceTypeHelper : TRACE_TYPES.values()) {
439 if (!traceTypeHelper.isExperimentType()) {
440 final String storedCategoryName = traceTypeHelper.getCategoryName();
376fdfbd 441 if (storedCategoryName.equals(categoryName)) {
88424bb7 442 traceNames.add(traceTypeHelper);
376fdfbd 443 }
d04ec5a7
MK
444 }
445 }
446 return traceNames;
447 }
448
d04ec5a7
MK
449 /**
450 * Validate a trace type
451 *
452 * @param traceTypeName
453 * the trace category (canonical name)
454 * @param fileName
455 * the file name (and path)
456 * @return true if the trace is of a valid type
d04ec5a7 457 */
a4a116c3 458 public static boolean validate(String traceTypeName, String fileName) {
76fccfb0 459 if (traceTypeName != null && !traceTypeName.isEmpty()) {
a4a116c3 460 final TraceTypeHelper traceTypeHelper = TRACE_TYPES.get(traceTypeName);
0621dbae 461 if (traceTypeHelper == null || !traceTypeHelper.validate(fileName).isOK()) {
d04ec5a7
MK
462 return false;
463 }
464 }
465 return true;
466 }
467
468 /**
469 * Validate a trace
470 *
471 * @param traceToValidate
472 * the trace category (canonical name)
473 * @return true if the trace is of a valid type
d04ec5a7 474 */
a4a116c3 475 public static boolean validate(TraceValidationHelper traceToValidate) {
d04ec5a7
MK
476 return validate(traceToValidate.getTraceType(), traceToValidate.getTraceToScan());
477 }
478
d04ec5a7
MK
479 /**
480 * Get a configuration element for a given name
481 *
482 * @param traceType
483 * the name canonical
484 * @return the configuration element, can be null
d04ec5a7 485 */
a4a116c3
PT
486 public static IConfigurationElement getTraceAttributes(String traceType) {
487 return TRACE_TYPE_ATTRIBUTES.get(traceType);
d04ec5a7
MK
488 }
489
490 /**
2b0005f0 491 * Find the id of a trace type by its label "category : name"
d04ec5a7 492 *
2b0005f0
PT
493 * @param label
494 * the trace type label
495 * @return the trace type id
d04ec5a7 496 */
2b0005f0 497 public static String getTraceTypeId(String label) {
88424bb7
MK
498 for (Entry<String, TraceTypeHelper> entry : TRACE_TYPES.entrySet()) {
499 if (entry.getValue().getLabel().equals(label)) {
500 return entry.getKey();
d04ec5a7
MK
501 }
502 }
503 return null;
504 }
76fccfb0 505
252c602c 506 /**
d8aba2e2 507 * Checks if a trace is a valid directory trace
88424bb7 508 *
d8aba2e2 509 * @param path
252c602c 510 * the file name (and path)
88424bb7
MK
511 * @return <code>true</code> if the trace is a valid directory trace else
512 * <code>false</code>
252c602c 513 */
a4a116c3 514 public static boolean isDirectoryTrace(String path) {
d8aba2e2
BH
515 final Iterable<TraceTypeHelper> traceTypeHelpers = getTraceTypeHelpers();
516 for (TraceTypeHelper traceTypeHelper : traceTypeHelpers) {
517 if (traceTypeHelper.isDirectoryTraceType() &&
d16bb0dd 518 (traceTypeHelper.validate(path).getSeverity() != IStatus.ERROR)) {
d8aba2e2
BH
519 return true;
520 }
252c602c
BH
521 }
522 return false;
523 }
524
525 /**
526 * @param traceType
88424bb7
MK
527 * the trace type
528 * @return <code>true</code> it is a directory trace type else else
529 * <code>false</code>
252c602c 530 */
a4a116c3 531 public static boolean isDirectoryTraceType(String traceType) {
d8aba2e2
BH
532 if (traceType != null) {
533 TraceTypeHelper traceTypeHelper = getTraceType(traceType);
534 if (traceTypeHelper != null) {
535 return traceTypeHelper.isDirectoryTraceType();
536 }
1dec1830 537 return false;
252c602c 538 }
d8aba2e2 539 throw new IllegalArgumentException("Invalid trace type string: " + traceType); //$NON-NLS-1$
252c602c 540 }
d8aba2e2 541
4b3b667b
PT
542 /**
543 * Get the trace type id for a resource
544 *
545 * @param resource
546 * the resource
547 * @return the trace type id or null if it is not set
548 * @throws CoreException
549 * if the trace type id cannot be accessed
4b3b667b
PT
550 */
551 public static String getTraceTypeId(IResource resource) throws CoreException {
552 String traceTypeId = resource.getPersistentProperties().get(TmfCommonConstants.TRACETYPE);
e86f7ac4
BH
553 return buildCompatibilityTraceTypeId(traceTypeId);
554 }
555
556 /**
557 * This methods builds a trace type ID from a given ID taking into
558 * consideration any format changes that were done for the IDs of custom
559 * text or XML traces. For example, such format change took place when
560 * moving to Trace Compass. Trace type IDs that are part of the plug-in
561 * extension for trace types won't be changed.
562 *
563 * This method is useful for IDs that were persisted in the workspace before
564 * the format changes (e.g. in the persistent properties of a trace
565 * resource).
566 *
567 * It ensures backwards compatibility of the workspace for custom text and
568 * XML traces.
569 *
570 * @param traceTypeId
571 * the legacy trace type ID
572 * @return the trace type ID in Trace Compass format
573 */
574 public static String buildCompatibilityTraceTypeId(String traceTypeId) {
88424bb7
MK
575 // Fix custom trace type id with old class name or without category name
576 // for backward compatibility
4b3b667b 577 if (traceTypeId != null) {
c9b31f60
BH
578 String newTraceType = CustomTxtTrace.buildCompatibilityTraceTypeId(traceTypeId);
579 if (newTraceType.equals(traceTypeId)) {
580 newTraceType = CustomXmlTrace.buildCompatibilityTraceTypeId(traceTypeId);
4b3b667b 581 }
c9b31f60 582 return newTraceType;
4b3b667b
PT
583 }
584 return traceTypeId;
585 }
c9b31f60 586
281def42
BH
587 /**
588 * This method figures out the trace type of a given trace.
589 *
590 * @param path
591 * The path of trace to import (file or directory for directory traces)
592 * @param traceTypeHint
593 * the ID of a trace (like "o.e.l.specifictrace" )
594 * @return a list of {@link TraceTypeHelper} sorted by confidence (highest first)
595 *
596 * @throws TmfTraceImportException
597 * if there are errors in the trace file or no trace type found
598 * for a directory trace
599 * @since 2.0
600 */
601 public static @NonNull List<TraceTypeHelper> selectTraceType(String path, String traceTypeHint) throws TmfTraceImportException {
602
603 Comparator<Pair<Integer, TraceTypeHelper>> comparator = new Comparator<Pair<Integer, TraceTypeHelper>>() {
604 @Override
605 public int compare(Pair<Integer, TraceTypeHelper> o1, Pair<Integer, TraceTypeHelper> o2) {
606 int res = -o1.getFirst().compareTo(o2.getFirst()); // invert so that highest confidence is first
607 if (res == 0) {
608 res = o1.getSecond().getName().compareTo(o2.getSecond().getName());
609 }
610 return res;
611 }
612 };
613
614 TreeSet<Pair<Integer, TraceTypeHelper>> validCandidates = new TreeSet<>(comparator);
615 final Iterable<TraceTypeHelper> traceTypeHelpers = TmfTraceType.getTraceTypeHelpers();
616 for (TraceTypeHelper traceTypeHelper : traceTypeHelpers) {
617 if (traceTypeHelper.isExperimentType()) {
618 continue;
619 }
620 int confidence = traceTypeHelper.validateWithConfidence(path);
621 if (confidence >= 0) {
622 // insert in the tree map, ordered by confidence (highest confidence first) then name
623 Pair<Integer, TraceTypeHelper> element = new Pair<>(confidence, traceTypeHelper);
624 validCandidates.add(element);
625 }
626 }
627
628 List<TraceTypeHelper> returned = new ArrayList<>();
629 if (validCandidates.isEmpty()) {
630 File traceFile = new File(path);
631 if (traceFile.isFile()) {
632 return returned;
633 }
634 final String errorMsg = NLS.bind(Messages.TmfOpenTraceHelper_NoTraceTypeMatch, path);
635 throw new TmfTraceImportException(errorMsg);
636 }
637
638 if (validCandidates.size() != 1) {
639 List<Pair<Integer, TraceTypeHelper>> candidates = new ArrayList<>(validCandidates);
640 List<Pair<Integer, TraceTypeHelper>> reducedCandidates = reduce(candidates);
641 for (Pair<Integer, TraceTypeHelper> candidatePair : reducedCandidates) {
642 TraceTypeHelper candidate = candidatePair.getSecond();
643 if (candidate.getTraceTypeId().equals(traceTypeHint)) {
644 returned.add(candidate);
645 break;
646 }
647 }
648 if (returned.size() == 0) {
649 if (reducedCandidates.size() == 0) {
650 throw new TmfTraceImportException("Error reducing trace type candidates"); //$NON-NLS-1$
651 } else if (reducedCandidates.size() == 1) {
652 // Don't select the trace type if it has the lowest confidence
653 if (reducedCandidates.get(0).getFirst() > 0) {
654 returned.add(reducedCandidates.get(0).getSecond());
655 }
656 } else {
657 for (Pair<Integer, TraceTypeHelper> candidatePair : reducedCandidates) {
68621ce0
BH
658 // Don't select the trace type if it has the lowest confidence
659 if (candidatePair.getFirst() > 0) {
660 returned.add(candidatePair.getSecond());
661 }
281def42
BH
662 }
663 }
664 }
665 } else {
666 // Don't select the trace type if it has the lowest confidence
667 if (validCandidates.first().getFirst() > 0) {
668 returned.add(validCandidates.first().getSecond());
669 }
670 }
671 return returned;
672 }
673
674 private static List<Pair<Integer, TraceTypeHelper>> reduce(List<Pair<Integer, TraceTypeHelper>> candidates) {
675 List<Pair<Integer, TraceTypeHelper>> retVal = new ArrayList<>();
676
677 // get all the tracetypes that are unique in that stage
678 for (Pair<Integer, TraceTypeHelper> candidatePair : candidates) {
679 TraceTypeHelper candidate = candidatePair.getSecond();
680 if (isUnique(candidate, candidates)) {
681 retVal.add(candidatePair);
682 }
683 }
684 return retVal;
685 }
686
687 /*
688 * Only return the leaves of the trace types. Ignore custom trace types.
689 */
690 private static boolean isUnique(TraceTypeHelper trace, List<Pair<Integer, TraceTypeHelper>> set) {
691 if (trace.getTraceClass().equals(CustomTxtTrace.class) ||
692 trace.getTraceClass().equals(CustomXmlTrace.class)) {
693 return true;
694 }
695 // check if the trace type is the leaf. we make an instance of the trace
696 // type and if it is only an instance of itself, it is a leaf
697 final ITmfTrace tmfTrace = trace.getTrace();
698 int count = -1;
699 for (Pair<Integer, TraceTypeHelper> child : set) {
700 final ITmfTrace traceCandidate = child.getSecond().getTrace();
701 if (tmfTrace.getClass().isInstance(traceCandidate)) {
702 count++;
703 }
704 }
705 return count == 0;
706 }
707
4bf17f4a 708}
This page took 0.127316 seconds and 5 git commands to generate.