Commit | Line | Data |
---|---|---|
4bf17f4a | 1 | /******************************************************************************* |
661b21a1 | 2 | * Copyright (c) 2011, 2013 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; |
76fccfb0 | 25 | import java.util.Set; |
4bf17f4a | 26 | |
05627bda | 27 | import org.eclipse.core.resources.IResource; |
76fccfb0 | 28 | import org.eclipse.core.resources.ResourcesPlugin; |
05627bda | 29 | import org.eclipse.core.runtime.CoreException; |
4bf17f4a | 30 | import org.eclipse.core.runtime.IConfigurationElement; |
76fccfb0 MK |
31 | import org.eclipse.core.runtime.IPath; |
32 | import org.eclipse.core.runtime.IStatus; | |
4bf17f4a | 33 | import org.eclipse.core.runtime.Platform; |
76fccfb0 | 34 | import org.eclipse.core.runtime.Status; |
05627bda | 35 | import org.eclipse.linuxtools.internal.tmf.ui.Activator; |
76fccfb0 | 36 | import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtTrace; |
d04ec5a7 | 37 | import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtTraceDefinition; |
76fccfb0 | 38 | import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomXmlTrace; |
d04ec5a7 | 39 | import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomXmlTraceDefinition; |
76fccfb0 | 40 | import org.eclipse.linuxtools.internal.tmf.ui.project.model.TmfTraceImportException; |
05627bda | 41 | import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; |
72807127 | 42 | import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; |
d04ec5a7 | 43 | import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; |
76fccfb0 MK |
44 | import org.eclipse.swt.SWT; |
45 | import org.eclipse.swt.events.SelectionEvent; | |
46 | import org.eclipse.swt.events.SelectionListener; | |
47 | import org.eclipse.swt.layout.RowLayout; | |
48 | import org.eclipse.swt.widgets.Button; | |
49 | import org.eclipse.swt.widgets.Display; | |
50 | import org.eclipse.swt.widgets.Shell; | |
d04ec5a7 | 51 | import org.eclipse.ui.dialogs.FileSystemElement; |
4bf17f4a | 52 | |
b544077e | 53 | /** |
d04ec5a7 MK |
54 | * Utility class for accessing TMF trace type extensions from the platform's |
55 | * extensions registry. | |
cfd22ad0 | 56 | * |
b544077e BH |
57 | * @version 1.0 |
58 | * @author Patrick Tasse | |
d04ec5a7 | 59 | * @author Matthew Khouzam |
b544077e | 60 | */ |
d04ec5a7 | 61 | public final class TmfTraceType { |
4bf17f4a | 62 | |
76fccfb0 MK |
63 | private static final String DEFAULT_TRACE_ICON_PATH = "icons" + File.separator + "elcl16" + File.separator + "trace.gif"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
64 | ||
a2d29ca1 MK |
65 | private static final char SEPARATOR = ':'; |
66 | ||
b544077e | 67 | /** |
d04ec5a7 | 68 | * Extension point ID |
b544077e | 69 | */ |
bfc779a0 | 70 | public static final String TMF_TRACE_TYPE_ID = "org.eclipse.linuxtools.tmf.ui.tracetype"; //$NON-NLS-1$ |
4bf17f4a | 71 | |
b544077e | 72 | /** |
d04ec5a7 | 73 | * Extension point element 'Category' |
b544077e | 74 | */ |
4bf17f4a | 75 | public static final String CATEGORY_ELEM = "category"; //$NON-NLS-1$ |
b544077e | 76 | /** |
d04ec5a7 | 77 | * Extension point element 'Type' |
b544077e | 78 | */ |
4bf17f4a | 79 | public static final String TYPE_ELEM = "type"; //$NON-NLS-1$ |
b544077e | 80 | /** |
cfd22ad0 | 81 | * Extension point element 'Default editor' |
b544077e | 82 | */ |
4bf17f4a | 83 | public static final String DEFAULT_EDITOR_ELEM = "defaultEditor"; //$NON-NLS-1$ |
b544077e BH |
84 | /** |
85 | * Extension point element 'Events table type' | |
86 | */ | |
4bf17f4a | 87 | public static final String EVENTS_TABLE_TYPE_ELEM = "eventsTableType"; //$NON-NLS-1$ |
cfd22ad0 MD |
88 | /** |
89 | * Extension point element 'Statistics viewer type' | |
90 | * | |
91 | * @since 2.0 | |
92 | */ | |
93 | public static final String STATISTICS_VIEWER_ELEM = "statisticsViewerType"; //$NON-NLS-1$ | |
4bf17f4a | 94 | |
b544077e | 95 | /** |
d04ec5a7 | 96 | * Extension point attribute 'ID' |
b544077e | 97 | */ |
4bf17f4a | 98 | public static final String ID_ATTR = "id"; //$NON-NLS-1$ |
b544077e BH |
99 | /** |
100 | * Extension point attribute 'name' | |
101 | */ | |
4bf17f4a | 102 | public static final String NAME_ATTR = "name"; //$NON-NLS-1$ |
b544077e BH |
103 | /** |
104 | * Extension point attribute 'category' | |
105 | */ | |
4bf17f4a | 106 | public static final String CATEGORY_ATTR = "category"; //$NON-NLS-1$ |
b544077e BH |
107 | /** |
108 | * Extension point attribute 'trace_type' | |
109 | */ | |
4bf17f4a | 110 | public static final String TRACE_TYPE_ATTR = "trace_type"; //$NON-NLS-1$ |
b544077e BH |
111 | /** |
112 | * Extension point attribute 'event_type' | |
113 | */ | |
4bf17f4a | 114 | public static final String EVENT_TYPE_ATTR = "event_type"; //$NON-NLS-1$ |
b544077e BH |
115 | /** |
116 | * Extension point attribute 'icon' | |
117 | */ | |
4bf17f4a | 118 | public static final String ICON_ATTR = "icon"; //$NON-NLS-1$ |
b544077e BH |
119 | /** |
120 | * Extension point attribute 'class' | |
121 | */ | |
4bf17f4a | 122 | public static final String CLASS_ATTR = "class"; //$NON-NLS-1$ |
123 | ||
b544077e | 124 | /** |
d04ec5a7 MK |
125 | * Custom text label used internally and therefore should not be |
126 | * externalized | |
127 | * | |
128 | * @since 2.0 | |
129 | */ | |
130 | public static final String CUSTOM_TXT_CATEGORY = "Custom Text"; //$NON-NLS-1$ | |
131 | /** | |
132 | * Custom XML label used internally and therefore should not be externalized | |
133 | * | |
134 | * @since 2.0 | |
135 | */ | |
136 | public static final String CUSTOM_XML_CATEGORY = "Custom XML"; //$NON-NLS-1$ | |
137 | ||
138 | // The mapping of available trace type IDs to their corresponding | |
139 | // configuration element | |
507b1336 AM |
140 | private final Map<String, IConfigurationElement> fTraceTypeAttributes = new HashMap<>(); |
141 | private final Map<String, IConfigurationElement> fTraceCategories = new HashMap<>(); | |
142 | private final Map<String, TraceTypeHelper> fTraceTypes = new LinkedHashMap<>(); | |
d04ec5a7 MK |
143 | |
144 | private static TmfTraceType fInstance = null; | |
145 | ||
146 | /** | |
147 | * Retrieves the category name from the platform extension registry based on | |
148 | * the category ID | |
149 | * | |
150 | * @param categoryId | |
151 | * The category ID | |
b544077e BH |
152 | * @return the category name or empty string if not found |
153 | */ | |
4bf17f4a | 154 | public static String getCategoryName(String categoryId) { |
155 | IConfigurationElement[] elements = Platform.getExtensionRegistry() | |
156 | .getConfigurationElementsFor(TMF_TRACE_TYPE_ID); | |
157 | for (IConfigurationElement element : elements) { | |
158 | if (element.getName().equals(CATEGORY_ELEM) && categoryId.equals(element.getAttribute(ID_ATTR))) { | |
159 | return element.getAttribute(NAME_ATTR); | |
160 | } | |
161 | } | |
162 | return ""; //$NON-NLS-1$ | |
163 | } | |
164 | ||
05627bda MD |
165 | /** |
166 | * Retrieves and instantiates an element's object based on his plug-in | |
167 | * definition for a specific trace type. | |
168 | * | |
169 | * The element's object is instantiated using its 0-argument constructor. | |
170 | * | |
171 | * @param resource | |
172 | * The resource where to find the information about the trace | |
173 | * properties | |
174 | * @param element | |
175 | * The name of the element to find under the trace type | |
176 | * definition | |
177 | * @return a new Object based on his definition in plugin.xml, or null if no | |
178 | * definition was found | |
179 | * @since 2.0 | |
180 | */ | |
181 | public static Object getTraceTypeElement(IResource resource, String element) { | |
182 | try { | |
183 | if (resource != null) { | |
184 | String traceType = resource.getPersistentProperty(TmfCommonConstants.TRACETYPE); | |
185 | /* | |
186 | * Search in the configuration if there is any viewer specified | |
187 | * for this kind of trace type. | |
188 | */ | |
189 | for (IConfigurationElement ce : TmfTraceType.getTypeElements()) { | |
190 | if (ce.getAttribute(TmfTraceType.ID_ATTR).equals(traceType)) { | |
191 | IConfigurationElement[] viewerCE = ce.getChildren(element); | |
192 | if (viewerCE.length != 1) { | |
193 | break; | |
194 | } | |
195 | return viewerCE[0].createExecutableExtension(TmfTraceType.CLASS_ATTR); | |
196 | } | |
197 | } | |
198 | } | |
199 | } catch (CoreException e) { | |
200 | Activator.getDefault().logError("Error creating the element from the resource", e); //$NON-NLS-1$ | |
201 | } | |
202 | return null; | |
203 | } | |
204 | ||
b544077e | 205 | /** |
cfd22ad0 | 206 | * Retrieves all configuration elements from the platform extension registry |
b544077e | 207 | * for the trace type extension. |
cfd22ad0 MD |
208 | * |
209 | * @return an array of trace type configuration elements | |
b544077e | 210 | */ |
4bf17f4a | 211 | public static IConfigurationElement[] getTypeElements() { |
212 | IConfigurationElement[] elements = Platform.getExtensionRegistry() | |
213 | .getConfigurationElementsFor(TMF_TRACE_TYPE_ID); | |
507b1336 | 214 | List<IConfigurationElement> typeElements = new LinkedList<>(); |
4bf17f4a | 215 | for (IConfigurationElement element : elements) { |
216 | if (element.getName().equals(TYPE_ELEM)) { | |
217 | typeElements.add(element); | |
218 | } | |
219 | } | |
beae214a | 220 | return typeElements.toArray(new IConfigurationElement[typeElements.size()]); |
4bf17f4a | 221 | } |
d04ec5a7 MK |
222 | |
223 | private TmfTraceType() { | |
224 | init(); | |
225 | } | |
226 | ||
227 | /** | |
228 | * The import utils instance | |
229 | * | |
230 | * @return the import utils instance | |
231 | * @since 2.0 | |
232 | */ | |
233 | public static TmfTraceType getInstance() { | |
234 | if (fInstance == null) { | |
235 | fInstance = new TmfTraceType(); | |
236 | } | |
237 | return fInstance; | |
238 | } | |
239 | ||
240 | // ------------------------------------------------------------------ | |
241 | // Get trace types | |
242 | // ------------------------------------------------------------------ | |
243 | ||
244 | /** | |
a2d29ca1 | 245 | * Returns a list of "category:tracetype , ..." |
d04ec5a7 | 246 | * |
a2d29ca1 | 247 | * @return returns a list of "category:tracetype , ..." |
d04ec5a7 MK |
248 | * @since 2.0 |
249 | */ | |
250 | public String[] getAvailableTraceTypes() { | |
251 | ||
252 | // Generate the list of Category:TraceType to populate the ComboBox | |
507b1336 | 253 | List<String> traceTypes = new ArrayList<>(); |
d04ec5a7 | 254 | |
76fccfb0 MK |
255 | // re-populate custom trace types |
256 | getCustomTraceTypes(); | |
d04ec5a7 MK |
257 | for (String key : this.fTraceTypes.keySet()) { |
258 | TraceTypeHelper tt = this.fTraceTypes.get(key); | |
a2d29ca1 | 259 | traceTypes.add(tt.getCategoryName() + SEPARATOR + tt.getName()); |
d04ec5a7 | 260 | } |
d04ec5a7 MK |
261 | |
262 | // Format result | |
263 | return traceTypes.toArray(new String[traceTypes.size()]); | |
264 | } | |
265 | ||
266 | /** | |
267 | * Gets the custom trace types (custom text and friends) | |
268 | * | |
269 | * @param type | |
270 | * the type to get (Text, xml or other...) | |
271 | * @return the list of custom trace types | |
272 | * @since 2.0 | |
273 | */ | |
274 | public static List<String> getCustomTraceTypes(String type) { | |
507b1336 | 275 | List<String> traceTypes = new ArrayList<>(); |
d04ec5a7 MK |
276 | if (type.equals(CUSTOM_TXT_CATEGORY)) { |
277 | for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) { | |
278 | String traceTypeName = def.definitionName; | |
279 | traceTypes.add(traceTypeName); | |
280 | } | |
281 | } | |
282 | if (type.equals(CUSTOM_XML_CATEGORY)) { | |
283 | for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { | |
284 | String traceTypeName = def.definitionName; | |
285 | traceTypes.add(traceTypeName); | |
286 | } | |
287 | } | |
288 | return traceTypes; | |
289 | } | |
290 | ||
291 | /** | |
292 | * Gets all the custom trace types | |
293 | * | |
294 | * @return the list of custom trace types | |
295 | * @since 2.0 | |
296 | */ | |
297 | public List<String> getCustomTraceTypes() { | |
507b1336 | 298 | List<String> traceTypes = new ArrayList<>(); |
d04ec5a7 MK |
299 | // remove the customTraceTypes |
300 | final String[] keySet = fTraceTypes.keySet().toArray(new String[0]); | |
301 | for (String key : keySet) { | |
661b21a1 PT |
302 | TraceTypeHelper helper = fTraceTypes.get(key); |
303 | if (helper.getCategoryName().equals(CUSTOM_TXT_CATEGORY) || helper.getCategoryName().equals(CUSTOM_XML_CATEGORY)) { | |
304 | helper.getTrace().dispose(); | |
d04ec5a7 MK |
305 | fTraceTypes.remove(key); |
306 | } | |
307 | } | |
308 | ||
309 | // add the custom trace types | |
310 | for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) { | |
26e33e67 | 311 | String traceTypeId = CustomTxtTrace.class.getCanonicalName() + SEPARATOR + def.definitionName; |
72807127 BH |
312 | ITmfTrace trace = new CustomTxtTrace(def); |
313 | TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, CUSTOM_TXT_CATEGORY, def.definitionName, trace); | |
26e33e67 MAL |
314 | fTraceTypes.put(traceTypeId, tt); |
315 | traceTypes.add(traceTypeId); | |
72807127 BH |
316 | // Deregister trace as signal handler because it is only used for validation |
317 | TmfSignalManager.deregister(trace); | |
d04ec5a7 MK |
318 | } |
319 | for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) { | |
26e33e67 | 320 | String traceTypeId = CustomXmlTrace.class.getCanonicalName() + SEPARATOR + def.definitionName; |
72807127 BH |
321 | ITmfTrace trace = new CustomXmlTrace(def); |
322 | TraceTypeHelper tt = new TraceTypeHelper(traceTypeId, CUSTOM_XML_CATEGORY, def.definitionName, trace); | |
26e33e67 MAL |
323 | fTraceTypes.put(traceTypeId, tt); |
324 | traceTypes.add(traceTypeId); | |
72807127 BH |
325 | // Deregister trace as signal handler because it is only used for validation |
326 | TmfSignalManager.deregister(trace); | |
d04ec5a7 MK |
327 | } |
328 | return traceTypes; | |
329 | } | |
330 | ||
331 | /** | |
332 | * Gets a trace type for a given canonical id | |
333 | * | |
334 | * @param id | |
335 | * the ID of the trace | |
336 | * @return the return type | |
337 | * @since 2.0 | |
338 | */ | |
339 | public TraceTypeHelper getTraceType(String id) { | |
cd9821de | 340 | init(); |
d04ec5a7 MK |
341 | return fTraceTypes.get(id); |
342 | } | |
343 | ||
344 | private void populateCategoriesAndTraceTypes() { | |
345 | if (fTraceTypes.isEmpty()) { | |
346 | // Populate the Categories and Trace Types | |
347 | IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType.TMF_TRACE_TYPE_ID); | |
348 | for (IConfigurationElement ce : config) { | |
349 | String elementName = ce.getName(); | |
350 | if (elementName.equals(TmfTraceType.TYPE_ELEM)) { | |
351 | String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR); | |
352 | fTraceTypeAttributes.put(traceTypeId, ce); | |
353 | } else if (elementName.equals(TmfTraceType.CATEGORY_ELEM)) { | |
354 | String categoryId = ce.getAttribute(TmfTraceType.ID_ATTR); | |
355 | fTraceCategories.put(categoryId, ce); | |
356 | } | |
357 | } | |
358 | // create the trace types | |
359 | for (String typeId : fTraceTypeAttributes.keySet()) { | |
360 | IConfigurationElement ce = fTraceTypeAttributes.get(typeId); | |
361 | final String category = getCategory(ce); | |
362 | final String attribute = ce.getAttribute(TmfTraceType.NAME_ATTR); | |
363 | ITmfTrace trace = null; | |
364 | try { | |
365 | trace = (ITmfTrace) ce.createExecutableExtension(TmfTraceType.TRACE_TYPE_ATTR); | |
72807127 BH |
366 | // Deregister trace as signal handler because it is only used for validation |
367 | TmfSignalManager.deregister(trace); | |
d04ec5a7 MK |
368 | } catch (CoreException e) { |
369 | } | |
370 | TraceTypeHelper tt = new TraceTypeHelper(typeId, category, attribute, trace); | |
371 | fTraceTypes.put(typeId, tt); | |
372 | } | |
373 | } | |
374 | } | |
375 | ||
376 | private String getCategory(IConfigurationElement ce) { | |
377 | final String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR); | |
378 | if (categoryId != null) { | |
379 | IConfigurationElement category = fTraceCategories.get(categoryId); | |
380 | if (category != null && !category.getName().equals("")) { //$NON-NLS-1$ | |
381 | return category.getAttribute(TmfTraceType.NAME_ATTR); | |
382 | } | |
383 | } | |
384 | return "[no category]"; //$NON-NLS-1$ | |
385 | } | |
386 | ||
387 | /** | |
388 | * Returns the list of trace categories | |
389 | * | |
390 | * @return the list of trace categories | |
391 | * @since 2.0 | |
392 | */ | |
393 | public List<String> getTraceCategories() { | |
507b1336 | 394 | List<String> categoryNames = new ArrayList<>(); |
d04ec5a7 MK |
395 | for (String key : fTraceTypes.keySet()) { |
396 | final String categoryName = fTraceTypes.get(key).getCategoryName(); | |
397 | if (!categoryNames.contains(categoryName)) { | |
398 | categoryNames.add(categoryName); | |
399 | } | |
400 | } | |
401 | return categoryNames; | |
402 | } | |
403 | ||
404 | /** | |
cd9821de | 405 | * Get the trace type helper classes from category name |
d04ec5a7 | 406 | * |
cd9821de BH |
407 | * @param categoryName |
408 | * the categoryName to lookup | |
409 | * @return a list of trace type helper classes {@link TraceTypeHelper} | |
d04ec5a7 MK |
410 | * @since 2.0 |
411 | */ | |
412 | ||
cd9821de | 413 | public List<TraceTypeHelper> getTraceTypes(String categoryName) { |
2ddeece8 | 414 | init(); |
507b1336 | 415 | List<TraceTypeHelper> traceNames = new ArrayList<>(); |
d04ec5a7 | 416 | for (String key : fTraceTypes.keySet()) { |
cd9821de BH |
417 | final String storedCategoryName = fTraceTypes.get(key).getCategoryName(); |
418 | if (storedCategoryName.equals(categoryName)) { | |
d04ec5a7 MK |
419 | traceNames.add(fTraceTypes.get(key)); |
420 | } | |
421 | } | |
422 | return traceNames; | |
423 | } | |
424 | ||
425 | private void init() { | |
426 | populateCategoriesAndTraceTypes(); | |
427 | getCustomTraceTypes(); | |
428 | ||
429 | } | |
430 | ||
431 | private static List<File> isolateTraces(List<FileSystemElement> selectedResources) { | |
432 | ||
507b1336 | 433 | List<File> traces = new ArrayList<>(); |
d04ec5a7 MK |
434 | |
435 | // Get the selection | |
436 | Iterator<FileSystemElement> resources = selectedResources.iterator(); | |
437 | ||
438 | // Get the sorted list of unique entries | |
507b1336 | 439 | Map<String, File> fileSystemObjects = new HashMap<>(); |
d04ec5a7 MK |
440 | while (resources.hasNext()) { |
441 | File resource = (File) resources.next().getFileSystemObject(); | |
442 | String key = resource.getAbsolutePath(); | |
443 | fileSystemObjects.put(key, resource); | |
444 | } | |
507b1336 | 445 | List<String> files = new ArrayList<>(fileSystemObjects.keySet()); |
d04ec5a7 MK |
446 | Collections.sort(files); |
447 | ||
448 | // After sorting, traces correspond to the unique prefixes | |
449 | String prefix = null; | |
450 | for (int i = 0; i < files.size(); i++) { | |
451 | File file = fileSystemObjects.get(files.get(i)); | |
452 | String name = file.getAbsolutePath(); | |
453 | if (prefix == null || !name.startsWith(prefix)) { | |
454 | prefix = name; // new prefix | |
455 | traces.add(file); | |
456 | } | |
457 | } | |
458 | ||
459 | return traces; | |
460 | } | |
461 | ||
462 | /** | |
463 | * Validate a trace type | |
464 | * | |
465 | * @param traceTypeName | |
466 | * the trace category (canonical name) | |
467 | * @param fileName | |
468 | * the file name (and path) | |
469 | * @return true if the trace is of a valid type | |
470 | * @since 2.0 | |
471 | */ | |
472 | public boolean validate(String traceTypeName, String fileName) { | |
76fccfb0 | 473 | if (traceTypeName != null && !traceTypeName.isEmpty()) { |
de2501f8 MK |
474 | final TraceTypeHelper traceTypeHelper = fTraceTypes.get(traceTypeName); |
475 | if (!traceTypeHelper.validate(fileName)) { | |
d04ec5a7 MK |
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 | * @since 2.0 | |
489 | */ | |
490 | public boolean validate(TraceValidationHelper traceToValidate) { | |
491 | return validate(traceToValidate.getTraceType(), traceToValidate.getTraceToScan()); | |
492 | } | |
493 | ||
494 | /** | |
495 | * validate list of traces with a tracetype | |
496 | * | |
497 | * @param traceTypeName | |
498 | * the trace category (canonical name) | |
499 | * @param selectedResources | |
500 | * List of traces to validate | |
501 | * @return true if all the traces are valid | |
502 | * @since 2.0 | |
503 | */ | |
504 | public boolean validateTrace(String traceTypeName, List<FileSystemElement> selectedResources) { | |
505 | List<File> traces = isolateTraces(selectedResources); | |
506 | return validateTraceFiles(traceTypeName, traces); | |
507 | } | |
508 | ||
509 | /** | |
510 | * Validate a list of files with a tracetype | |
511 | * | |
512 | * @param traceTypeName | |
513 | * the trace category (canonical name) | |
514 | * @param traces | |
515 | * the list of files to check if they are trace | |
516 | * @return true if all the traces are valid | |
517 | * @since 2.0 | |
518 | */ | |
519 | public boolean validateTraceFiles(String traceTypeName, List<File> traces) { | |
520 | if (traceTypeName != null && !"".equals(traceTypeName) && //$NON-NLS-1$ | |
521 | !traceTypeName.startsWith(TmfTraceType.CUSTOM_TXT_CATEGORY) && !traceTypeName.startsWith(TmfTraceType.CUSTOM_XML_CATEGORY)) { | |
522 | for (File trace : traces) { | |
edd51555 MK |
523 | if (!validate(traceTypeName, trace.getAbsolutePath())) { |
524 | return false; | |
525 | } | |
d04ec5a7 MK |
526 | } |
527 | } | |
528 | return true; | |
529 | } | |
530 | ||
531 | /** | |
532 | * Get a configuration element for a given name | |
533 | * | |
534 | * @param traceType | |
535 | * the name canonical | |
536 | * @return the configuration element, can be null | |
537 | * @since 2.0 | |
538 | */ | |
539 | public IConfigurationElement getTraceAttributes(String traceType) { | |
540 | return fTraceTypeAttributes.get(traceType); | |
541 | } | |
542 | ||
543 | /** | |
544 | * Find the id of a trace type by its parameters | |
545 | * | |
546 | * @param category | |
547 | * like "ctf" or "custom text" | |
548 | * @param traceType | |
549 | * like "kernel" | |
550 | * @return an id like "org.eclipse.linuxtools.blabla... | |
551 | * @since 2.0 | |
552 | */ | |
553 | public String getTraceTypeId(String category, String traceType) { | |
554 | for (String key : fTraceTypes.keySet()) { | |
555 | if (fTraceTypes.get(key).getCategoryName().equals(category.trim()) && fTraceTypes.get(key).getName().equals(traceType.trim())) { | |
556 | return key; | |
557 | } | |
558 | } | |
559 | return null; | |
560 | } | |
76fccfb0 MK |
561 | |
562 | /** | |
563 | * Is the trace a custom (user-defined) trace type. These are the traces | |
564 | * like : text and xml defined by the custom trace wizard. | |
565 | * | |
566 | * @param traceType | |
567 | * the trace type in human form (category:name) | |
568 | * @return true if the trace is a custom type | |
569 | * @since 2.1 | |
570 | */ | |
571 | public static boolean isCustomTrace(String traceType) { | |
572 | final boolean startsWithTxt = traceType.startsWith(TmfTraceType.CUSTOM_TXT_CATEGORY); | |
573 | final boolean startsWithXML = traceType.startsWith(TmfTraceType.CUSTOM_XML_CATEGORY); | |
574 | return (startsWithTxt || startsWithXML); | |
575 | } | |
576 | ||
26e33e67 | 577 | /** |
4958a213 MK |
578 | * Is the trace type id a custom (user-defined) trace type. These are the |
579 | * traces like : text and xml defined by the custom trace wizard. | |
26e33e67 MAL |
580 | * |
581 | * @param traceTypeId | |
582 | * the trace type id | |
583 | * @return true if the trace is a custom type | |
584 | */ | |
585 | private static boolean isCustomTraceId(String traceTypeId) { | |
586 | TraceTypeHelper traceType = getInstance().getTraceType(traceTypeId); | |
587 | if (traceType != null) { | |
588 | return isCustomTrace(traceType.getCategoryName() + SEPARATOR + traceType.getName()); | |
589 | } | |
590 | ||
591 | return false; | |
592 | } | |
593 | ||
76fccfb0 MK |
594 | /** |
595 | * Gets the custom trace type ID from the custom trace name | |
596 | * | |
597 | * @param traceType | |
598 | * The trace type in human form (category:name) | |
599 | * @return the trace type ID or null if the trace is not a custom one | |
600 | * @since 2.1 | |
601 | */ | |
602 | public static String getCustomTraceTypeId(String traceType) { | |
603 | String traceTypeId = null; | |
604 | ||
605 | // do custom trace stuff here | |
606 | String traceTypeToken[] = traceType.split(":", 2); //$NON-NLS-1$ | |
607 | if (traceTypeToken.length == 2) { | |
608 | final boolean startsWithTxt = traceType.startsWith(TmfTraceType.CUSTOM_TXT_CATEGORY); | |
609 | final boolean startsWithXML = traceType.startsWith(TmfTraceType.CUSTOM_XML_CATEGORY); | |
610 | if (startsWithTxt) { | |
611 | traceTypeId = CustomTxtTrace.class.getCanonicalName() + SEPARATOR + traceTypeToken[1]; | |
612 | } else if (startsWithXML) { | |
613 | traceTypeId = CustomXmlTrace.class.getCanonicalName() + SEPARATOR + traceTypeToken[1]; | |
614 | } | |
615 | } | |
616 | return traceTypeId; | |
617 | } | |
618 | ||
4958a213 MK |
619 | TraceTypeHelper selectTraceType(String path, Shell shell) throws TmfTraceImportException { |
620 | return selectTraceType(path, shell, null); | |
621 | } | |
622 | ||
76fccfb0 | 623 | /** |
4958a213 MK |
624 | * This member figures out the trace type of a given file. It will prompt |
625 | * the user if it needs more information to properly pick the trace type. | |
76fccfb0 MK |
626 | * |
627 | * @param path | |
628 | * The path of file to import | |
629 | * @param shell | |
630 | * a shell to display the message to. If it is null, it is | |
631 | * assumed to be cancelled. | |
4958a213 MK |
632 | * @param traceTypeHint the ID of a trace (like "o.e.l.specifictrace" ) |
633 | * @return null if the request is cancelled or a TraceTypeHelper if it passes. | |
76fccfb0 MK |
634 | * @throws TmfTraceImportException |
635 | * if the traces don't match or there are errors in the trace | |
636 | * file | |
f7885d6d | 637 | * @since 2.2 |
76fccfb0 | 638 | */ |
f7885d6d | 639 | public TraceTypeHelper selectTraceType(String path, Shell shell, String traceTypeHint) throws TmfTraceImportException { |
507b1336 | 640 | List<TraceTypeHelper> validCandidates = new ArrayList<>(); |
76fccfb0 MK |
641 | getCustomTraceTypes(); |
642 | final Set<String> traceTypes = fTraceTypes.keySet(); | |
643 | for (String traceType : traceTypes) { | |
644 | if (validate(traceType, path)) { | |
645 | validCandidates.add(fTraceTypes.get(traceType)); | |
646 | } | |
647 | } | |
648 | ||
4958a213 | 649 | TraceTypeHelper traceTypeToSet = null; |
76fccfb0 MK |
650 | if (validCandidates.isEmpty()) { |
651 | final String errorMsg = Messages.TmfOpenTraceHelper_NoTraceTypeMatch + path; | |
652 | throw new TmfTraceImportException(errorMsg); | |
653 | } else if (validCandidates.size() != 1) { | |
654 | List<TraceTypeHelper> reducedCandidates = reduce(validCandidates); | |
4958a213 MK |
655 | for (TraceTypeHelper tth : reducedCandidates) { |
656 | if (tth.getCanonicalName().equals(traceTypeHint)) { | |
657 | traceTypeToSet = tth; | |
658 | } | |
659 | } | |
660 | if (traceTypeToSet == null) { | |
661 | if (reducedCandidates.size() == 0) { | |
662 | throw new TmfTraceImportException(Messages.TmfOpenTraceHelper_ReduceError); | |
663 | } else if (reducedCandidates.size() == 1) { | |
664 | traceTypeToSet = reducedCandidates.get(0); | |
665 | } else { | |
666 | if (shell == null) { | |
667 | return null; | |
668 | } | |
669 | traceTypeToSet = getTraceTypeToSet(reducedCandidates, shell); | |
76fccfb0 | 670 | } |
76fccfb0 | 671 | } |
76fccfb0 MK |
672 | } else { |
673 | traceTypeToSet = validCandidates.get(0); | |
674 | } | |
675 | return traceTypeToSet; | |
676 | } | |
677 | ||
678 | private static List<TraceTypeHelper> reduce(List<TraceTypeHelper> candidates) { | |
507b1336 | 679 | List<TraceTypeHelper> retVal = new ArrayList<>(); |
76fccfb0 MK |
680 | |
681 | // get all the tracetypes that are unique in that stage | |
682 | for (TraceTypeHelper trace : candidates) { | |
683 | if (isUnique(trace, candidates)) { | |
684 | retVal.add(trace); | |
685 | } | |
686 | } | |
687 | return retVal; | |
688 | } | |
689 | ||
690 | /* | |
691 | * Only return the leaves of the trace types. Ignore custom trace types. | |
692 | */ | |
693 | private static boolean isUnique(TraceTypeHelper trace, List<TraceTypeHelper> set) { | |
26e33e67 | 694 | if (TmfTraceType.isCustomTraceId(trace.getCanonicalName())) { |
76fccfb0 MK |
695 | return true; |
696 | } | |
697 | // check if the trace type is the leaf. we make an instance of the trace | |
698 | // type and if it is only an instance of itself, it is a leaf | |
699 | final ITmfTrace tmfTrace = trace.getTrace(); | |
700 | int count = -1; | |
701 | for (TraceTypeHelper child : set) { | |
702 | final ITmfTrace traceCandidate = child.getTrace(); | |
703 | if (tmfTrace.getClass().isInstance(traceCandidate)) { | |
704 | count++; | |
705 | } | |
706 | } | |
707 | return count == 0; | |
708 | } | |
709 | ||
710 | private TraceTypeHelper getTraceTypeToSet(List<TraceTypeHelper> candidates, Shell shell) { | |
507b1336 | 711 | final Map<String, String> names = new HashMap<>(); |
76fccfb0 | 712 | Shell shellToShow = new Shell(shell); |
043ad4df | 713 | shellToShow.setText(Messages.TmfTraceType_SelectTraceType); |
76fccfb0 MK |
714 | final String candidatesToSet[] = new String[1]; |
715 | for (TraceTypeHelper candidate : candidates) { | |
716 | Button b = new Button(shellToShow, SWT.RADIO); | |
717 | final String displayName = candidate.getCategoryName() + ':' + candidate.getName(); | |
718 | b.setText(displayName); | |
719 | names.put(displayName, candidate.getCanonicalName()); | |
720 | ||
721 | b.addSelectionListener(new SelectionListener() { | |
722 | ||
723 | @Override | |
724 | public void widgetSelected(SelectionEvent e) { | |
725 | final Button source = (Button) e.getSource(); | |
726 | candidatesToSet[0] = (names.get(source.getText())); | |
727 | source.getParent().dispose(); | |
728 | } | |
729 | ||
730 | @Override | |
731 | public void widgetDefaultSelected(SelectionEvent e) { | |
732 | ||
733 | } | |
734 | }); | |
735 | } | |
736 | shellToShow.setLayout(new RowLayout(SWT.VERTICAL)); | |
737 | shellToShow.pack(); | |
738 | shellToShow.open(); | |
739 | ||
740 | Display display = shellToShow.getDisplay(); | |
741 | while (!shellToShow.isDisposed()) { | |
742 | if (!display.readAndDispatch()) { | |
743 | display.sleep(); | |
744 | } | |
745 | } | |
746 | return fTraceTypes.get(candidatesToSet[0]); | |
747 | } | |
748 | ||
749 | /** | |
750 | * Set the trace type of a {@Link TraceTypeHelper}. Should only be | |
751 | * used internally by this project. | |
752 | * | |
753 | * @param path | |
754 | * the {@link IPath} path of the resource to set | |
755 | * @param traceType | |
756 | * the {@link TraceTypeHelper} to set the trace type to. | |
757 | * @return Status.OK_Status if successful, error is otherwise. | |
758 | * @throws CoreException | |
759 | * An exception caused by accessing eclipse project items. | |
ef9f0c61 | 760 | * @since 2.1 |
76fccfb0 | 761 | */ |
cd9821de | 762 | public static IStatus setTraceType(IPath path, TraceTypeHelper traceType) throws CoreException { |
76fccfb0 MK |
763 | IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(path); |
764 | String TRACE_NAME = path.lastSegment(); | |
765 | String traceBundle = null, traceTypeId = traceType.getCanonicalName(), traceIcon = null; | |
26e33e67 | 766 | if (TmfTraceType.isCustomTraceId(traceTypeId)) { |
76fccfb0 MK |
767 | traceBundle = Activator.getDefault().getBundle().getSymbolicName(); |
768 | traceIcon = DEFAULT_TRACE_ICON_PATH; | |
769 | } else { | |
770 | IConfigurationElement ce = TmfTraceType.getInstance().getTraceAttributes(traceTypeId); | |
771 | traceBundle = ce.getContributor().getName(); | |
772 | traceIcon = ce.getAttribute(TmfTraceType.ICON_ATTR); | |
773 | } | |
774 | ||
775 | resource.setPersistentProperty(TmfCommonConstants.TRACEBUNDLE, traceBundle); | |
776 | resource.setPersistentProperty(TmfCommonConstants.TRACETYPE, traceTypeId); | |
777 | resource.setPersistentProperty(TmfCommonConstants.TRACEICON, traceIcon); | |
778 | ||
779 | TmfProjectElement tmfProject = TmfProjectRegistry.getProject(resource.getProject()); | |
780 | if (tmfProject != null) { | |
781 | final TmfTraceFolder tracesFolder = tmfProject.getTracesFolder(); | |
782 | tracesFolder.refresh(); | |
783 | ||
784 | List<TmfTraceElement> traces = tracesFolder.getTraces(); | |
785 | boolean found = false; | |
786 | for (TmfTraceElement traceElement : traces) { | |
787 | if (traceElement.getName().equals(resource.getName())) { | |
788 | traceElement.refreshTraceType(); | |
789 | found = true; | |
790 | break; | |
791 | } | |
792 | } | |
793 | if (!found) { | |
794 | TmfTraceElement te = new TmfTraceElement(TRACE_NAME, resource, tracesFolder); | |
795 | te.refreshTraceType(); | |
796 | traces = tracesFolder.getTraces(); | |
797 | for (TmfTraceElement traceElement : traces) { | |
798 | traceElement.refreshTraceType(); | |
799 | } | |
800 | } | |
801 | } | |
802 | return Status.OK_STATUS; | |
803 | } | |
804 | ||
4bf17f4a | 805 | } |