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