Commit | Line | Data |
---|---|---|
4bf17f4a | 1 | /******************************************************************************* |
b544077e | 2 | * Copyright (c) 2011, 2012 Ericsson |
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 |
4bf17f4a | 12 | *******************************************************************************/ |
13 | ||
bfc779a0 | 14 | package org.eclipse.linuxtools.tmf.ui.project.model; |
4bf17f4a | 15 | |
d04ec5a7 MK |
16 | import java.io.File; |
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; | |
4bf17f4a | 22 | import java.util.LinkedList; |
23 | import java.util.List; | |
d04ec5a7 | 24 | import java.util.Map; |
4bf17f4a | 25 | |
05627bda MD |
26 | import org.eclipse.core.resources.IResource; |
27 | import org.eclipse.core.runtime.CoreException; | |
4bf17f4a | 28 | import org.eclipse.core.runtime.IConfigurationElement; |
29 | import org.eclipse.core.runtime.Platform; | |
05627bda | 30 | import org.eclipse.linuxtools.internal.tmf.ui.Activator; |
d04ec5a7 MK |
31 | import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtTraceDefinition; |
32 | import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomXmlTraceDefinition; | |
05627bda | 33 | import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; |
d04ec5a7 MK |
34 | import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; |
35 | import org.eclipse.ui.dialogs.FileSystemElement; | |
4bf17f4a | 36 | |
b544077e | 37 | /** |
d04ec5a7 MK |
38 | * Utility class for accessing TMF trace type extensions from the platform's |
39 | * extensions registry. | |
cfd22ad0 | 40 | * |
b544077e BH |
41 | * @version 1.0 |
42 | * @author Patrick Tasse | |
d04ec5a7 | 43 | * @author Matthew Khouzam |
b544077e | 44 | */ |
d04ec5a7 | 45 | public final class TmfTraceType { |
4bf17f4a | 46 | |
b544077e | 47 | /** |
d04ec5a7 | 48 | * Extension point ID |
b544077e | 49 | */ |
bfc779a0 | 50 | public static final String TMF_TRACE_TYPE_ID = "org.eclipse.linuxtools.tmf.ui.tracetype"; //$NON-NLS-1$ |
4bf17f4a | 51 | |
b544077e | 52 | /** |
d04ec5a7 | 53 | * Extension point element 'Category' |
b544077e | 54 | */ |
4bf17f4a | 55 | public static final String CATEGORY_ELEM = "category"; //$NON-NLS-1$ |
b544077e | 56 | /** |
d04ec5a7 | 57 | * Extension point element 'Type' |
b544077e | 58 | */ |
4bf17f4a | 59 | public static final String TYPE_ELEM = "type"; //$NON-NLS-1$ |
b544077e | 60 | /** |
cfd22ad0 | 61 | * Extension point element 'Default editor' |
b544077e | 62 | */ |
4bf17f4a | 63 | public static final String DEFAULT_EDITOR_ELEM = "defaultEditor"; //$NON-NLS-1$ |
b544077e BH |
64 | /** |
65 | * Extension point element 'Events table type' | |
66 | */ | |
4bf17f4a | 67 | public static final String EVENTS_TABLE_TYPE_ELEM = "eventsTableType"; //$NON-NLS-1$ |
cfd22ad0 MD |
68 | /** |
69 | * Extension point element 'Statistics viewer type' | |
70 | * | |
71 | * @since 2.0 | |
72 | */ | |
73 | public static final String STATISTICS_VIEWER_ELEM = "statisticsViewerType"; //$NON-NLS-1$ | |
4bf17f4a | 74 | |
b544077e | 75 | /** |
d04ec5a7 | 76 | * Extension point attribute 'ID' |
b544077e | 77 | */ |
4bf17f4a | 78 | public static final String ID_ATTR = "id"; //$NON-NLS-1$ |
b544077e BH |
79 | /** |
80 | * Extension point attribute 'name' | |
81 | */ | |
4bf17f4a | 82 | public static final String NAME_ATTR = "name"; //$NON-NLS-1$ |
b544077e BH |
83 | /** |
84 | * Extension point attribute 'category' | |
85 | */ | |
4bf17f4a | 86 | public static final String CATEGORY_ATTR = "category"; //$NON-NLS-1$ |
b544077e BH |
87 | /** |
88 | * Extension point attribute 'trace_type' | |
89 | */ | |
4bf17f4a | 90 | public static final String TRACE_TYPE_ATTR = "trace_type"; //$NON-NLS-1$ |
b544077e BH |
91 | /** |
92 | * Extension point attribute 'event_type' | |
93 | */ | |
4bf17f4a | 94 | public static final String EVENT_TYPE_ATTR = "event_type"; //$NON-NLS-1$ |
b544077e BH |
95 | /** |
96 | * Extension point attribute 'icon' | |
97 | */ | |
4bf17f4a | 98 | public static final String ICON_ATTR = "icon"; //$NON-NLS-1$ |
b544077e BH |
99 | /** |
100 | * Extension point attribute 'class' | |
101 | */ | |
4bf17f4a | 102 | public static final String CLASS_ATTR = "class"; //$NON-NLS-1$ |
103 | ||
b544077e | 104 | /** |
d04ec5a7 MK |
105 | * Custom text label used internally and therefore should not be |
106 | * externalized | |
107 | * | |
108 | * @since 2.0 | |
109 | */ | |
110 | public static final String CUSTOM_TXT_CATEGORY = "Custom Text"; //$NON-NLS-1$ | |
111 | /** | |
112 | * Custom XML label used internally and therefore should not be externalized | |
113 | * | |
114 | * @since 2.0 | |
115 | */ | |
116 | public static final String CUSTOM_XML_CATEGORY = "Custom XML"; //$NON-NLS-1$ | |
117 | ||
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>(); | |
123 | ||
124 | private static TmfTraceType fInstance = null; | |
125 | ||
126 | /** | |
127 | * Retrieves the category name from the platform extension registry based on | |
128 | * the category ID | |
129 | * | |
130 | * @param categoryId | |
131 | * The category ID | |
b544077e BH |
132 | * @return the category name or empty string if not found |
133 | */ | |
4bf17f4a | 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); | |
140 | } | |
141 | } | |
142 | return ""; //$NON-NLS-1$ | |
143 | } | |
144 | ||
05627bda MD |
145 | /** |
146 | * Retrieves and instantiates an element's object based on his plug-in | |
147 | * definition for a specific trace type. | |
148 | * | |
149 | * The element's object is instantiated using its 0-argument constructor. | |
150 | * | |
151 | * @param resource | |
152 | * The resource where to find the information about the trace | |
153 | * properties | |
154 | * @param element | |
155 | * The name of the element to find under the trace type | |
156 | * definition | |
157 | * @return a new Object based on his definition in plugin.xml, or null if no | |
158 | * definition was found | |
159 | * @since 2.0 | |
160 | */ | |
161 | public static Object getTraceTypeElement(IResource resource, String element) { | |
162 | try { | |
163 | if (resource != null) { | |
164 | String traceType = resource.getPersistentProperty(TmfCommonConstants.TRACETYPE); | |
165 | /* | |
166 | * Search in the configuration if there is any viewer specified | |
167 | * for this kind of trace type. | |
168 | */ | |
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) { | |
173 | break; | |
174 | } | |
175 | return viewerCE[0].createExecutableExtension(TmfTraceType.CLASS_ATTR); | |
176 | } | |
177 | } | |
178 | } | |
179 | } catch (CoreException e) { | |
180 | Activator.getDefault().logError("Error creating the element from the resource", e); //$NON-NLS-1$ | |
181 | } | |
182 | return null; | |
183 | } | |
184 | ||
b544077e | 185 | /** |
cfd22ad0 | 186 | * Retrieves all configuration elements from the platform extension registry |
b544077e | 187 | * for the trace type extension. |
cfd22ad0 MD |
188 | * |
189 | * @return an array of trace type configuration elements | |
b544077e | 190 | */ |
4bf17f4a | 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); | |
198 | } | |
199 | } | |
beae214a | 200 | return typeElements.toArray(new IConfigurationElement[typeElements.size()]); |
4bf17f4a | 201 | } |
d04ec5a7 MK |
202 | |
203 | private TmfTraceType() { | |
204 | init(); | |
205 | } | |
206 | ||
207 | /** | |
208 | * The import utils instance | |
209 | * | |
210 | * @return the import utils instance | |
211 | * @since 2.0 | |
212 | */ | |
213 | public static TmfTraceType getInstance() { | |
214 | if (fInstance == null) { | |
215 | fInstance = new TmfTraceType(); | |
216 | } | |
217 | return fInstance; | |
218 | } | |
219 | ||
220 | // ------------------------------------------------------------------ | |
221 | // Get trace types | |
222 | // ------------------------------------------------------------------ | |
223 | ||
224 | /** | |
225 | * Returns a list of "category : tracetype , ..." | |
226 | * | |
227 | * @return returns a list of "category : tracetype , ..." | |
228 | * @since 2.0 | |
229 | */ | |
230 | public String[] getAvailableTraceTypes() { | |
231 | ||
232 | // Generate the list of Category:TraceType to populate the ComboBox | |
233 | List<String> traceTypes = new ArrayList<String>(); | |
234 | ||
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$ | |
239 | } | |
240 | traceTypes.addAll(customTypes); | |
241 | ||
242 | // Format result | |
243 | return traceTypes.toArray(new String[traceTypes.size()]); | |
244 | } | |
245 | ||
246 | /** | |
247 | * Gets the custom trace types (custom text and friends) | |
248 | * | |
249 | * @param type | |
250 | * the type to get (Text, xml or other...) | |
251 | * @return the list of custom trace types | |
252 | * @since 2.0 | |
253 | */ | |
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); | |
260 | } | |
261 | } | |
262 | if (type.equals(CUSTOM_XML_CATEGORY)) { | |
263 | for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { | |
264 | String traceTypeName = def.definitionName; | |
265 | traceTypes.add(traceTypeName); | |
266 | } | |
267 | } | |
268 | return traceTypes; | |
269 | } | |
270 | ||
271 | /** | |
272 | * Gets all the custom trace types | |
273 | * | |
274 | * @return the list of custom trace types | |
275 | * @since 2.0 | |
276 | */ | |
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); | |
284 | } | |
285 | } | |
286 | ||
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); | |
293 | } | |
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); | |
299 | } | |
300 | return traceTypes; | |
301 | } | |
302 | ||
303 | /** | |
304 | * Gets a trace type for a given canonical id | |
305 | * | |
306 | * @param id | |
307 | * the ID of the trace | |
308 | * @return the return type | |
309 | * @since 2.0 | |
310 | */ | |
311 | public TraceTypeHelper getTraceType(String id) { | |
312 | return fTraceTypes.get(id); | |
313 | } | |
314 | ||
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); | |
327 | } | |
328 | } | |
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; | |
335 | try { | |
336 | trace = (ITmfTrace) ce.createExecutableExtension(TmfTraceType.TRACE_TYPE_ATTR); | |
337 | } catch (CoreException e) { | |
338 | } | |
339 | TraceTypeHelper tt = new TraceTypeHelper(typeId, category, attribute, trace); | |
340 | fTraceTypes.put(typeId, tt); | |
341 | } | |
342 | } | |
343 | } | |
344 | ||
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); | |
351 | } | |
352 | } | |
353 | return "[no category]"; //$NON-NLS-1$ | |
354 | } | |
355 | ||
356 | /** | |
357 | * Returns the list of trace categories | |
358 | * | |
359 | * @return the list of trace categories | |
360 | * @since 2.0 | |
361 | */ | |
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); | |
368 | } | |
369 | } | |
370 | return categoryNames; | |
371 | } | |
372 | ||
373 | /** | |
374 | * Get the trace types | |
375 | * | |
376 | * @param category | |
377 | * the category to lookup | |
378 | * @return the trace types | |
379 | * @since 2.0 | |
380 | */ | |
381 | ||
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)); | |
388 | } | |
389 | } | |
390 | return traceNames; | |
391 | } | |
392 | ||
393 | private void init() { | |
394 | populateCategoriesAndTraceTypes(); | |
395 | getCustomTraceTypes(); | |
396 | ||
397 | } | |
398 | ||
399 | private static List<File> isolateTraces(List<FileSystemElement> selectedResources) { | |
400 | ||
401 | List<File> traces = new ArrayList<File>(); | |
402 | ||
403 | // Get the selection | |
404 | Iterator<FileSystemElement> resources = selectedResources.iterator(); | |
405 | ||
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); | |
412 | } | |
413 | List<String> files = new ArrayList<String>(fileSystemObjects.keySet()); | |
414 | Collections.sort(files); | |
415 | ||
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 | |
423 | traces.add(file); | |
424 | } | |
425 | } | |
426 | ||
427 | return traces; | |
428 | } | |
429 | ||
430 | /** | |
431 | * Validate a trace type | |
432 | * | |
433 | * @param traceTypeName | |
434 | * the trace category (canonical name) | |
435 | * @param fileName | |
436 | * the file name (and path) | |
437 | * @return true if the trace is of a valid type | |
438 | * @since 2.0 | |
439 | */ | |
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)) { | |
444 | return false; | |
445 | } | |
446 | } | |
447 | return true; | |
448 | } | |
449 | ||
450 | /** | |
451 | * Validate a trace | |
452 | * | |
453 | * @param traceToValidate | |
454 | * the trace category (canonical name) | |
455 | * @return true if the trace is of a valid type | |
456 | * @since 2.0 | |
457 | */ | |
458 | public boolean validate(TraceValidationHelper traceToValidate) { | |
459 | return validate(traceToValidate.getTraceType(), traceToValidate.getTraceToScan()); | |
460 | } | |
461 | ||
462 | /** | |
463 | * validate list of traces with a tracetype | |
464 | * | |
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 | |
470 | * @since 2.0 | |
471 | */ | |
472 | public boolean validateTrace(String traceTypeName, List<FileSystemElement> selectedResources) { | |
473 | List<File> traces = isolateTraces(selectedResources); | |
474 | return validateTraceFiles(traceTypeName, traces); | |
475 | } | |
476 | ||
477 | /** | |
478 | * Validate a list of files with a tracetype | |
479 | * | |
480 | * @param traceTypeName | |
481 | * the trace category (canonical name) | |
482 | * @param traces | |
483 | * the list of files to check if they are trace | |
484 | * @return true if all the traces are valid | |
485 | * @since 2.0 | |
486 | */ | |
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()); | |
492 | } | |
493 | } | |
494 | return true; | |
495 | } | |
496 | ||
497 | /** | |
498 | * Get a configuration element for a given name | |
499 | * | |
500 | * @param traceType | |
501 | * the name canonical | |
502 | * @return the configuration element, can be null | |
503 | * @since 2.0 | |
504 | */ | |
505 | public IConfigurationElement getTraceAttributes(String traceType) { | |
506 | return fTraceTypeAttributes.get(traceType); | |
507 | } | |
508 | ||
509 | /** | |
510 | * Find the id of a trace type by its parameters | |
511 | * | |
512 | * @param category | |
513 | * like "ctf" or "custom text" | |
514 | * @param traceType | |
515 | * like "kernel" | |
516 | * @return an id like "org.eclipse.linuxtools.blabla... | |
517 | * @since 2.0 | |
518 | */ | |
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())) { | |
522 | return key; | |
523 | } | |
524 | } | |
525 | return null; | |
526 | } | |
4bf17f4a | 527 | } |