Remove all existing @since annotations
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / project / model / TmfTraceType.java
1 /*******************************************************************************
2 * Copyright (c) 2011, 2015 Ericsson, École Polytechnique de Montréal
3 *
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
8 *
9 * Contributors:
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 *******************************************************************************/
15
16 package org.eclipse.tracecompass.tmf.core.project.model;
17
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.Comparator;
21 import java.util.HashMap;
22 import java.util.LinkedHashMap;
23 import java.util.LinkedList;
24 import java.util.List;
25 import java.util.Map;
26
27 import org.eclipse.core.resources.IResource;
28 import org.eclipse.core.runtime.CoreException;
29 import org.eclipse.core.runtime.IConfigurationElement;
30 import org.eclipse.core.runtime.Platform;
31 import org.eclipse.tracecompass.internal.tmf.core.Activator;
32 import org.eclipse.tracecompass.tmf.core.TmfCommonConstants;
33 import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTrace;
34 import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition;
35 import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTrace;
36 import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition;
37 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
38 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
39
40 /**
41 * Utility class for accessing TMF trace type extensions from the platform's
42 * extensions registry.
43 *
44 * @author Patrick Tasse
45 * @author Matthew Khouzam
46 */
47 public final class TmfTraceType {
48
49 // ------------------------------------------------------------------
50 // Constants
51 // ------------------------------------------------------------------
52
53 /** Extension point ID */
54 public static final String TMF_TRACE_TYPE_ID = "org.eclipse.linuxtools.tmf.core.tracetype"; //$NON-NLS-1$
55
56 /** Extension point element 'Category' */
57 public static final String CATEGORY_ELEM = "category"; //$NON-NLS-1$
58
59 /** Extension point element 'Type' */
60 public static final String TYPE_ELEM = "type"; //$NON-NLS-1$
61
62 /** Extension point element 'Experiment' */
63 public static final String EXPERIMENT_ELEM = "experiment"; //$NON-NLS-1$
64
65 /** Extension point attribute 'ID' */
66 public static final String ID_ATTR = "id"; //$NON-NLS-1$
67
68 /** Extension point attribute 'name' */
69 public static final String NAME_ATTR = "name"; //$NON-NLS-1$
70
71 /** Extension point attribute 'category' */
72 public static final String CATEGORY_ATTR = "category"; //$NON-NLS-1$
73
74 /** Extension point attribute 'trace_type' */
75 public static final String TRACE_TYPE_ATTR = "trace_type"; //$NON-NLS-1$
76
77 /** Extension point attribute 'event_type' */
78 public static final String EVENT_TYPE_ATTR = "event_type"; //$NON-NLS-1$
79
80 /** Extension point attribute 'experiment_type' */
81 public static final String EXPERIMENT_TYPE_ATTR = "experiment_type"; //$NON-NLS-1$
82
83 /** Extension point attribute 'isDirectory' */
84 public static final String IS_DIR_ATTR = "isDirectory"; //$NON-NLS-1$
85
86 /** Default experiment type */
87 public static final String DEFAULT_EXPERIMENT_TYPE = "org.eclipse.linuxtools.tmf.core.experiment.generic"; //$NON-NLS-1$
88
89 // The mapping of available trace type IDs to their corresponding
90 // configuration element
91 private static final Map<String, IConfigurationElement> TRACE_TYPE_ATTRIBUTES = new HashMap<>();
92 private static final Map<String, IConfigurationElement> TRACE_CATEGORIES = new HashMap<>();
93 private static final Map<String, TraceTypeHelper> TRACE_TYPES = new LinkedHashMap<>();
94
95 static {
96 populateCategoriesAndTraceTypes();
97 populateCustomTraceTypes();
98 }
99
100 /**
101 * Enum to say whether a type applies to a trace or experiment
102 *
103 * @author Geneviève Bastien
104 */
105 public enum TraceElementType {
106 /** Trace type applies to trace */
107 TRACE,
108 /** Trace type applies to experiment */
109 EXPERIMENT,
110 }
111
112 // ------------------------------------------------------------------
113 // Constructor
114 // ------------------------------------------------------------------
115
116 private TmfTraceType() {
117 }
118
119 // ------------------------------------------------------------------
120 // Operations
121 // ------------------------------------------------------------------
122
123 /**
124 * Retrieves the category name from the platform extension registry based on
125 * the category ID
126 *
127 * @param categoryId
128 * The category ID
129 * @return the category name or empty string if not found
130 */
131 public static String getCategoryName(String categoryId) {
132 IConfigurationElement[] elements = Platform.getExtensionRegistry()
133 .getConfigurationElementsFor(TMF_TRACE_TYPE_ID);
134 for (IConfigurationElement element : elements) {
135 if (element.getName().equals(CATEGORY_ELEM) && element.getAttribute(ID_ATTR).equals(categoryId)) {
136 return element.getAttribute(NAME_ATTR);
137 }
138 }
139 return ""; //$NON-NLS-1$
140 }
141
142 /**
143 * Retrieves all configuration elements from the platform extension registry
144 * for the trace type extension that apply to traces and not experiments.
145 *
146 * @return an array of trace type configuration elements
147 */
148 public static IConfigurationElement[] getTypeElements() {
149 IConfigurationElement[] elements = Platform.getExtensionRegistry()
150 .getConfigurationElementsFor(TMF_TRACE_TYPE_ID);
151 List<IConfigurationElement> typeElements = new LinkedList<>();
152 for (IConfigurationElement element : elements) {
153 if (element.getName().equals(TYPE_ELEM)) {
154 typeElements.add(element);
155 }
156 }
157 return typeElements.toArray(new IConfigurationElement[typeElements.size()]);
158 }
159
160 /**
161 * Get an iterable view of the existing trace type IDs.
162 *
163 * @return The currently registered trace type IDs
164 */
165 public static Iterable<String> getTraceTypeIDs() {
166 return TRACE_TYPES.keySet();
167 }
168
169 /**
170 * Get an iterable view of the existing trace type helpers.
171 *
172 * @return The currently registered trace type helpers
173 */
174 public static Iterable<TraceTypeHelper> getTraceTypeHelpers() {
175 return TRACE_TYPES.values();
176 }
177
178 /**
179 * Returns a list of trace type labels "category : name", ...
180 *
181 * Returns only trace types, not experiment types
182 *
183 * @return a list of trace type labels
184 */
185 public static String[] getAvailableTraceTypes() {
186 return getAvailableTraceTypes(null);
187 }
188
189 /**
190 * Returns a list of trace type labels "category : name", ... sorted by given comparator.
191 *
192 * Returns only trace types, not experiment types
193 *
194 * @param comparator
195 * Comparator class (type String) or null for alphabetical order.
196 * @return a list of trace type labels sorted according to the given comparator
197 */
198 public static String[] getAvailableTraceTypes(Comparator<String> comparator) {
199
200 // Generate the list of Category:TraceType to populate the ComboBox
201 List<String> traceTypes = new ArrayList<>();
202
203 for (String key : TRACE_TYPES.keySet()) {
204 TraceTypeHelper tt = TRACE_TYPES.get(key);
205 if (!tt.isExperimentType()) {
206 traceTypes.add(tt.getLabel());
207 }
208 }
209
210 if (comparator == null) {
211 Collections.sort(traceTypes);
212 } else {
213 Collections.sort(traceTypes, comparator);
214 }
215
216 // Format result
217 return traceTypes.toArray(new String[traceTypes.size()]);
218 }
219
220 /**
221 * Gets all the custom trace types
222 *
223 * @return the list of custom trace types
224 */
225 public static List<String> getCustomTraceTypes() {
226
227 List<String> traceTypes = new ArrayList<>();
228 for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {
229 String traceTypeName = def.definitionName;
230 traceTypes.add(traceTypeName);
231 }
232 for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) {
233 String traceTypeName = def.definitionName;
234 traceTypes.add(traceTypeName);
235 }
236 return traceTypes;
237 }
238
239 private static void populateCustomTraceTypes() {
240 // add the custom trace types
241 for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {
242 CustomTxtTrace trace = new CustomTxtTrace(def);
243 String traceTypeId = trace.getTraceTypeId();
244 TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, def.categoryName, def.definitionName, trace, false, TraceElementType.TRACE);
245 TRACE_TYPES.put(traceTypeId, tt);
246 // Deregister trace as signal handler because it is only used for validation
247 TmfSignalManager.deregister(trace);
248 }
249 for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) {
250 CustomXmlTrace trace = new CustomXmlTrace(def);
251 String traceTypeId = trace.getTraceTypeId();
252 TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, def.categoryName, def.definitionName, trace, false, TraceElementType.TRACE);
253 TRACE_TYPES.put(traceTypeId, tt);
254 // Deregister trace as signal handler because it is only used for validation
255 TmfSignalManager.deregister(trace);
256 }
257 }
258
259 /**
260 * Add or replace a custom trace type
261 *
262 * @param traceClass
263 * The custom trace class, either {@link CustomTxtTrace} or
264 * {@link CustomXmlTrace}
265 * @param category
266 * The custom parser category
267 * @param definitionName
268 * The custom parser definition name to add or replace
269 */
270 public static void addCustomTraceType(Class<? extends ITmfTrace> traceClass, String category, String definitionName) {
271 String traceTypeId = null;
272 ITmfTrace trace = null;
273
274 if (traceClass.equals(CustomTxtTrace.class)) {
275 CustomTxtTraceDefinition def = CustomTxtTraceDefinition.load(category, definitionName);
276 if (def != null) {
277 trace = new CustomTxtTrace(def);
278 traceTypeId = trace.getTraceTypeId();
279 }
280 } else if (traceClass.equals(CustomXmlTrace.class)) {
281 CustomXmlTraceDefinition def = CustomXmlTraceDefinition.load(category, definitionName);
282 if (def != null) {
283 trace = new CustomXmlTrace(def);
284 traceTypeId = trace.getTraceTypeId();
285 }
286 }
287
288 if (traceTypeId != null && trace != null) {
289 TraceTypeHelper helper = TRACE_TYPES.get(traceTypeId);
290 if (helper != null) {
291 helper.getTrace().dispose();
292 }
293 TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, category, definitionName, trace, false, TraceElementType.TRACE);
294 TRACE_TYPES.put(traceTypeId, tt);
295 // Deregister trace as signal handler because it is only used for validation
296 TmfSignalManager.deregister(trace);
297 }
298 }
299
300 /**
301 * Remove a custom trace type
302 *
303 * @param traceClass
304 * The custom trace class, either {@link CustomTxtTrace} or
305 * {@link CustomXmlTrace}
306 * @param category
307 * The custom parser category
308 * @param definitionName
309 * The custom parser definition name to add or replace
310 */
311 public static void removeCustomTraceType(Class<? extends ITmfTrace> traceClass, String category, String definitionName) {
312 String traceTypeId = null;
313 if (traceClass.equals(CustomTxtTrace.class)) {
314 traceTypeId = CustomTxtTrace.buildTraceTypeId(category, definitionName);
315 } else if (traceClass.equals(CustomXmlTrace.class)) {
316 traceTypeId = CustomXmlTrace.buildTraceTypeId(category, definitionName);
317 }
318 if (traceTypeId != null) {
319 TraceTypeHelper helper = TRACE_TYPES.remove(traceTypeId);
320 if (helper != null) {
321 helper.getTrace().dispose();
322 }
323 }
324 }
325
326 /**
327 * Gets a trace type for a given canonical id
328 *
329 * @param id
330 * the ID of the trace
331 * @return the return type
332 */
333 public static TraceTypeHelper getTraceType(String id) {
334 return TRACE_TYPES.get(id);
335 }
336
337 private static void populateCategoriesAndTraceTypes() {
338 if (TRACE_TYPES.isEmpty()) {
339 // Populate the Categories and Trace Types
340 IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType.TMF_TRACE_TYPE_ID);
341 for (IConfigurationElement ce : config) {
342 String elementName = ce.getName();
343 if (elementName.equals(TmfTraceType.TYPE_ELEM)) {
344 String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR);
345 TRACE_TYPE_ATTRIBUTES.put(traceTypeId, ce);
346 } else if (elementName.equals(TmfTraceType.CATEGORY_ELEM)) {
347 String categoryId = ce.getAttribute(TmfTraceType.ID_ATTR);
348 TRACE_CATEGORIES.put(categoryId, ce);
349 } else if (elementName.equals(TmfTraceType.EXPERIMENT_ELEM)) {
350 String experimentTypeId = ce.getAttribute(TmfTraceType.ID_ATTR);
351 TRACE_TYPE_ATTRIBUTES.put(experimentTypeId, ce);
352 }
353 }
354 // create the trace types
355 for (String typeId : TRACE_TYPE_ATTRIBUTES.keySet()) {
356 IConfigurationElement ce = TRACE_TYPE_ATTRIBUTES.get(typeId);
357 final String category = getCategory(ce);
358 final String attribute = ce.getAttribute(TmfTraceType.NAME_ATTR);
359 ITmfTrace trace = null;
360 TraceElementType elementType = TraceElementType.TRACE;
361 try {
362 if (ce.getName().equals(TmfTraceType.TYPE_ELEM)) {
363 trace = (ITmfTrace) ce.createExecutableExtension(TmfTraceType.TRACE_TYPE_ATTR);
364 } else if (ce.getName().equals(TmfTraceType.EXPERIMENT_ELEM)) {
365 trace = (ITmfTrace) ce.createExecutableExtension(TmfTraceType.EXPERIMENT_TYPE_ATTR);
366 elementType = TraceElementType.EXPERIMENT;
367 }
368 if (trace == null) {
369 break;
370 }
371 // Deregister trace as signal handler because it is only
372 // used for validation
373 TmfSignalManager.deregister(trace);
374
375 final String dirString = ce.getAttribute(TmfTraceType.IS_DIR_ATTR);
376 boolean isDir = Boolean.parseBoolean(dirString);
377
378 TraceTypeHelper tt = new TraceTypeHelper(typeId, category, attribute, trace, isDir, elementType);
379 TRACE_TYPES.put(typeId, tt);
380 } catch (CoreException e) {
381 Activator.logError("Unexpected error during populating trace types", e); //$NON-NLS-1$
382 }
383
384 }
385 }
386 }
387
388 private static String getCategory(IConfigurationElement ce) {
389 final String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR);
390 if (categoryId != null) {
391 IConfigurationElement category = TRACE_CATEGORIES.get(categoryId);
392 if (category != null && !category.getName().equals("")) { //$NON-NLS-1$
393 return category.getAttribute(TmfTraceType.NAME_ATTR);
394 }
395 }
396 return ""; //$NON-NLS-1$
397 }
398
399 /**
400 * Returns the list of trace categories
401 *
402 * @return the list of trace categories
403 */
404 public static List<String> getTraceCategories() {
405 List<String> categoryNames = new ArrayList<>();
406 for (String key : TRACE_TYPES.keySet()) {
407 final String categoryName = TRACE_TYPES.get(key).getCategoryName();
408 if (!categoryNames.contains(categoryName)) {
409 categoryNames.add(categoryName);
410 }
411 }
412 return categoryNames;
413 }
414
415 /**
416 * Get the trace type helper classes from category name. Return only the
417 * trace types, not the experiment types
418 *
419 * @param categoryName
420 * the categoryName to lookup
421 * @return a list of trace type helper classes {@link TraceTypeHelper}
422 */
423 public static List<TraceTypeHelper> getTraceTypes(String categoryName) {
424 List<TraceTypeHelper> traceNames = new ArrayList<>();
425 for (String key : TRACE_TYPES.keySet()) {
426 if (!TRACE_TYPES.get(key).isExperimentType()) {
427 final String storedCategoryName = TRACE_TYPES.get(key).getCategoryName();
428 if (storedCategoryName.equals(categoryName)) {
429 traceNames.add(TRACE_TYPES.get(key));
430 }
431 }
432 }
433 return traceNames;
434 }
435
436 /**
437 * Validate a trace type
438 *
439 * @param traceTypeName
440 * the trace category (canonical name)
441 * @param fileName
442 * the file name (and path)
443 * @return true if the trace is of a valid type
444 */
445 public static boolean validate(String traceTypeName, String fileName) {
446 if (traceTypeName != null && !traceTypeName.isEmpty()) {
447 final TraceTypeHelper traceTypeHelper = TRACE_TYPES.get(traceTypeName);
448 if (traceTypeHelper == null || !traceTypeHelper.validate(fileName).isOK()) {
449 return false;
450 }
451 }
452 return true;
453 }
454
455 /**
456 * Validate a trace
457 *
458 * @param traceToValidate
459 * the trace category (canonical name)
460 * @return true if the trace is of a valid type
461 */
462 public static boolean validate(TraceValidationHelper traceToValidate) {
463 return validate(traceToValidate.getTraceType(), traceToValidate.getTraceToScan());
464 }
465
466 /**
467 * Get a configuration element for a given name
468 *
469 * @param traceType
470 * the name canonical
471 * @return the configuration element, can be null
472 */
473 public static IConfigurationElement getTraceAttributes(String traceType) {
474 return TRACE_TYPE_ATTRIBUTES.get(traceType);
475 }
476
477 /**
478 * Find the id of a trace type by its label "category : name"
479 *
480 * @param label
481 * the trace type label
482 * @return the trace type id
483 */
484 public static String getTraceTypeId(String label) {
485 for (String key : TRACE_TYPES.keySet()) {
486 if (TRACE_TYPES.get(key).getLabel().equals(label)) {
487 return key;
488 }
489 }
490 return null;
491 }
492
493 /**
494 * Checks if a trace is a valid directory trace
495 * @param path
496 * the file name (and path)
497 * @return <code>true</code> if the trace is a valid directory trace else <code>false</code>
498 */
499 public static boolean isDirectoryTrace(String path) {
500 final Iterable<TraceTypeHelper> traceTypeHelpers = getTraceTypeHelpers();
501 for (TraceTypeHelper traceTypeHelper : traceTypeHelpers) {
502 if (traceTypeHelper.isDirectoryTraceType() &&
503 traceTypeHelper.validate(path).isOK()) {
504 return true;
505 }
506 }
507 return false;
508 }
509
510 /**
511 * @param traceType
512 * the trace type
513 * @return <code>true</code> it is a directory trace type else else <code>false</code>
514 */
515 public static boolean isDirectoryTraceType(String traceType) {
516 if (traceType != null) {
517 TraceTypeHelper traceTypeHelper = getTraceType(traceType);
518 if (traceTypeHelper != null) {
519 return traceTypeHelper.isDirectoryTraceType();
520 }
521 return false;
522 }
523 throw new IllegalArgumentException("Invalid trace type string: " + traceType); //$NON-NLS-1$
524 }
525
526 /**
527 * Get the trace type id for a resource
528 *
529 * @param resource
530 * the resource
531 * @return the trace type id or null if it is not set
532 * @throws CoreException
533 * if the trace type id cannot be accessed
534 */
535 public static String getTraceTypeId(IResource resource) throws CoreException {
536 String traceTypeId = resource.getPersistentProperties().get(TmfCommonConstants.TRACETYPE);
537 return buildCompatibilityTraceTypeId(traceTypeId);
538 }
539
540 /**
541 * This methods builds a trace type ID from a given ID taking into
542 * consideration any format changes that were done for the IDs of custom
543 * text or XML traces. For example, such format change took place when
544 * moving to Trace Compass. Trace type IDs that are part of the plug-in
545 * extension for trace types won't be changed.
546 *
547 * This method is useful for IDs that were persisted in the workspace before
548 * the format changes (e.g. in the persistent properties of a trace
549 * resource).
550 *
551 * It ensures backwards compatibility of the workspace for custom text and
552 * XML traces.
553 *
554 * @param traceTypeId
555 * the legacy trace type ID
556 * @return the trace type ID in Trace Compass format
557 */
558 public static String buildCompatibilityTraceTypeId(String traceTypeId) {
559 // Fix custom trace type id with old class name or without category name for backward compatibility
560 if (traceTypeId != null) {
561 String newTraceType = CustomTxtTrace.buildCompatibilityTraceTypeId(traceTypeId);
562 if (newTraceType.equals(traceTypeId)) {
563 newTraceType = CustomXmlTrace.buildCompatibilityTraceTypeId(traceTypeId);
564 }
565 return newTraceType;
566 }
567 return traceTypeId;
568 }
569
570 }
This page took 0.044332 seconds and 5 git commands to generate.