1 /*******************************************************************************
2 * Copyright (c) 2011, 2012 Ericsson
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 *******************************************************************************/
14 package org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
;
17 import java
.util
.ArrayList
;
18 import java
.util
.Collections
;
19 import java
.util
.HashMap
;
20 import java
.util
.Iterator
;
21 import java
.util
.LinkedHashMap
;
22 import java
.util
.LinkedList
;
23 import java
.util
.List
;
26 import org
.eclipse
.core
.resources
.IResource
;
27 import org
.eclipse
.core
.runtime
.CoreException
;
28 import org
.eclipse
.core
.runtime
.IConfigurationElement
;
29 import org
.eclipse
.core
.runtime
.Platform
;
30 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Activator
;
31 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomTxtTraceDefinition
;
32 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomXmlTraceDefinition
;
33 import org
.eclipse
.linuxtools
.tmf
.core
.TmfCommonConstants
;
34 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
35 import org
.eclipse
.ui
.dialogs
.FileSystemElement
;
38 * Utility class for accessing TMF trace type extensions from the platform's
39 * extensions registry.
42 * @author Patrick Tasse
43 * @author Matthew Khouzam
45 public final class TmfTraceType
{
50 public static final String TMF_TRACE_TYPE_ID
= "org.eclipse.linuxtools.tmf.ui.tracetype"; //$NON-NLS-1$
53 * Extension point element 'Category'
55 public static final String CATEGORY_ELEM
= "category"; //$NON-NLS-1$
57 * Extension point element 'Type'
59 public static final String TYPE_ELEM
= "type"; //$NON-NLS-1$
61 * Extension point element 'Default editor'
63 public static final String DEFAULT_EDITOR_ELEM
= "defaultEditor"; //$NON-NLS-1$
65 * Extension point element 'Events table type'
67 public static final String EVENTS_TABLE_TYPE_ELEM
= "eventsTableType"; //$NON-NLS-1$
69 * Extension point element 'Statistics viewer type'
73 public static final String STATISTICS_VIEWER_ELEM
= "statisticsViewerType"; //$NON-NLS-1$
76 * Extension point attribute 'ID'
78 public static final String ID_ATTR
= "id"; //$NON-NLS-1$
80 * Extension point attribute 'name'
82 public static final String NAME_ATTR
= "name"; //$NON-NLS-1$
84 * Extension point attribute 'category'
86 public static final String CATEGORY_ATTR
= "category"; //$NON-NLS-1$
88 * Extension point attribute 'trace_type'
90 public static final String TRACE_TYPE_ATTR
= "trace_type"; //$NON-NLS-1$
92 * Extension point attribute 'event_type'
94 public static final String EVENT_TYPE_ATTR
= "event_type"; //$NON-NLS-1$
96 * Extension point attribute 'icon'
98 public static final String ICON_ATTR
= "icon"; //$NON-NLS-1$
100 * Extension point attribute 'class'
102 public static final String CLASS_ATTR
= "class"; //$NON-NLS-1$
105 * Custom text label used internally and therefore should not be
110 public static final String CUSTOM_TXT_CATEGORY
= "Custom Text"; //$NON-NLS-1$
112 * Custom XML label used internally and therefore should not be externalized
116 public static final String CUSTOM_XML_CATEGORY
= "Custom XML"; //$NON-NLS-1$
118 // The mapping of available trace type IDs to their corresponding
119 // configuration element
120 private final Map
<String
, IConfigurationElement
> fTraceTypeAttributes
= new HashMap
<String
, IConfigurationElement
>();
121 private final Map
<String
, IConfigurationElement
> fTraceCategories
= new HashMap
<String
, IConfigurationElement
>();
122 private final Map
<String
, TraceTypeHelper
> fTraceTypes
= new LinkedHashMap
<String
, TraceTypeHelper
>();
124 private static TmfTraceType fInstance
= null;
127 * Retrieves the category name from the platform extension registry based on
132 * @return the category name or empty string if not found
134 public static String
getCategoryName(String categoryId
) {
135 IConfigurationElement
[] elements
= Platform
.getExtensionRegistry()
136 .getConfigurationElementsFor(TMF_TRACE_TYPE_ID
);
137 for (IConfigurationElement element
: elements
) {
138 if (element
.getName().equals(CATEGORY_ELEM
) && categoryId
.equals(element
.getAttribute(ID_ATTR
))) {
139 return element
.getAttribute(NAME_ATTR
);
142 return ""; //$NON-NLS-1$
146 * Retrieves and instantiates an element's object based on his plug-in
147 * definition for a specific trace type.
149 * The element's object is instantiated using its 0-argument constructor.
152 * The resource where to find the information about the trace
155 * The name of the element to find under the trace type
157 * @return a new Object based on his definition in plugin.xml, or null if no
158 * definition was found
161 public static Object
getTraceTypeElement(IResource resource
, String element
) {
163 if (resource
!= null) {
164 String traceType
= resource
.getPersistentProperty(TmfCommonConstants
.TRACETYPE
);
166 * Search in the configuration if there is any viewer specified
167 * for this kind of trace type.
169 for (IConfigurationElement ce
: TmfTraceType
.getTypeElements()) {
170 if (ce
.getAttribute(TmfTraceType
.ID_ATTR
).equals(traceType
)) {
171 IConfigurationElement
[] viewerCE
= ce
.getChildren(element
);
172 if (viewerCE
.length
!= 1) {
175 return viewerCE
[0].createExecutableExtension(TmfTraceType
.CLASS_ATTR
);
179 } catch (CoreException e
) {
180 Activator
.getDefault().logError("Error creating the element from the resource", e
); //$NON-NLS-1$
186 * Retrieves all configuration elements from the platform extension registry
187 * for the trace type extension.
189 * @return an array of trace type configuration elements
191 public static IConfigurationElement
[] getTypeElements() {
192 IConfigurationElement
[] elements
= Platform
.getExtensionRegistry()
193 .getConfigurationElementsFor(TMF_TRACE_TYPE_ID
);
194 List
<IConfigurationElement
> typeElements
= new LinkedList
<IConfigurationElement
>();
195 for (IConfigurationElement element
: elements
) {
196 if (element
.getName().equals(TYPE_ELEM
)) {
197 typeElements
.add(element
);
200 return typeElements
.toArray(new IConfigurationElement
[typeElements
.size()]);
203 private TmfTraceType() {
208 * The import utils instance
210 * @return the import utils instance
213 public static TmfTraceType
getInstance() {
214 if (fInstance
== null) {
215 fInstance
= new TmfTraceType();
220 // ------------------------------------------------------------------
222 // ------------------------------------------------------------------
225 * Returns a list of "category : tracetype , ..."
227 * @return returns a list of "category : tracetype , ..."
230 public String
[] getAvailableTraceTypes() {
232 // Generate the list of Category:TraceType to populate the ComboBox
233 List
<String
> traceTypes
= new ArrayList
<String
>();
235 List
<String
> customTypes
= getCustomTraceTypes();
236 for (String key
: this.fTraceTypes
.keySet()) {
237 TraceTypeHelper tt
= this.fTraceTypes
.get(key
);
238 traceTypes
.add(tt
.getCategoryName() + " : " + tt
.getName()); //$NON-NLS-1$
240 traceTypes
.addAll(customTypes
);
243 return traceTypes
.toArray(new String
[traceTypes
.size()]);
247 * Gets the custom trace types (custom text and friends)
250 * the type to get (Text, xml or other...)
251 * @return the list of custom trace types
254 public static List
<String
> getCustomTraceTypes(String type
) {
255 List
<String
> traceTypes
= new ArrayList
<String
>();
256 if (type
.equals(CUSTOM_TXT_CATEGORY
)) {
257 for (CustomTxtTraceDefinition def
: CustomTxtTraceDefinition
.loadAll()) {
258 String traceTypeName
= def
.definitionName
;
259 traceTypes
.add(traceTypeName
);
262 if (type
.equals(CUSTOM_XML_CATEGORY
)) {
263 for (CustomXmlTraceDefinition def
: CustomXmlTraceDefinition
.loadAll()) {
264 String traceTypeName
= def
.definitionName
;
265 traceTypes
.add(traceTypeName
);
272 * Gets all the custom trace types
274 * @return the list of custom trace types
277 public List
<String
> getCustomTraceTypes() {
278 List
<String
> traceTypes
= new ArrayList
<String
>();
279 // remove the customTraceTypes
280 final String
[] keySet
= fTraceTypes
.keySet().toArray(new String
[0]);
281 for (String key
: keySet
) {
282 if (fTraceTypes
.get(key
).getCategoryName().equals(CUSTOM_TXT_CATEGORY
) || fTraceTypes
.get(key
).getCategoryName().equals(CUSTOM_XML_CATEGORY
)) {
283 fTraceTypes
.remove(key
);
287 // add the custom trace types
288 for (CustomTxtTraceDefinition def
: CustomTxtTraceDefinition
.loadAll()) {
289 String traceTypeName
= CUSTOM_TXT_CATEGORY
+ " : " + def
.definitionName
; //$NON-NLS-1$
290 TraceTypeHelper tt
= new TraceTypeHelper(traceTypeName
, CUSTOM_TXT_CATEGORY
, def
.definitionName
, null);
291 fTraceTypes
.put(traceTypeName
, tt
);
292 traceTypes
.add(traceTypeName
);
294 for (CustomXmlTraceDefinition def
: CustomXmlTraceDefinition
.loadAll()) {
295 String traceTypeName
= CUSTOM_XML_CATEGORY
+ " : " + def
.definitionName
; //$NON-NLS-1$
296 TraceTypeHelper tt
= new TraceTypeHelper(traceTypeName
, CUSTOM_TXT_CATEGORY
, def
.definitionName
, null);
297 fTraceTypes
.put(traceTypeName
, tt
);
298 traceTypes
.add(traceTypeName
);
304 * Gets a trace type for a given canonical id
307 * the ID of the trace
308 * @return the return type
311 public TraceTypeHelper
getTraceType(String id
) {
312 return fTraceTypes
.get(id
);
315 private void populateCategoriesAndTraceTypes() {
316 if (fTraceTypes
.isEmpty()) {
317 // Populate the Categories and Trace Types
318 IConfigurationElement
[] config
= Platform
.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType
.TMF_TRACE_TYPE_ID
);
319 for (IConfigurationElement ce
: config
) {
320 String elementName
= ce
.getName();
321 if (elementName
.equals(TmfTraceType
.TYPE_ELEM
)) {
322 String traceTypeId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
323 fTraceTypeAttributes
.put(traceTypeId
, ce
);
324 } else if (elementName
.equals(TmfTraceType
.CATEGORY_ELEM
)) {
325 String categoryId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
326 fTraceCategories
.put(categoryId
, ce
);
329 // create the trace types
330 for (String typeId
: fTraceTypeAttributes
.keySet()) {
331 IConfigurationElement ce
= fTraceTypeAttributes
.get(typeId
);
332 final String category
= getCategory(ce
);
333 final String attribute
= ce
.getAttribute(TmfTraceType
.NAME_ATTR
);
334 ITmfTrace trace
= null;
336 trace
= (ITmfTrace
) ce
.createExecutableExtension(TmfTraceType
.TRACE_TYPE_ATTR
);
337 } catch (CoreException e
) {
339 TraceTypeHelper tt
= new TraceTypeHelper(typeId
, category
, attribute
, trace
);
340 fTraceTypes
.put(typeId
, tt
);
345 private String
getCategory(IConfigurationElement ce
) {
346 final String categoryId
= ce
.getAttribute(TmfTraceType
.CATEGORY_ATTR
);
347 if (categoryId
!= null) {
348 IConfigurationElement category
= fTraceCategories
.get(categoryId
);
349 if (category
!= null && !category
.getName().equals("")) { //$NON-NLS-1$
350 return category
.getAttribute(TmfTraceType
.NAME_ATTR
);
353 return "[no category]"; //$NON-NLS-1$
357 * Returns the list of trace categories
359 * @return the list of trace categories
362 public List
<String
> getTraceCategories() {
363 List
<String
> categoryNames
= new ArrayList
<String
>();
364 for (String key
: fTraceTypes
.keySet()) {
365 final String categoryName
= fTraceTypes
.get(key
).getCategoryName();
366 if (!categoryNames
.contains(categoryName
)) {
367 categoryNames
.add(categoryName
);
370 return categoryNames
;
374 * Get the trace types
377 * the category to lookup
378 * @return the trace types
382 public List
<TraceTypeHelper
> getTraceTypes(String category
) {
383 List
<TraceTypeHelper
> traceNames
= new ArrayList
<TraceTypeHelper
>();
384 for (String key
: fTraceTypes
.keySet()) {
385 final String categoryName
= fTraceTypes
.get(key
).getCategoryName();
386 if (categoryName
.equals(category
)) {
387 traceNames
.add(fTraceTypes
.get(key
));
393 private void init() {
394 populateCategoriesAndTraceTypes();
395 getCustomTraceTypes();
399 private static List
<File
> isolateTraces(List
<FileSystemElement
> selectedResources
) {
401 List
<File
> traces
= new ArrayList
<File
>();
404 Iterator
<FileSystemElement
> resources
= selectedResources
.iterator();
406 // Get the sorted list of unique entries
407 Map
<String
, File
> fileSystemObjects
= new HashMap
<String
, File
>();
408 while (resources
.hasNext()) {
409 File resource
= (File
) resources
.next().getFileSystemObject();
410 String key
= resource
.getAbsolutePath();
411 fileSystemObjects
.put(key
, resource
);
413 List
<String
> files
= new ArrayList
<String
>(fileSystemObjects
.keySet());
414 Collections
.sort(files
);
416 // After sorting, traces correspond to the unique prefixes
417 String prefix
= null;
418 for (int i
= 0; i
< files
.size(); i
++) {
419 File file
= fileSystemObjects
.get(files
.get(i
));
420 String name
= file
.getAbsolutePath();
421 if (prefix
== null || !name
.startsWith(prefix
)) {
422 prefix
= name
; // new prefix
431 * Validate a trace type
433 * @param traceTypeName
434 * the trace category (canonical name)
436 * the file name (and path)
437 * @return true if the trace is of a valid type
440 public boolean validate(String traceTypeName
, String fileName
) {
441 if (traceTypeName
!= null && !"".equals(traceTypeName
) && //$NON-NLS-1$
442 !traceTypeName
.startsWith(TmfTraceType
.CUSTOM_TXT_CATEGORY
) && !traceTypeName
.startsWith(TmfTraceType
.CUSTOM_XML_CATEGORY
)) {
443 if (!fTraceTypes
.get(traceTypeName
).validate(fileName
)) {
453 * @param traceToValidate
454 * the trace category (canonical name)
455 * @return true if the trace is of a valid type
458 public boolean validate(TraceValidationHelper traceToValidate
) {
459 return validate(traceToValidate
.getTraceType(), traceToValidate
.getTraceToScan());
463 * validate list of traces with a tracetype
465 * @param traceTypeName
466 * the trace category (canonical name)
467 * @param selectedResources
468 * List of traces to validate
469 * @return true if all the traces are valid
472 public boolean validateTrace(String traceTypeName
, List
<FileSystemElement
> selectedResources
) {
473 List
<File
> traces
= isolateTraces(selectedResources
);
474 return validateTraceFiles(traceTypeName
, traces
);
478 * Validate a list of files with a tracetype
480 * @param traceTypeName
481 * the trace category (canonical name)
483 * the list of files to check if they are trace
484 * @return true if all the traces are valid
487 public boolean validateTraceFiles(String traceTypeName
, List
<File
> traces
) {
488 if (traceTypeName
!= null && !"".equals(traceTypeName
) && //$NON-NLS-1$
489 !traceTypeName
.startsWith(TmfTraceType
.CUSTOM_TXT_CATEGORY
) && !traceTypeName
.startsWith(TmfTraceType
.CUSTOM_XML_CATEGORY
)) {
490 for (File trace
: traces
) {
491 validate(traceTypeName
, trace
.getAbsolutePath());
498 * Get a configuration element for a given name
502 * @return the configuration element, can be null
505 public IConfigurationElement
getTraceAttributes(String traceType
) {
506 return fTraceTypeAttributes
.get(traceType
);
510 * Find the id of a trace type by its parameters
513 * like "ctf" or "custom text"
516 * @return an id like "org.eclipse.linuxtools.blabla...
519 public String
getTraceTypeId(String category
, String traceType
) {
520 for (String key
: fTraceTypes
.keySet()) {
521 if (fTraceTypes
.get(key
).getCategoryName().equals(category
.trim()) && fTraceTypes
.get(key
).getName().equals(traceType
.trim())) {