1 /*******************************************************************************
2 * Copyright (c) 2010, 2017 Ericsson, École Polytechnique de Montréal
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Francois Chouinard - Initial API and implementation
11 * Bernd Hufmann - Added supplementary files handling
12 * Geneviève Bastien - Moved supplementary files handling to parent class,
13 * added code to copy trace
14 * Patrick Tasse - Close editors to release resources
15 * Jean-Christian Kouame - added trace properties to be shown into
17 * Geneviève Bastien - Moved trace type related methods to parent class
18 *******************************************************************************/
20 package org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
;
22 import java
.util
.Arrays
;
23 import java
.util
.Date
;
24 import java
.util
.HashMap
;
25 import java
.util
.LinkedList
;
26 import java
.util
.List
;
29 import org
.eclipse
.core
.filesystem
.EFS
;
30 import org
.eclipse
.core
.filesystem
.IFileInfo
;
31 import org
.eclipse
.core
.resources
.IFile
;
32 import org
.eclipse
.core
.resources
.IFolder
;
33 import org
.eclipse
.core
.resources
.IResource
;
34 import org
.eclipse
.core
.runtime
.CoreException
;
35 import org
.eclipse
.core
.runtime
.IConfigurationElement
;
36 import org
.eclipse
.core
.runtime
.IPath
;
37 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
38 import org
.eclipse
.core
.runtime
.IStatus
;
39 import org
.eclipse
.core
.runtime
.Platform
;
40 import org
.eclipse
.core
.runtime
.Status
;
41 import org
.eclipse
.core
.runtime
.URIUtil
;
42 import org
.eclipse
.jdt
.annotation
.NonNull
;
43 import org
.eclipse
.osgi
.util
.NLS
;
44 import org
.eclipse
.swt
.graphics
.Image
;
45 import org
.eclipse
.swt
.widgets
.Display
;
46 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Activator
;
47 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.editors
.ITmfEventsEditorConstants
;
48 import org
.eclipse
.tracecompass
.tmf
.core
.TmfCommonConstants
;
49 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
50 import org
.eclipse
.tracecompass
.tmf
.core
.parsers
.custom
.CustomTxtEvent
;
51 import org
.eclipse
.tracecompass
.tmf
.core
.parsers
.custom
.CustomTxtTrace
;
52 import org
.eclipse
.tracecompass
.tmf
.core
.parsers
.custom
.CustomTxtTraceDefinition
;
53 import org
.eclipse
.tracecompass
.tmf
.core
.parsers
.custom
.CustomXmlEvent
;
54 import org
.eclipse
.tracecompass
.tmf
.core
.parsers
.custom
.CustomXmlTrace
;
55 import org
.eclipse
.tracecompass
.tmf
.core
.parsers
.custom
.CustomXmlTraceDefinition
;
56 import org
.eclipse
.tracecompass
.tmf
.core
.project
.model
.ITmfPropertiesProvider
;
57 import org
.eclipse
.tracecompass
.tmf
.core
.project
.model
.TmfTraceType
;
58 import org
.eclipse
.tracecompass
.tmf
.core
.project
.model
.TraceTypeHelper
;
59 import org
.eclipse
.tracecompass
.tmf
.core
.synchronization
.TimestampTransformFactory
;
60 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.ITmfTimestamp
;
61 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimestampFormat
;
62 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
63 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
64 import org
.eclipse
.tracecompass
.tmf
.ui
.editors
.TmfEventsEditor
;
65 import org
.eclipse
.tracecompass
.tmf
.ui
.properties
.ReadOnlyTextPropertyDescriptor
;
66 import org
.eclipse
.ui
.IActionFilter
;
67 import org
.eclipse
.ui
.views
.properties
.IPropertyDescriptor
;
68 import org
.eclipse
.ui
.views
.properties
.IPropertySource2
;
70 import com
.ibm
.icu
.text
.DateFormat
;
71 import com
.ibm
.icu
.text
.NumberFormat
;
74 * Implementation of trace model element representing a trace. It provides
75 * methods to instantiate <code>ITmfTrace</code> and <code>ITmfEvent</code> as
76 * well as editor ID from the trace type extension definition.
79 * @author Francois Chouinard
81 public class TmfTraceElement
extends TmfCommonProjectElement
implements IActionFilter
, IPropertySource2
{
83 // ------------------------------------------------------------------------
85 // ------------------------------------------------------------------------
89 * Bundle attribute name
91 public static final String BUNDLE
= "bundle"; //$NON-NLS-1$
93 * IsLinked attribute name.
95 public static final String IS_LINKED
= "isLinked"; //$NON-NLS-1$
97 // Property View stuff
98 private static final String RESOURCE_PROPERTIES_CATEGORY
= Messages
.TmfTraceElement_ResourceProperties
;
99 private static final String NAME
= Messages
.TmfTraceElement_Name
;
100 private static final String PATH
= Messages
.TmfTraceElement_Path
;
101 private static final String LOCATION
= Messages
.TmfTraceElement_Location
;
102 private static final String TRACE_TYPE
= Messages
.TmfTraceElement_EventType
;
103 private static final String TRACE_TYPE_ID
= Messages
.TmfTraceElement_TraceTypeId
;
104 private static final String IS_LINKED_PROPERTY
= Messages
.TmfTraceElement_IsLinked
;
105 private static final String SOURCE_LOCATION
= Messages
.TmfTraceElement_SourceLocation
;
106 private static final String TIME_OFFSET
= Messages
.TmfTraceElement_TimeOffset
;
107 private static final String LAST_MODIFIED
= Messages
.TmfTraceElement_LastModified
;
108 private static final String SIZE
= Messages
.TmfTraceElement_Size
;
109 private static final String TRACE_PROPERTIES_CATEGORY
= Messages
.TmfTraceElement_TraceProperties
;
111 private static final ReadOnlyTextPropertyDescriptor NAME_DESCRIPTOR
= new ReadOnlyTextPropertyDescriptor(NAME
, NAME
);
112 private static final ReadOnlyTextPropertyDescriptor PATH_DESCRIPTOR
= new ReadOnlyTextPropertyDescriptor(PATH
, PATH
);
113 private static final ReadOnlyTextPropertyDescriptor LOCATION_DESCRIPTOR
= new ReadOnlyTextPropertyDescriptor(LOCATION
, LOCATION
);
114 private static final ReadOnlyTextPropertyDescriptor TYPE_DESCRIPTOR
= new ReadOnlyTextPropertyDescriptor(TRACE_TYPE
, TRACE_TYPE
);
115 private static final ReadOnlyTextPropertyDescriptor TYPE_ID_DESCRIPTOR
= new ReadOnlyTextPropertyDescriptor(TRACE_TYPE_ID
, TRACE_TYPE_ID
);
116 private static final ReadOnlyTextPropertyDescriptor IS_LINKED_DESCRIPTOR
= new ReadOnlyTextPropertyDescriptor(IS_LINKED_PROPERTY
, IS_LINKED_PROPERTY
);
117 private static final ReadOnlyTextPropertyDescriptor SOURCE_LOCATION_DESCRIPTOR
= new ReadOnlyTextPropertyDescriptor(SOURCE_LOCATION
, SOURCE_LOCATION
);
118 private static final ReadOnlyTextPropertyDescriptor TIME_OFFSET_DESCRIPTOR
= new ReadOnlyTextPropertyDescriptor(TIME_OFFSET
, TIME_OFFSET
);
119 private static final ReadOnlyTextPropertyDescriptor LAST_MODIFIED_DESCRIPTOR
= new ReadOnlyTextPropertyDescriptor(LAST_MODIFIED
, LAST_MODIFIED
);
120 private static final ReadOnlyTextPropertyDescriptor SIZE_DESCRIPTOR
= new ReadOnlyTextPropertyDescriptor(SIZE
, SIZE
);
122 private static final IPropertyDescriptor
[] sfDescriptors
= { NAME_DESCRIPTOR
, PATH_DESCRIPTOR
, LOCATION_DESCRIPTOR
,
123 TYPE_DESCRIPTOR
, TYPE_ID_DESCRIPTOR
, IS_LINKED_DESCRIPTOR
, SOURCE_LOCATION_DESCRIPTOR
,
124 TIME_OFFSET_DESCRIPTOR
, LAST_MODIFIED_DESCRIPTOR
, SIZE_DESCRIPTOR
};
127 NAME_DESCRIPTOR
.setCategory(RESOURCE_PROPERTIES_CATEGORY
);
128 PATH_DESCRIPTOR
.setCategory(RESOURCE_PROPERTIES_CATEGORY
);
129 LOCATION_DESCRIPTOR
.setCategory(RESOURCE_PROPERTIES_CATEGORY
);
130 TYPE_DESCRIPTOR
.setCategory(RESOURCE_PROPERTIES_CATEGORY
);
131 TYPE_ID_DESCRIPTOR
.setCategory(RESOURCE_PROPERTIES_CATEGORY
);
132 IS_LINKED_DESCRIPTOR
.setCategory(RESOURCE_PROPERTIES_CATEGORY
);
133 SOURCE_LOCATION_DESCRIPTOR
.setCategory(RESOURCE_PROPERTIES_CATEGORY
);
134 TIME_OFFSET_DESCRIPTOR
.setCategory(RESOURCE_PROPERTIES_CATEGORY
);
135 LAST_MODIFIED_DESCRIPTOR
.setCategory(RESOURCE_PROPERTIES_CATEGORY
);
136 SIZE_DESCRIPTOR
.setCategory(RESOURCE_PROPERTIES_CATEGORY
);
139 private static final TmfTimestampFormat OFFSET_FORMAT
= new TmfTimestampFormat("T.SSS SSS SSS s"); //$NON-NLS-1$
141 private static final int FOLDER_MAX_COUNT
= 1024;
143 // ------------------------------------------------------------------------
144 // Static initialization
145 // ------------------------------------------------------------------------
147 // The mapping of available trace type IDs to their corresponding
148 // configuration element
149 private static final Map
<String
, IConfigurationElement
> TRACE_TYPE_ATTRIBUTES
= new HashMap
<>();
150 private static final Map
<String
, IConfigurationElement
> TRACE_TYPE_UI_ATTRIBUTES
= new HashMap
<>();
151 private static final Map
<String
, IConfigurationElement
> TRACE_CATEGORIES
= new HashMap
<>();
154 * Initialize statically at startup by getting extensions from the platform
155 * extension registry.
157 public static void init() {
158 /* Read the tmf.core "tracetype" extension point */
159 IConfigurationElement
[] config
= Platform
.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType
.TMF_TRACE_TYPE_ID
);
160 for (IConfigurationElement ce
: config
) {
161 switch (ce
.getName()) {
162 case TmfTraceType
.TYPE_ELEM
:
163 String traceTypeId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
164 TRACE_TYPE_ATTRIBUTES
.put(traceTypeId
, ce
);
166 case TmfTraceType
.CATEGORY_ELEM
:
167 String categoryId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
168 TRACE_CATEGORIES
.put(categoryId
, ce
);
175 * Read the corresponding tmf.ui "tracetypeui" extension point for this
176 * trace type, if it exists.
178 config
= Platform
.getExtensionRegistry().getConfigurationElementsFor(TmfTraceTypeUIUtils
.TMF_TRACE_TYPE_UI_ID
);
179 for (IConfigurationElement ce
: config
) {
180 String elemName
= ce
.getName();
181 if (TmfTraceTypeUIUtils
.TYPE_ELEM
.equals(elemName
)) {
182 String traceType
= ce
.getAttribute(TmfTraceTypeUIUtils
.TRACETYPE_ATTR
);
183 TRACE_TYPE_UI_ATTRIBUTES
.put(traceType
, ce
);
188 // ------------------------------------------------------------------------
190 // ------------------------------------------------------------------------
192 private class FileInfo
{
198 // ------------------------------------------------------------------------
200 // ------------------------------------------------------------------------
202 private FileInfo fFileInfo
;
203 private ITmfTimestamp fStartTime
= null;
204 private ITmfTimestamp fEndTime
= null;
206 // ------------------------------------------------------------------------
208 // ------------------------------------------------------------------------
210 * Constructor. Creates trace model element under the trace folder.
215 * The trace resource.
217 * The parent element (trace folder)
219 public TmfTraceElement(String name
, IResource trace
, TmfTraceFolder parent
) {
220 super(name
, trace
, parent
);
224 * Constructor. Creates trace model element under the experiment folder.
229 * The trace resource.
231 * The parent element (experiment folder)
233 public TmfTraceElement(String name
, IResource trace
, TmfExperimentElement parent
) {
234 super(name
, trace
, parent
);
237 // ------------------------------------------------------------------------
239 // ------------------------------------------------------------------------
245 public @NonNull Image
getIcon() {
246 Image icon
= super.getIcon();
247 return (icon
== null ? TmfProjectModelIcons
.DEFAULT_TRACE_ICON
: icon
);
254 public String
getLabelText() {
255 if (getParent() instanceof TmfExperimentElement
) {
256 return getElementPath();
262 * Instantiate a <code>ITmfTrace</code> object based on the trace type and
263 * the corresponding extension.
265 * @return the <code>ITmfTrace</code> or <code>null</code> for an error
268 public ITmfTrace
instantiateTrace() {
271 // make sure that supplementary folder exists
272 refreshSupplementaryFolder();
274 String traceTypeId
= getTraceType();
275 if (traceTypeId
!= null) {
276 if (CustomTxtTrace
.isCustomTraceTypeId(traceTypeId
)) {
277 for (CustomTxtTraceDefinition def
: CustomTxtTraceDefinition
.loadAll()) {
278 String id
= CustomTxtTrace
.buildTraceTypeId(def
.categoryName
, def
.definitionName
);
279 if (traceTypeId
.equals(id
)) {
280 return new CustomTxtTrace(def
);
284 if (CustomXmlTrace
.isCustomTraceTypeId(traceTypeId
)) {
285 for (CustomXmlTraceDefinition def
: CustomXmlTraceDefinition
.loadAll()) {
286 String id
= CustomXmlTrace
.buildTraceTypeId(def
.categoryName
, def
.definitionName
);
287 if (traceTypeId
.equals(id
)) {
288 return new CustomXmlTrace(def
);
292 IConfigurationElement ce
= TRACE_TYPE_ATTRIBUTES
.get(traceTypeId
);
296 ITmfTrace trace
= (ITmfTrace
) ce
.createExecutableExtension(TmfTraceType
.TRACE_TYPE_ATTR
);
299 } catch (CoreException e
) {
300 Activator
.getDefault().logError("Error instantiating ITmfTrace object for trace " + getName(), e
); //$NON-NLS-1$
306 * Instantiate a <code>ITmfEvent</code> object based on the trace type and
307 * the corresponding extension.
309 * @return the <code>ITmfEvent</code> or <code>null</code> for an error
311 public ITmfEvent
instantiateEvent() {
313 String traceTypeId
= getTraceType();
314 if (traceTypeId
!= null) {
315 if (CustomTxtTrace
.isCustomTraceTypeId(traceTypeId
)) {
316 for (CustomTxtTraceDefinition def
: CustomTxtTraceDefinition
.loadAll()) {
317 String id
= CustomTxtTrace
.buildTraceTypeId(def
.categoryName
, def
.definitionName
);
318 if (traceTypeId
.equals(id
)) {
319 return new CustomTxtEvent(def
);
323 if (CustomXmlTrace
.isCustomTraceTypeId(traceTypeId
)) {
324 for (CustomXmlTraceDefinition def
: CustomXmlTraceDefinition
.loadAll()) {
325 String id
= CustomXmlTrace
.buildTraceTypeId(def
.categoryName
, def
.definitionName
);
326 if (traceTypeId
.equals(id
)) {
327 return new CustomXmlEvent(def
);
331 IConfigurationElement ce
= TRACE_TYPE_ATTRIBUTES
.get(traceTypeId
);
335 ITmfEvent event
= (ITmfEvent
) ce
.createExecutableExtension(TmfTraceType
.EVENT_TYPE_ATTR
);
338 } catch (CoreException e
) {
339 Activator
.getDefault().logError("Error instantiating ITmfEvent object for trace " + getName(), e
); //$NON-NLS-1$
345 public String
getEditorId() {
346 String traceTypeId
= getTraceType();
347 if (traceTypeId
!= null) {
348 if (CustomTxtTrace
.isCustomTraceTypeId(traceTypeId
) || CustomXmlTrace
.isCustomTraceTypeId(traceTypeId
)) {
349 return TmfEventsEditor
.ID
;
352 IConfigurationElement ce
= TRACE_TYPE_UI_ATTRIBUTES
.get(getTraceType());
354 /* This trace type does not define UI attributes */
357 IConfigurationElement
[] defaultEditorCE
= ce
.getChildren(TmfTraceTypeUIUtils
.DEFAULT_EDITOR_ELEM
);
358 if (defaultEditorCE
.length
== 1) {
359 return defaultEditorCE
[0].getAttribute(TmfTraceType
.ID_ATTR
);
366 * Returns the file resource used to store bookmarks after creating it if
367 * necessary. If the trace resource is a file, it is returned directly. If
368 * the trace resource is a folder, a linked file is returned. The file will
369 * be created if it does not exist.
371 * @return the bookmarks file
372 * @throws CoreException
373 * if the bookmarks file cannot be created
376 public IFile
createBookmarksFile() throws CoreException
{
377 IFile file
= getBookmarksFile();
378 if (getResource() instanceof IFolder
) {
379 TmfTraceFolder tracesFolder
= getProject().getTracesFolder();
380 if (tracesFolder
== null) {
381 throw new CoreException(new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, Messages
.TmfProject_TracesFolderNotExists
));
383 return createBookmarksFile(tracesFolder
.getResource(), ITmfEventsEditorConstants
.TRACE_EDITOR_INPUT_TYPE
);
389 * Returns the file resource used to store bookmarks. The file may not
392 * @return the bookmarks file
395 public IFile
getBookmarksFile() {
397 IResource resource
= getResource();
398 if (resource
instanceof IFile
) {
399 file
= (IFile
) resource
;
400 } else if (resource
instanceof IFolder
) {
401 final IFolder folder
= (IFolder
) resource
;
402 file
= folder
.getFile(getName() + '_');
408 * Returns the <code>TmfTraceElement</code> located under the
409 * <code>TmfTracesFolder</code>.
411 * @return <code>this</code> if this element is under the
412 * <code>TmfTracesFolder</code> else the corresponding
413 * <code>TmfTraceElement</code> if this element is under
414 * <code>TmfExperimentElement</code>.
416 public TmfTraceElement
getElementUnderTraceFolder() {
418 // If trace is under an experiment, return original trace from the
420 if (getParent() instanceof TmfExperimentElement
) {
421 TmfTraceFolder tracesFolder
= getProject().getTracesFolder();
422 if (tracesFolder
!= null) {
423 for (TmfTraceElement aTrace
: tracesFolder
.getTraces()) {
424 if (aTrace
.getElementPath().equals(getElementPath())) {
434 public String
getTypeName() {
435 return Messages
.TmfTraceElement_TypeName
;
438 // ------------------------------------------------------------------------
440 // ------------------------------------------------------------------------
443 public boolean testAttribute(Object target
, String name
, String value
) {
444 if (name
.equals(IS_LINKED
)) {
445 boolean isLinked
= getResource().isLinked();
446 return Boolean
.toString(isLinked
).equals(value
);
451 // ------------------------------------------------------------------------
453 // ------------------------------------------------------------------------
456 public Object
getEditableValue() {
461 * Get the trace properties of this traceElement if the corresponding trace
462 * is opened in an editor
464 * @return a map with the names and values of the trace properties
465 * respectively as keys and values
467 private Map
<String
, String
> getTraceProperties() {
468 for (ITmfTrace openedTrace
: TmfTraceManager
.getInstance().getOpenedTraces()) {
469 for (ITmfTrace singleTrace
: TmfTraceManager
.getTraceSet(openedTrace
)) {
470 if (getElementUnderTraceFolder().getResource().equals(singleTrace
.getResource())) {
471 if (singleTrace
instanceof ITmfPropertiesProvider
) {
472 ITmfPropertiesProvider traceProperties
= (ITmfPropertiesProvider
) singleTrace
;
473 return traceProperties
.getProperties();
478 return new HashMap
<>();
482 public IPropertyDescriptor
[] getPropertyDescriptors() {
483 Map
<String
, String
> traceProperties
= getTraceProperties();
484 if (!traceProperties
.isEmpty()) {
485 IPropertyDescriptor
[] propertyDescriptorArray
= new IPropertyDescriptor
[traceProperties
.size() + sfDescriptors
.length
];
487 for (Map
.Entry
<String
, String
> varName
: traceProperties
.entrySet()) {
488 ReadOnlyTextPropertyDescriptor descriptor
= new ReadOnlyTextPropertyDescriptor(this.getName() + "_" + varName
.getKey(), varName
.getKey()); //$NON-NLS-1$
489 descriptor
.setCategory(TRACE_PROPERTIES_CATEGORY
);
490 propertyDescriptorArray
[index
] = descriptor
;
493 System
.arraycopy(sfDescriptors
, 0, propertyDescriptorArray
, index
, sfDescriptors
.length
);
494 return propertyDescriptorArray
;
496 return Arrays
.copyOf(sfDescriptors
, sfDescriptors
.length
);
500 public Object
getPropertyValue(Object id
) {
502 if (NAME
.equals(id
)) {
506 if (PATH
.equals(id
)) {
507 return getPath().toString();
510 if (LOCATION
.equals(id
)) {
511 return URIUtil
.toUnencodedString(getLocation());
514 if (IS_LINKED_PROPERTY
.equals(id
)) {
515 return Boolean
.valueOf(getResource().isLinked()).toString();
518 if (SOURCE_LOCATION
.equals(id
)) {
520 String sourceLocation
= getElementUnderTraceFolder().getResource().getPersistentProperty(TmfCommonConstants
.SOURCE_LOCATION
);
521 if (sourceLocation
!= null) {
522 return sourceLocation
;
524 } catch (CoreException e
) {
526 return ""; //$NON-NLS-1$
529 if (LAST_MODIFIED
.equals(id
)) {
530 FileInfo fileInfo
= getFileInfo();
531 if (fileInfo
== null) {
532 return ""; //$NON-NLS-1$
534 long date
= fileInfo
.lastModified
;
535 DateFormat format
= DateFormat
.getDateTimeInstance(DateFormat
.LONG
, DateFormat
.MEDIUM
);
536 return format
.format(new Date(date
));
539 if (SIZE
.equals(id
)) {
540 FileInfo fileInfo
= getFileInfo();
541 if (fileInfo
== null) {
542 return ""; //$NON-NLS-1$
544 if (getResource() instanceof IFolder
) {
545 if (fileInfo
.count
<= FOLDER_MAX_COUNT
) {
546 return NLS
.bind(Messages
.TmfTraceElement_FolderSizeString
,
547 NumberFormat
.getInstance().format(fileInfo
.size
), fileInfo
.count
);
549 return NLS
.bind(Messages
.TmfTraceElement_FolderSizeOverflowString
,
550 NumberFormat
.getInstance().format(fileInfo
.size
), FOLDER_MAX_COUNT
);
552 return NLS
.bind(Messages
.TmfTraceElement_FileSizeString
, NumberFormat
.getInstance().format(fileInfo
.size
));
555 if (TRACE_TYPE
.equals(id
)) {
556 if (getTraceType() != null) {
557 TraceTypeHelper helper
= TmfTraceType
.getTraceType(getTraceType());
558 if (helper
!= null) {
559 return helper
.getLabel();
562 return ""; //$NON-NLS-1$
565 if (TRACE_TYPE_ID
.equals(id
)) {
566 if (getTraceType() != null) {
567 TraceTypeHelper helper
= TmfTraceType
.getTraceType(getTraceType());
568 if (helper
!= null) {
569 return helper
.getTraceTypeId();
572 return ""; //$NON-NLS-1$
575 if (TIME_OFFSET
.equals(id
)) {
576 long offset
= TimestampTransformFactory
.getTimestampTransform(getElementUnderTraceFolder().getResource()).transform(0);
578 return OFFSET_FORMAT
.format(offset
);
580 return ""; //$NON-NLS-1$
583 Map
<String
, String
> traceProperties
= getTraceProperties();
584 if (id
!= null && !traceProperties
.isEmpty()) {
585 String key
= (String
) id
;
586 key
= key
.substring(this.getName().length() + 1); // remove name_
587 String value
= traceProperties
.get(key
);
594 private FileInfo
getFileInfo() {
595 /* FileInfo is needed for both 'last modified' and 'size' properties.
596 * It is freshly computed for one, and reused for the other, then
597 * cleared so that the information can be refreshed the next time.
600 if (fFileInfo
== null) {
602 fileInfo
= computeFileInfo(new FileInfo(), getResource());
603 } catch (CoreException e
) {
606 fFileInfo
= fileInfo
;
608 fileInfo
= fFileInfo
;
614 private FileInfo
computeFileInfo(FileInfo fileInfo
, IResource resource
) throws CoreException
{
615 if (fileInfo
== null || fileInfo
.count
> FOLDER_MAX_COUNT
) {
618 if (resource
instanceof IFolder
) {
619 IFolder folder
= (IFolder
) resource
;
620 for (IResource member
: folder
.members()) {
621 computeFileInfo(fileInfo
, member
);
625 IFileInfo info
= EFS
.getStore(resource
.getLocationURI()).fetchInfo();
626 fileInfo
.lastModified
= Math
.max(fileInfo
.lastModified
, info
.getLastModified());
627 fileInfo
.size
+= info
.getLength();
633 public void resetPropertyValue(Object id
) {
637 public void setPropertyValue(Object id
, Object value
) {
641 public boolean isPropertyResettable(Object id
) {
646 public boolean isPropertySet(Object id
) {
651 * Copy this trace in the trace folder. No other parameters are mentioned so
652 * the trace is copied in this element's project trace folder
656 * @return the new Resource object
658 public TmfTraceElement
copy(String newName
) {
659 TmfTraceFolder folder
= (TmfTraceFolder
) getParent();
660 IResource res
= super.copy(newName
, false);
661 for (TmfTraceElement trace
: folder
.getTraces()) {
662 if (trace
.getResource().equals(res
)) {
670 * Close opened editors associated with this trace.
673 public void closeEditors() {
674 super.closeEditors();
676 // Close experiments that contain the trace if open
677 if (getParent() instanceof TmfTraceFolder
) {
678 TmfExperimentFolder experimentsFolder
= getProject().getExperimentsFolder();
679 if (experimentsFolder
!= null) {
680 for (TmfExperimentElement experiment
: experimentsFolder
.getExperiments()) {
681 for (TmfTraceElement trace
: experiment
.getTraces()) {
682 if (trace
.getElementPath().equals(getElementPath())) {
683 experiment
.closeEditors();
689 } else if (getParent() instanceof TmfExperimentElement
) {
690 TmfExperimentElement experiment
= (TmfExperimentElement
) getParent();
691 experiment
.closeEditors();
696 * Delete the trace resource, remove it from experiments and delete its
697 * supplementary files
699 * @param progressMonitor
700 * a progress monitor, or null if progress reporting is not
703 * @throws CoreException
704 * thrown when IResource.delete fails
706 public void delete(IProgressMonitor progressMonitor
) throws CoreException
{
707 // Close editors in UI Thread
708 Display
.getDefault().syncExec(new Runnable() {
715 IPath path
= getResource().getLocation();
717 if (getParent() instanceof TmfTraceFolder
) {
718 TmfExperimentFolder experimentFolder
= getProject().getExperimentsFolder();
720 // Propagate the removal to traces
721 if (experimentFolder
!= null) {
722 for (TmfExperimentElement experiment
: experimentFolder
.getExperiments()) {
723 List
<TmfTraceElement
> toRemove
= new LinkedList
<>();
724 for (TmfTraceElement trace
: experiment
.getTraces()) {
725 if (trace
.getElementPath().equals(getElementPath())) {
729 for (TmfTraceElement child
: toRemove
) {
730 experiment
.removeTrace(child
);
734 // Delete supplementary files
735 deleteSupplementaryFolder();
737 } else if (getParent() instanceof TmfExperimentElement
) {
738 TmfExperimentElement experimentElement
= (TmfExperimentElement
) getParent();
739 experimentElement
.removeTrace(this);
743 // Finally, delete the trace
744 getResource().delete(true, progressMonitor
);
748 * Update the trace's start time
751 * updated start time for this trace
754 public void setStartTime(ITmfTimestamp startTime
) {
755 fStartTime
= startTime
;
759 * Getter for the trace start time
761 * @return the start time from the trace if available, or from self when
762 * read in advance from supplementary files or from fast trace read.
763 * Return null if completely unknown.
766 public ITmfTimestamp
getStartTime() {
767 ITmfTrace trace
= getTrace();
769 setStartTime(trace
.getStartTime());
775 * Update the trace's end time
778 * updated end time for this trace
781 public void setEndTime(@NonNull ITmfTimestamp end
) {
782 if (fEndTime
== null || end
.compareTo(fEndTime
) > 0) {
788 * Getter for the trace end time
790 * @return the end time from the trace if available, or from self when read
791 * in advance from supplementary files or from fast trace read.
792 * Return null if completely unknown.
795 public ITmfTimestamp
getEndTime() {
796 ITmfTrace trace
= getTrace();
798 setEndTime(trace
.getEndTime());
804 public void deleteSupplementaryResources(IResource
[] resources
) {
805 /* Invalidate the cached trace bounds */
809 super.deleteSupplementaryResources(resources
);