1
1
/*******************************************************************************
2
* Copyright (c) 2010, 2013 Ericsson, École Polytechnique de Montréal
2
* Copyright (c) 2010, 2014 Ericsson, École Polytechnique de Montréal
4
4
* All rights reserved. This program and the accompanying materials are
5
5
* made available under the terms of the Eclipse Public License v1.0 which
14
14
* Patrick Tasse - Close editors to release resources
15
15
* Jean-Christian Kouame - added trace properties to be shown into
16
16
* the properties view
17
* Geneviève Bastien - Moved trace type related methods to parent class
17
18
*******************************************************************************/
19
20
package org.eclipse.linuxtools.tmf.ui.project.model;
21
import java.io.ByteArrayInputStream;
22
import java.io.InputStream;
23
22
import java.util.Arrays;
24
23
import java.util.HashMap;
25
24
import java.util.LinkedList;
34
33
import org.eclipse.core.runtime.IPath;
35
34
import org.eclipse.core.runtime.IProgressMonitor;
36
35
import org.eclipse.core.runtime.Platform;
36
import org.eclipse.core.runtime.URIUtil;
37
37
import org.eclipse.linuxtools.internal.tmf.ui.Activator;
38
import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtEvent;
39
import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtTrace;
40
import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomTxtTraceDefinition;
41
import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomXmlEvent;
42
import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomXmlTrace;
43
import org.eclipse.linuxtools.internal.tmf.ui.parsers.custom.CustomXmlTraceDefinition;
44
38
import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
45
39
import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
40
import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtEvent;
41
import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTrace;
42
import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomTxtTraceDefinition;
43
import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlEvent;
44
import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTrace;
45
import org.eclipse.linuxtools.tmf.core.parsers.custom.CustomXmlTraceDefinition;
46
import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceType;
47
import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper;
46
48
import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
47
49
import org.eclipse.linuxtools.tmf.core.trace.ITmfTraceProperties;
48
50
import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;
50
52
import org.eclipse.linuxtools.tmf.ui.editors.TmfEventsEditor;
51
53
import org.eclipse.linuxtools.tmf.ui.properties.ReadOnlyTextPropertyDescriptor;
52
54
import org.eclipse.ui.IActionFilter;
53
import org.eclipse.ui.IEditorReference;
54
import org.eclipse.ui.IWorkbench;
55
import org.eclipse.ui.IWorkbenchPage;
56
import org.eclipse.ui.IWorkbenchWindow;
57
import org.eclipse.ui.PartInitException;
58
import org.eclipse.ui.PlatformUI;
59
import org.eclipse.ui.part.FileEditorInput;
60
55
import org.eclipse.ui.views.properties.IPropertyDescriptor;
61
56
import org.eclipse.ui.views.properties.IPropertySource2;
89
84
private static final String sfName = Messages.TmfTraceElement_Name;
90
85
private static final String sfPath = Messages.TmfTraceElement_Path;
91
86
private static final String sfLocation = Messages.TmfTraceElement_Location;
92
private static final String sfEventType = Messages.TmfTraceElement_EventType;
87
private static final String sfTraceType = Messages.TmfTraceElement_EventType;
93
88
private static final String sfIsLinked = Messages.TmfTraceElement_IsLinked;
89
private static final String sfSourceLocation = Messages.TmfTraceElement_SourceLocation;
94
90
private static final String sfTracePropertiesCategory = Messages.TmfTraceElement_TraceProperties;
96
92
private static final ReadOnlyTextPropertyDescriptor sfNameDescriptor = new ReadOnlyTextPropertyDescriptor(sfName, sfName);
97
93
private static final ReadOnlyTextPropertyDescriptor sfPathDescriptor = new ReadOnlyTextPropertyDescriptor(sfPath, sfPath);
98
94
private static final ReadOnlyTextPropertyDescriptor sfLocationDescriptor = new ReadOnlyTextPropertyDescriptor(sfLocation, sfLocation);
99
private static final ReadOnlyTextPropertyDescriptor sfTypeDescriptor = new ReadOnlyTextPropertyDescriptor(sfEventType, sfEventType);
95
private static final ReadOnlyTextPropertyDescriptor sfTypeDescriptor = new ReadOnlyTextPropertyDescriptor(sfTraceType, sfTraceType);
100
96
private static final ReadOnlyTextPropertyDescriptor sfIsLinkedDescriptor = new ReadOnlyTextPropertyDescriptor(sfIsLinked, sfIsLinked);
97
private static final ReadOnlyTextPropertyDescriptor sfSourceLocationDescriptor = new ReadOnlyTextPropertyDescriptor(sfSourceLocation, sfSourceLocation);
102
99
private static final IPropertyDescriptor[] sfDescriptors = { sfNameDescriptor, sfPathDescriptor, sfLocationDescriptor,
103
sfTypeDescriptor, sfIsLinkedDescriptor };
100
sfTypeDescriptor, sfIsLinkedDescriptor, sfSourceLocationDescriptor };
106
103
sfNameDescriptor.setCategory(sfResourcePropertiesCategory);
108
105
sfLocationDescriptor.setCategory(sfResourcePropertiesCategory);
109
106
sfTypeDescriptor.setCategory(sfResourcePropertiesCategory);
110
107
sfIsLinkedDescriptor.setCategory(sfResourcePropertiesCategory);
108
sfSourceLocationDescriptor.setCategory(sfResourcePropertiesCategory);
113
private static final String BOOKMARKS_HIDDEN_FILE = ".bookmarks"; //$NON-NLS-1$
115
// ------------------------------------------------------------------------
117
// ------------------------------------------------------------------------
119
// This trace type ID as defined in plugin.xml
120
private String fTraceTypeId = null;
122
111
// ------------------------------------------------------------------------
123
112
// Static initialization
124
113
// ------------------------------------------------------------------------
126
115
// The mapping of available trace type IDs to their corresponding
127
116
// configuration element
128
private static final Map<String, IConfigurationElement> sfTraceTypeAttributes = new HashMap<String, IConfigurationElement>();
129
private static final Map<String, IConfigurationElement> sfTraceCategories = new HashMap<String, IConfigurationElement>();
117
private static final Map<String, IConfigurationElement> sfTraceTypeAttributes = new HashMap<>();
118
private static final Map<String, IConfigurationElement> sfTraceTypeUIAttributes = new HashMap<>();
119
private static final Map<String, IConfigurationElement> sfTraceCategories = new HashMap<>();
132
122
* Initialize statically at startup by getting extensions from the platform
133
123
* extension registry.
135
125
public static void init() {
126
/* Read the tmf.core "tracetype" extension point */
136
127
IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType.TMF_TRACE_TYPE_ID);
137
128
for (IConfigurationElement ce : config) {
138
String elementName = ce.getName();
139
if (elementName.equals(TmfTraceType.TYPE_ELEM)) {
129
switch (ce.getName()) {
130
case TmfTraceType.TYPE_ELEM:
140
131
String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR);
141
132
sfTraceTypeAttributes.put(traceTypeId, ce);
142
} else if (elementName.equals(TmfTraceType.CATEGORY_ELEM)) {
134
case TmfTraceType.CATEGORY_ELEM:
143
135
String categoryId = ce.getAttribute(TmfTraceType.ID_ATTR);
144
136
sfTraceCategories.put(categoryId, ce);
143
* Read the corresponding tmf.ui "tracetypeui" extension point for this
144
* trace type, if it exists.
146
config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceTypeUIUtils.TMF_TRACE_TYPE_UI_ID);
147
for (IConfigurationElement ce : config) {
148
String elemName = ce.getName();
149
if (TmfTraceTypeUIUtils.TYPE_ELEM.equals(elemName)) {
150
String traceType = ce.getAttribute(TmfTraceTypeUIUtils.TRACETYPE_ATTR);
151
sfTraceTypeUIAttributes.put(traceType, ce);
160
167
* The parent element (trace folder)
162
169
public TmfTraceElement(String name, IResource trace, TmfTraceFolder parent) {
163
this(name, trace, (TmfProjectModelElement) parent);
170
super(name, trace, parent);
174
181
* The parent element (experiment folder)
176
183
public TmfTraceElement(String name, IResource trace, TmfExperimentElement parent) {
177
this(name, trace, (TmfProjectModelElement) parent);
180
private TmfTraceElement(String name, IResource trace, TmfProjectModelElement parent) {
181
184
super(name, trace, parent);
182
parent.addChild(this);
186
187
// ------------------------------------------------------------------------
188
189
// ------------------------------------------------------------------------
190
* Returns the trace type ID.
192
* @return trace type ID.
194
public String getTraceType() {
199
* Refreshes the trace type filed by reading the trace type persistent
200
* property of the resource referenece.
202
public void refreshTraceType() {
204
fTraceTypeId = getResource().getPersistentProperty(TmfCommonConstants.TRACETYPE);
205
} catch (CoreException e) {
206
Activator.getDefault().logError("Error refreshing trace type pesistent property for trace " + getName(), e); //$NON-NLS-1$
211
192
* Instantiate a <code>ITmfTrace</code> object based on the trace type and
214
195
* @return the <code>ITmfTrace</code> or <code>null</code> for an error
216
198
public ITmfTrace instantiateTrace() {
219
201
// make sure that supplementary folder exists
220
202
refreshSupplementaryFolder();
222
if (fTraceTypeId != null) {
223
if (fTraceTypeId.startsWith(CustomTxtTrace.class.getCanonicalName())) {
204
if (getTraceType() != null) {
205
if (getTraceType().startsWith(CustomTxtTrace.class.getCanonicalName())) {
224
206
for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {
225
if (fTraceTypeId.equals(CustomTxtTrace.class.getCanonicalName() + ":" + def.definitionName)) { //$NON-NLS-1$
207
if (getTraceType().equals(CustomTxtTrace.class.getCanonicalName() + ":" + def.definitionName)) { //$NON-NLS-1$
226
208
return new CustomTxtTrace(def);
230
if (fTraceTypeId.startsWith(CustomXmlTrace.class.getCanonicalName())) {
212
if (getTraceType().startsWith(CustomXmlTrace.class.getCanonicalName())) {
231
213
for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) {
232
if (fTraceTypeId.equals(CustomXmlTrace.class.getCanonicalName() + ":" + def.definitionName)) { //$NON-NLS-1$
214
if (getTraceType().equals(CustomXmlTrace.class.getCanonicalName() + ":" + def.definitionName)) { //$NON-NLS-1$
233
215
return new CustomXmlTrace(def);
237
IConfigurationElement ce = sfTraceTypeAttributes.get(fTraceTypeId);
219
IConfigurationElement ce = sfTraceTypeAttributes.get(getTraceType());
238
220
if (ce == null) {
256
238
public ITmfEvent instantiateEvent() {
258
if (fTraceTypeId != null) {
259
if (fTraceTypeId.startsWith(CustomTxtTrace.class.getCanonicalName())) {
240
if (getTraceType() != null) {
241
if (getTraceType().startsWith(CustomTxtTrace.class.getCanonicalName())) {
260
242
for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {
261
if (fTraceTypeId.equals(CustomTxtTrace.class.getCanonicalName() + ":" + def.definitionName)) { //$NON-NLS-1$
243
if (getTraceType().equals(CustomTxtTrace.class.getCanonicalName() + ":" + def.definitionName)) { //$NON-NLS-1$
262
244
return new CustomTxtEvent(def);
266
if (fTraceTypeId.startsWith(CustomXmlTrace.class.getCanonicalName())) {
248
if (getTraceType().startsWith(CustomXmlTrace.class.getCanonicalName())) {
267
249
for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) {
268
if (fTraceTypeId.equals(CustomXmlTrace.class.getCanonicalName() + ":" + def.definitionName)) { //$NON-NLS-1$
250
if (getTraceType().equals(CustomXmlTrace.class.getCanonicalName() + ":" + def.definitionName)) { //$NON-NLS-1$
269
251
return new CustomXmlEvent(def);
273
IConfigurationElement ce = sfTraceTypeAttributes.get(fTraceTypeId);
255
IConfigurationElement ce = sfTraceTypeAttributes.get(getTraceType());
274
256
if (ce == null) {
287
* Returns the optional editor ID from the trace type extension.
289
* @return the editor ID or <code>null</code> if not defined.
291
269
public String getEditorId() {
292
if (fTraceTypeId != null) {
293
if (fTraceTypeId.startsWith(CustomTxtTrace.class.getCanonicalName())) {
294
return TmfEventsEditor.ID;
296
if (fTraceTypeId.startsWith(CustomXmlTrace.class.getCanonicalName())) {
297
return TmfEventsEditor.ID;
299
IConfigurationElement ce = sfTraceTypeAttributes.get(fTraceTypeId);
300
IConfigurationElement[] defaultEditorCE = ce.getChildren(TmfTraceType.DEFAULT_EDITOR_ELEM);
270
if (getTraceType() != null) {
271
if (getTraceType().startsWith(CustomTxtTrace.class.getCanonicalName())) {
272
return TmfEventsEditor.ID;
274
if (getTraceType().startsWith(CustomXmlTrace.class.getCanonicalName())) {
275
return TmfEventsEditor.ID;
277
IConfigurationElement ce = sfTraceTypeUIAttributes.get(getTraceType());
279
/* This trace type does not define UI attributes */
282
IConfigurationElement[] defaultEditorCE = ce.getChildren(TmfTraceTypeUIUtils.DEFAULT_EDITOR_ELEM);
301
283
if (defaultEditorCE.length == 1) {
302
284
return defaultEditorCE[0].getAttribute(TmfTraceType.ID_ATTR);
316
298
* if the bookmarks file cannot be created
319
302
public IFile createBookmarksFile() throws CoreException {
320
303
IFile file = getBookmarksFile();
321
304
if (fResource instanceof IFolder) {
322
if (!file.exists()) {
323
final IFile bookmarksFile = getProject().getTracesFolder().getResource().getFile(BOOKMARKS_HIDDEN_FILE);
324
if (!bookmarksFile.exists()) {
325
final InputStream source = new ByteArrayInputStream(new byte[0]);
326
bookmarksFile.create(source, true, null);
328
bookmarksFile.setHidden(true);
329
file.createLink(bookmarksFile.getLocation(), IResource.REPLACE, null);
330
file.setHidden(true);
331
file.setPersistentProperty(TmfCommonConstants.TRACETYPE, TmfTrace.class.getCanonicalName());
305
return createBookmarksFile(getProject().getTracesFolder().getResource(), TmfTrace.class.getCanonicalName());
391
370
// ------------------------------------------------------------------------
393
// ------------------------------------------------------------------------
396
public TmfProjectElement getProject() {
397
if (getParent() instanceof TmfTraceFolder) {
398
TmfTraceFolder folder = (TmfTraceFolder) getParent();
399
TmfProjectElement project = (TmfProjectElement) folder.getParent();
402
if (getParent() instanceof TmfExperimentElement) {
403
TmfExperimentElement experiment = (TmfExperimentElement) getParent();
404
TmfExperimentFolder folder = (TmfExperimentFolder) experiment.getParent();
405
TmfProjectElement project = (TmfProjectElement) folder.getParent();
411
// ------------------------------------------------------------------------
412
371
// IPropertySource2
413
372
// ------------------------------------------------------------------------
427
386
private Map<String, String> getTraceProperties() {
428
387
for (ITmfTrace openedTrace : TmfTraceManager.getInstance().getOpenedTraces()) {
429
388
for (ITmfTrace singleTrace : TmfTraceManager.getTraceSet(openedTrace)) {
430
if (this.getLocation().toString().endsWith(singleTrace.getPath())) {
389
if (this.getLocation().getPath().endsWith(singleTrace.getPath())) {
431
390
if (singleTrace instanceof ITmfTraceProperties) {
432
391
ITmfTraceProperties traceProperties = (ITmfTraceProperties) singleTrace;
433
392
return traceProperties.getTraceProperties();
473
432
if (sfLocation.equals(id)) {
474
return getLocation().toString();
433
return URIUtil.toUnencodedString(getLocation());
477
436
if (sfIsLinked.equals(id)) {
478
437
return Boolean.valueOf(getResource().isLinked()).toString();
481
if (sfEventType.equals(id)) {
482
if (fTraceTypeId != null) {
483
IConfigurationElement ce = sfTraceTypeAttributes.get(fTraceTypeId);
484
return (ce != null) ? (getCategory(ce) + " : " + ce.getAttribute(TmfTraceType.NAME_ATTR)) : ""; //$NON-NLS-1$ //$NON-NLS-2$
440
if (sfSourceLocation.equals(id)) {
442
String sourceLocation = getElementUnderTraceFolder().getResource().getPersistentProperty(TmfCommonConstants.SOURCE_LOCATION);
443
if (sourceLocation != null) {
444
return sourceLocation;
446
} catch (CoreException e) {
448
return ""; //$NON-NLS-1$
451
if (sfTraceType.equals(id)) {
452
if (getTraceType() != null) {
453
TraceTypeHelper helper = TmfTraceType.getTraceTypeHelper(getTraceType());
454
if (helper != null) {
455
return helper.getCategoryName() + " : " + helper.getName(); //$NON-NLS-1$
458
return ""; //$NON-NLS-1$
488
461
Map<String, String> traceProperties = getTraceProperties();
489
462
if (id != null && !traceProperties.isEmpty()) {
490
463
String key = (String) id;
491
key = key.replaceFirst(this.getName() + "_", ""); //$NON-NLS-1$ //$NON-NLS-2$
464
key = key.substring(this.getName().length() + 1); // remove name_
492
465
String value = traceProperties.get(key);
499
private static String getCategory(IConfigurationElement ce) {
500
String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR);
501
if (categoryId != null) {
502
IConfigurationElement category = sfTraceCategories.get(categoryId);
503
if (category != null) {
504
return category.getAttribute(TmfTraceType.NAME_ATTR);
507
return "[no category]"; //$NON-NLS-1$
511
473
public void resetPropertyValue(Object id) {
529
491
* Copy this trace in the trace folder. No other parameters are mentioned so
530
492
* the trace is copied in this element's project trace folder
533
495
* The new trace name
534
496
* @return the new Resource object
537
public TmfTraceElement copy(String string) {
538
TmfTraceFolder folder = this.getProject().getTracesFolder();
539
IResource res = super.copy(string, false);
540
return new TmfTraceElement(string, res, folder);
499
public TmfTraceElement copy(String newName) {
500
TmfTraceFolder folder = (TmfTraceFolder) getParent();
501
IResource res = super.copy(newName, false);
502
for (TmfTraceElement trace : folder.getTraces()) {
503
if (trace.getResource().equals(res)) {
548
516
public void closeEditors() {
549
// Close the trace if open
550
IFile file = getBookmarksFile();
551
FileEditorInput input = new FileEditorInput(file);
552
IWorkbench wb = PlatformUI.getWorkbench();
553
for (IWorkbenchWindow wbWindow : wb.getWorkbenchWindows()) {
554
for (IWorkbenchPage wbPage : wbWindow.getPages()) {
555
for (IEditorReference editorReference : wbPage.getEditorReferences()) {
557
if (editorReference.getEditorInput().equals(input)) {
558
wbPage.closeEditor(editorReference.getEditor(false), false);
560
} catch (PartInitException e) {
561
Activator.getDefault().logError("Error closing editor for trace " + getName(), e); //$NON-NLS-1$
517
super.closeEditors();
567
519
// Close experiments that contain the trace if open
568
520
if (getParent() instanceof TmfTraceFolder) {
569
TmfExperimentFolder experimentFolder = getProject().getExperimentsFolder();
570
for (ITmfProjectModelElement experiment : experimentFolder.getChildren()) {
571
for (ITmfProjectModelElement child : experiment.getChildren()) {
572
if (child.getName().equals(getName())) {
573
((TmfExperimentElement) experiment).closeEditors();
521
TmfExperimentFolder experimentsFolder = getProject().getExperimentsFolder();
522
for (TmfExperimentElement experiment : experimentsFolder.getExperiments()) {
523
for (TmfTraceElement trace : experiment.getTraces()) {
524
if (trace.getElementPath().equals(getElementPath())) {
525
experiment.closeEditors();
579
531
TmfExperimentElement experiment = (TmfExperimentElement) getParent();
580
532
experiment.closeEditors();
536
* We will be closing a trace shortly. Invoke GC to release
537
* MappedByteBuffer objects, which some trace types, like CTF, use.
538
* (see Java bug JDK-4724038)
599
558
IPath path = fResource.getLocation();
600
if (path != null && (getParent() instanceof TmfTraceFolder)) {
601
TmfExperimentFolder experimentFolder = getProject().getExperimentsFolder();
603
// Propagate the removal to traces
604
for (ITmfProjectModelElement experiment : experimentFolder.getChildren()) {
605
List<ITmfProjectModelElement> toRemove = new LinkedList<ITmfProjectModelElement>();
606
for (ITmfProjectModelElement child : experiment.getChildren()) {
607
if (child.getName().equals(getName())) {
611
for (ITmfProjectModelElement child : toRemove) {
612
((TmfExperimentElement) experiment).removeTrace((TmfTraceElement) child);
560
if (getParent() instanceof TmfTraceFolder) {
561
TmfExperimentFolder experimentFolder = getProject().getExperimentsFolder();
563
// Propagate the removal to traces
564
for (TmfExperimentElement experiment : experimentFolder.getExperiments()) {
565
List<TmfTraceElement> toRemove = new LinkedList<>();
566
for (TmfTraceElement trace : experiment.getTraces()) {
567
if (trace.getElementPath().equals(getElementPath())) {
571
for (TmfTraceElement child : toRemove) {
572
experiment.removeTrace(child);
576
// Delete supplementary files
577
deleteSupplementaryFolder();
579
} else if (getParent() instanceof TmfExperimentElement) {
580
TmfExperimentElement experimentElement = (TmfExperimentElement) getParent();
581
experimentElement.removeTrace(this);
616
// Delete supplementary files
617
deleteSupplementaryFolder();
620
585
// Finally, delete the trace
621
586
fResource.delete(true, progressMonitor);
625
* Get the instantiated trace associated with this element.
627
* @return The instantiated trace or null if trace is not (yet) available
630
public ITmfTrace getTrace() {
631
for (ITmfTrace trace : TmfTraceManager.getInstance().getOpenedTraces()) {
632
if (trace.getResource().equals(getResource())) {