tmf: Move TmfTraceType and custom parsers to tmf.core
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / project / model / TmfTraceType.java
1 /*******************************************************************************
2 * Copyright (c) 2011, 2013 Ericsson
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 *******************************************************************************/
13
14 package org.eclipse.linuxtools.tmf.core.project.model;
15
16 import java.io.File;
17 import java.util.ArrayList;
18 import java.util.HashMap;
19 import java.util.LinkedHashMap;
20 import java.util.LinkedList;
21 import java.util.List;
22 import java.util.Map;
23
24 import org.eclipse.core.resources.IResource;
25 import org.eclipse.core.runtime.CoreException;
26 import org.eclipse.core.runtime.IConfigurationElement;
27 import org.eclipse.core.runtime.Platform;
28 import org.eclipse.linuxtools.internal.tmf.core.Activator;
29 import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
30 import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTrace;
31 import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTraceDefinition;
32 import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTrace;
33 import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition;
34 import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager;
35 import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
36
37 /**
38 * Utility class for accessing TMF trace type extensions from the platform's
39 * extensions registry.
40 *
41 * @version 1.0
42 * @author Patrick Tasse
43 * @author Matthew Khouzam
44 * @since 3.0
45 */
46 public final class TmfTraceType {
47
48 private static final char SEPARATOR = ':';
49
50 /** Extension point ID */
51 public static final String TMF_TRACE_TYPE_ID = "org.eclipse.linuxtools.tmf.ui.tracetype"; //$NON-NLS-1$
52
53 /** Extension point element 'Category' */
54 public static final String CATEGORY_ELEM = "category"; //$NON-NLS-1$
55
56 /** Extension point element 'Type' */
57 public static final String TYPE_ELEM = "type"; //$NON-NLS-1$
58
59 /** Extension point element 'Default editor' */
60 public static final String DEFAULT_EDITOR_ELEM = "defaultEditor"; //$NON-NLS-1$
61
62 /** Extension point element 'Events table type' */
63 public static final String EVENTS_TABLE_TYPE_ELEM = "eventsTableType"; //$NON-NLS-1$
64
65 /** Extension point element 'Statistics viewer type' */
66 public static final String STATISTICS_VIEWER_ELEM = "statisticsViewerType"; //$NON-NLS-1$
67
68 /** Extension point attribute 'ID' */
69 public static final String ID_ATTR = "id"; //$NON-NLS-1$
70
71 /** Extension point attribute 'name' */
72 public static final String NAME_ATTR = "name"; //$NON-NLS-1$
73
74 /** Extension point attribute 'category' */
75 public static final String CATEGORY_ATTR = "category"; //$NON-NLS-1$
76
77 /** Extension point attribute 'trace_type' */
78 public static final String TRACE_TYPE_ATTR = "trace_type"; //$NON-NLS-1$
79
80 /** Extension point attribute 'event_type' */
81 public static final String EVENT_TYPE_ATTR = "event_type"; //$NON-NLS-1$
82
83 /** Extension point attribute 'icon' */
84 public static final String ICON_ATTR = "icon"; //$NON-NLS-1$
85
86 /** Extension point attribute 'class' */
87 public static final String CLASS_ATTR = "class"; //$NON-NLS-1$
88
89 /**
90 * Custom text label used internally and therefore should not be
91 * externalized
92 */
93 public static final String CUSTOM_TXT_CATEGORY = "Custom Text"; //$NON-NLS-1$
94
95 /**
96 * Custom XML label used internally and therefore should not be externalized
97 */
98 public static final String CUSTOM_XML_CATEGORY = "Custom XML"; //$NON-NLS-1$
99
100 // The mapping of available trace type IDs to their corresponding
101 // configuration element
102 private final Map<String, IConfigurationElement> fTraceTypeAttributes = new HashMap<>();
103 private final Map<String, IConfigurationElement> fTraceCategories = new HashMap<>();
104 private final Map<String, TraceTypeHelper> fTraceTypes = new LinkedHashMap<>();
105
106 private static TmfTraceType fInstance = null;
107
108 /**
109 * Retrieves the category name from the platform extension registry based on
110 * the category ID
111 *
112 * @param categoryId
113 * The category ID
114 * @return the category name or empty string if not found
115 */
116 public static String getCategoryName(String categoryId) {
117 IConfigurationElement[] elements = Platform.getExtensionRegistry()
118 .getConfigurationElementsFor(TMF_TRACE_TYPE_ID);
119 for (IConfigurationElement element : elements) {
120 if (element.getName().equals(CATEGORY_ELEM) && categoryId.equals(element.getAttribute(ID_ATTR))) {
121 return element.getAttribute(NAME_ATTR);
122 }
123 }
124 return ""; //$NON-NLS-1$
125 }
126
127 /**
128 * Retrieves and instantiates an element's object based on his plug-in
129 * definition for a specific trace type.
130 *
131 * The element's object is instantiated using its 0-argument constructor.
132 *
133 * @param resource
134 * The resource where to find the information about the trace
135 * properties
136 * @param element
137 * The name of the element to find under the trace type
138 * definition
139 * @return a new Object based on his definition in plugin.xml, or null if no
140 * definition was found
141 */
142 public static Object getTraceTypeElement(IResource resource, String element) {
143 try {
144 if (resource != null) {
145 String traceType = resource.getPersistentProperty(TmfCommonConstants.TRACETYPE);
146 /*
147 * Search in the configuration if there is any viewer specified
148 * for this kind of trace type.
149 */
150 for (IConfigurationElement ce : TmfTraceType.getTypeElements()) {
151 if (ce.getAttribute(TmfTraceType.ID_ATTR).equals(traceType)) {
152 IConfigurationElement[] viewerCE = ce.getChildren(element);
153 if (viewerCE.length != 1) {
154 break;
155 }
156 return viewerCE[0].createExecutableExtension(TmfTraceType.CLASS_ATTR);
157 }
158 }
159 }
160 } catch (CoreException e) {
161 Activator.logError("Error creating the element from the resource", e); //$NON-NLS-1$
162 }
163 return null;
164 }
165
166 /**
167 * Retrieves all configuration elements from the platform extension registry
168 * for the trace type extension.
169 *
170 * @return an array of trace type configuration elements
171 */
172 public static IConfigurationElement[] getTypeElements() {
173 IConfigurationElement[] elements = Platform.getExtensionRegistry()
174 .getConfigurationElementsFor(TMF_TRACE_TYPE_ID);
175 List<IConfigurationElement> typeElements = new LinkedList<>();
176 for (IConfigurationElement element : elements) {
177 if (element.getName().equals(TYPE_ELEM)) {
178 typeElements.add(element);
179 }
180 }
181 return typeElements.toArray(new IConfigurationElement[typeElements.size()]);
182 }
183
184 private TmfTraceType() {
185 init();
186 }
187
188 /**
189 * The import utils instance
190 *
191 * @return the import utils instance
192 */
193 public static TmfTraceType getInstance() {
194 if (fInstance == null) {
195 fInstance = new TmfTraceType();
196 }
197 return fInstance;
198 }
199
200 // ------------------------------------------------------------------
201 // Get trace types
202 // ------------------------------------------------------------------
203
204 /**
205 * Retrieve the TraceTypeHelper for a given trace type ID
206 *
207 * @param id
208 * The trace type ID
209 * @return The corresponding TraceTypeHelper, or null if there is none for
210 * the specified ID
211 */
212 public TraceTypeHelper getTraceTypeHelper(String id) {
213 return fTraceTypes.get(id);
214 }
215
216 /**
217 * Get an iterable view of the existing trace type IDs.
218 *
219 * @return The currently registered trace type IDs
220 */
221 public Iterable<String> getTraceTypeIDs() {
222 return fTraceTypes.keySet();
223 }
224
225 /**
226 * Returns a list of "category:tracetype , ..."
227 *
228 * @return returns a list of "category:tracetype , ..."
229 */
230 public String[] getAvailableTraceTypes() {
231
232 // Generate the list of Category:TraceType to populate the ComboBox
233 List<String> traceTypes = new ArrayList<>();
234
235 for (String key : this.fTraceTypes.keySet()) {
236 TraceTypeHelper tt = this.fTraceTypes.get(key);
237 traceTypes.add(tt.getCategoryName() + SEPARATOR + tt.getName());
238 }
239
240 // Format result
241 return traceTypes.toArray(new String[traceTypes.size()]);
242 }
243
244 /**
245 * Gets the custom trace types (custom text and friends)
246 *
247 * @param type
248 * the type to get (Text, xml or other...)
249 * @return the list of custom trace types
250 */
251 public static List<String> getCustomTraceTypes(String type) {
252 List<String> traceTypes = new ArrayList<>();
253 if (type.equals(CUSTOM_TXT_CATEGORY)) {
254 for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {
255 String traceTypeName = def.definitionName;
256 traceTypes.add(traceTypeName);
257 }
258 }
259 if (type.equals(CUSTOM_XML_CATEGORY)) {
260 for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) {
261 String traceTypeName = def.definitionName;
262 traceTypes.add(traceTypeName);
263 }
264 }
265 return traceTypes;
266 }
267
268 /**
269 * Gets all the custom trace types
270 *
271 * @return the list of custom trace types
272 */
273 public static List<String> getCustomTraceTypes() {
274
275 List<String> traceTypes = new ArrayList<>();
276 for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {
277 String traceTypeName = def.definitionName;
278 traceTypes.add(traceTypeName);
279 }
280 for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) {
281 String traceTypeName = def.definitionName;
282 traceTypes.add(traceTypeName);
283 }
284 return traceTypes;
285 }
286
287 private void populateCustomTraceTypes() {
288 // add the custom trace types
289 for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {
290 String traceTypeId = CustomTxtTrace.class.getCanonicalName() + SEPARATOR + def.definitionName;
291 ITmfTrace trace = new CustomTxtTrace(def);
292 TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, CUSTOM_TXT_CATEGORY, def.definitionName, trace);
293 fTraceTypes.put(traceTypeId, tt);
294 // Deregister trace as signal handler because it is only used for validation
295 TmfSignalManager.deregister(trace);
296 }
297 for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) {
298 String traceTypeId = CustomXmlTrace.class.getCanonicalName() + SEPARATOR + def.definitionName;
299 ITmfTrace trace = new CustomXmlTrace(def);
300 TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, CUSTOM_XML_CATEGORY, def.definitionName, trace);
301 fTraceTypes.put(traceTypeId, tt);
302 // Deregister trace as signal handler because it is only used for validation
303 TmfSignalManager.deregister(trace);
304 }
305 }
306
307 /**
308 * Add or replace a custom trace type
309 *
310 * @param category
311 * The custom parser category
312 * @param definitionName
313 * The custom parser definition name to add or replace
314 */
315 public void addCustomTraceType(String category, String definitionName) {
316 String traceTypeId = null;
317 ITmfTrace trace = null;
318
319 if (category.equals(CUSTOM_TXT_CATEGORY)) {
320 traceTypeId = CustomTxtTrace.class.getCanonicalName() + SEPARATOR + definitionName;
321 CustomTxtTraceDefinition def = CustomTxtTraceDefinition.load(definitionName);
322 if (def != null) {
323 trace = new CustomTxtTrace(def);
324 }
325 } else if (category.equals(CUSTOM_XML_CATEGORY)) {
326 traceTypeId = CustomXmlTrace.class.getCanonicalName() + SEPARATOR + definitionName;
327 CustomXmlTraceDefinition def = CustomXmlTraceDefinition.load(definitionName);
328 if (def != null) {
329 trace = new CustomXmlTrace(def);
330 }
331 }
332
333 if (traceTypeId != null && trace != null) {
334 TraceTypeHelper helper = fTraceTypes.get(traceTypeId);
335 if (helper != null) {
336 helper.getTrace().dispose();
337 }
338 TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, category, definitionName, trace);
339 fTraceTypes.put(traceTypeId, tt);
340 // Deregister trace as signal handler because it is only used for validation
341 TmfSignalManager.deregister(trace);
342 }
343 }
344
345 /**
346 * Remove a custom trace type
347 *
348 * @param category
349 * The custom parser category
350 * @param definitionName
351 * The custom parser definition name to add or replace
352 */
353 public void removeCustomTraceType(String category, String definitionName) {
354 if (category.equals(CUSTOM_TXT_CATEGORY)) {
355 String traceTypeId = CustomTxtTrace.class.getCanonicalName() + SEPARATOR + definitionName;
356 TraceTypeHelper helper = fTraceTypes.remove(traceTypeId);
357 if (helper != null) {
358 helper.getTrace().dispose();
359 }
360 } else if (category.equals(CUSTOM_XML_CATEGORY)) {
361 String traceTypeId = CustomXmlTrace.class.getCanonicalName() + SEPARATOR + definitionName;
362 TraceTypeHelper helper = fTraceTypes.remove(traceTypeId);
363 if (helper != null) {
364 helper.getTrace().dispose();
365 }
366 }
367 }
368
369 /**
370 * Gets a trace type for a given canonical id
371 *
372 * @param id
373 * the ID of the trace
374 * @return the return type
375 */
376 public TraceTypeHelper getTraceType(String id) {
377 return fTraceTypes.get(id);
378 }
379
380 private void populateCategoriesAndTraceTypes() {
381 if (fTraceTypes.isEmpty()) {
382 // Populate the Categories and Trace Types
383 IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType.TMF_TRACE_TYPE_ID);
384 for (IConfigurationElement ce : config) {
385 String elementName = ce.getName();
386 if (elementName.equals(TmfTraceType.TYPE_ELEM)) {
387 String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR);
388 fTraceTypeAttributes.put(traceTypeId, ce);
389 } else if (elementName.equals(TmfTraceType.CATEGORY_ELEM)) {
390 String categoryId = ce.getAttribute(TmfTraceType.ID_ATTR);
391 fTraceCategories.put(categoryId, ce);
392 }
393 }
394 // create the trace types
395 for (String typeId : fTraceTypeAttributes.keySet()) {
396 IConfigurationElement ce = fTraceTypeAttributes.get(typeId);
397 final String category = getCategory(ce);
398 final String attribute = ce.getAttribute(TmfTraceType.NAME_ATTR);
399 ITmfTrace trace = null;
400 try {
401 trace = (ITmfTrace) ce.createExecutableExtension(TmfTraceType.TRACE_TYPE_ATTR);
402 // Deregister trace as signal handler because it is only used for validation
403 TmfSignalManager.deregister(trace);
404 } catch (CoreException e) {
405 }
406 TraceTypeHelper tt = new TraceTypeHelper(typeId, category, attribute, trace);
407 fTraceTypes.put(typeId, tt);
408 }
409 }
410 }
411
412 private String getCategory(IConfigurationElement ce) {
413 final String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR);
414 if (categoryId != null) {
415 IConfigurationElement category = fTraceCategories.get(categoryId);
416 if (category != null && !category.getName().equals("")) { //$NON-NLS-1$
417 return category.getAttribute(TmfTraceType.NAME_ATTR);
418 }
419 }
420 return "[no category]"; //$NON-NLS-1$
421 }
422
423 /**
424 * Returns the list of trace categories
425 *
426 * @return the list of trace categories
427 */
428 public List<String> getTraceCategories() {
429 List<String> categoryNames = new ArrayList<>();
430 for (String key : fTraceTypes.keySet()) {
431 final String categoryName = fTraceTypes.get(key).getCategoryName();
432 if (!categoryNames.contains(categoryName)) {
433 categoryNames.add(categoryName);
434 }
435 }
436 return categoryNames;
437 }
438
439 /**
440 * Get the trace type helper classes from category name
441 *
442 * @param categoryName
443 * the categoryName to lookup
444 * @return a list of trace type helper classes {@link TraceTypeHelper}
445 */
446 public List<TraceTypeHelper> getTraceTypes(String categoryName) {
447 List<TraceTypeHelper> traceNames = new ArrayList<>();
448 for (String key : fTraceTypes.keySet()) {
449 final String storedCategoryName = fTraceTypes.get(key).getCategoryName();
450 if (storedCategoryName.equals(categoryName)) {
451 traceNames.add(fTraceTypes.get(key));
452 }
453 }
454 return traceNames;
455 }
456
457 private void init() {
458 populateCategoriesAndTraceTypes();
459 populateCustomTraceTypes();
460
461 }
462
463 /**
464 * Validate a trace type
465 *
466 * @param traceTypeName
467 * the trace category (canonical name)
468 * @param fileName
469 * the file name (and path)
470 * @return true if the trace is of a valid type
471 */
472 public boolean validate(String traceTypeName, String fileName) {
473 if (traceTypeName != null && !traceTypeName.isEmpty()) {
474 final TraceTypeHelper traceTypeHelper = fTraceTypes.get(traceTypeName);
475 if (!traceTypeHelper.validate(fileName)) {
476 return false;
477 }
478 }
479 return true;
480 }
481
482 /**
483 * Validate a trace
484 *
485 * @param traceToValidate
486 * the trace category (canonical name)
487 * @return true if the trace is of a valid type
488 */
489 public boolean validate(TraceValidationHelper traceToValidate) {
490 return validate(traceToValidate.getTraceType(), traceToValidate.getTraceToScan());
491 }
492
493 /**
494 * Validate a list of files with a tracetype
495 *
496 * @param traceTypeName
497 * the trace category (canonical name)
498 * @param traces
499 * the list of files to check if they are trace
500 * @return true if all the traces are valid
501 */
502 public boolean validateTraceFiles(String traceTypeName, List<File> traces) {
503 if (traceTypeName != null && !"".equals(traceTypeName) && //$NON-NLS-1$
504 !traceTypeName.startsWith(TmfTraceType.CUSTOM_TXT_CATEGORY) && !traceTypeName.startsWith(TmfTraceType.CUSTOM_XML_CATEGORY)) {
505 for (File trace : traces) {
506 if (!validate(traceTypeName, trace.getAbsolutePath())) {
507 return false;
508 }
509 }
510 }
511 return true;
512 }
513
514 /**
515 * Get a configuration element for a given name
516 *
517 * @param traceType
518 * the name canonical
519 * @return the configuration element, can be null
520 */
521 public IConfigurationElement getTraceAttributes(String traceType) {
522 return fTraceTypeAttributes.get(traceType);
523 }
524
525 /**
526 * Find the id of a trace type by its parameters
527 *
528 * @param category
529 * like "ctf" or "custom text"
530 * @param traceType
531 * like "kernel"
532 * @return an id like "org.eclipse.linuxtools.blabla...
533 */
534 public String getTraceTypeId(String category, String traceType) {
535 for (String key : fTraceTypes.keySet()) {
536 if (fTraceTypes.get(key).getCategoryName().equals(category.trim()) && fTraceTypes.get(key).getName().equals(traceType.trim())) {
537 return key;
538 }
539 }
540 return null;
541 }
542
543 /**
544 * Gets the custom trace type ID from the custom trace name
545 *
546 * @param traceType
547 * The trace type in human form (category:name)
548 * @return the trace type ID or null if the trace is not a custom one
549 */
550 public static String getCustomTraceTypeId(String traceType) {
551 String traceTypeId = null;
552
553 // do custom trace stuff here
554 String traceTypeToken[] = traceType.split(":", 2); //$NON-NLS-1$
555 if (traceTypeToken.length == 2) {
556 final boolean startsWithTxt = traceType.startsWith(TmfTraceType.CUSTOM_TXT_CATEGORY);
557 final boolean startsWithXML = traceType.startsWith(TmfTraceType.CUSTOM_XML_CATEGORY);
558 if (startsWithTxt) {
559 traceTypeId = CustomTxtTrace.class.getCanonicalName() + SEPARATOR + traceTypeToken[1];
560 } else if (startsWithXML) {
561 traceTypeId = CustomXmlTrace.class.getCanonicalName() + SEPARATOR + traceTypeToken[1];
562 }
563 }
564 return traceTypeId;
565 }
566
567 /**
568 * Is the trace a custom (user-defined) trace type. These are the traces
569 * like : text and xml defined by the custom trace wizard.
570 *
571 * @param traceType
572 * the trace type in human form (category:name)
573 * @return true if the trace is a custom type
574 */
575 public static boolean isCustomTrace(String traceType) {
576 final boolean startsWithTxt = traceType.startsWith(TmfTraceType.CUSTOM_TXT_CATEGORY);
577 final boolean startsWithXML = traceType.startsWith(TmfTraceType.CUSTOM_XML_CATEGORY);
578 return (startsWithTxt || startsWithXML);
579 }
580 }
This page took 0.05438 seconds and 5 git commands to generate.