releng: Fix invalid since tag in several files
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / project / model / TmfTraceElement.java
1 /*******************************************************************************
2 * Copyright (c) 2010, 2015 Ericsson, École Polytechnique de Montréal
3 *
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
8 *
9 * Contributors:
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
16 * the properties view
17 * Geneviève Bastien - Moved trace type related methods to parent class
18 *******************************************************************************/
19
20 package org.eclipse.tracecompass.tmf.ui.project.model;
21
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;
27 import java.util.Map;
28
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
47 import org.eclipse.tracecompass.internal.tmf.ui.Activator;
48 import org.eclipse.tracecompass.internal.tmf.ui.editors.ITmfEventsEditorConstants;
49 import org.eclipse.tracecompass.tmf.core.TmfCommonConstants;
50 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
51 import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtEvent;
52 import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTrace;
53 import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomTxtTraceDefinition;
54 import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlEvent;
55 import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTrace;
56 import org.eclipse.tracecompass.tmf.core.parsers.custom.CustomXmlTraceDefinition;
57 import org.eclipse.tracecompass.tmf.core.project.model.ITmfPropertiesProvider;
58 import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType;
59 import org.eclipse.tracecompass.tmf.core.project.model.TraceTypeHelper;
60 import org.eclipse.tracecompass.tmf.core.synchronization.TimestampTransformFactory;
61 import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
62 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat;
63 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
64 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
65 import org.eclipse.tracecompass.tmf.ui.editors.TmfEventsEditor;
66 import org.eclipse.tracecompass.tmf.ui.properties.ReadOnlyTextPropertyDescriptor;
67 import org.eclipse.ui.IActionFilter;
68 import org.eclipse.ui.views.properties.IPropertyDescriptor;
69 import org.eclipse.ui.views.properties.IPropertySource2;
70
71 import com.ibm.icu.text.DateFormat;
72 import com.ibm.icu.text.NumberFormat;
73
74 /**
75 * Implementation of trace model element representing a trace. It provides
76 * methods to instantiate <code>ITmfTrace</code> and <code>ITmfEvent</code> as
77 * well as editor ID from the trace type extension definition.
78 *
79 * @version 1.0
80 * @author Francois Chouinard
81 */
82 public class TmfTraceElement extends TmfCommonProjectElement implements IActionFilter, IPropertySource2 {
83
84 // ------------------------------------------------------------------------
85 // Constants
86 // ------------------------------------------------------------------------
87
88 // Other attributes
89 /**
90 * Bundle attribute name
91 */
92 public static final String BUNDLE = "bundle"; //$NON-NLS-1$
93 /**
94 * IsLinked attribute name.
95 */
96 public static final String IS_LINKED = "isLinked"; //$NON-NLS-1$
97
98 // Property View stuff
99 private static final String RESOURCE_PROPERTIES_CATEGORY = Messages.TmfTraceElement_ResourceProperties;
100 private static final String NAME = Messages.TmfTraceElement_Name;
101 private static final String PATH = Messages.TmfTraceElement_Path;
102 private static final String LOCATION = Messages.TmfTraceElement_Location;
103 private static final String TRACE_TYPE = Messages.TmfTraceElement_EventType;
104 private static final String TRACE_TYPE_ID = Messages.TmfTraceElement_TraceTypeId;
105 private static final String IS_LINKED_PROPERTY = Messages.TmfTraceElement_IsLinked;
106 private static final String SOURCE_LOCATION = Messages.TmfTraceElement_SourceLocation;
107 private static final String TIME_OFFSET = Messages.TmfTraceElement_TimeOffset;
108 private static final String LAST_MODIFIED = Messages.TmfTraceElement_LastModified;
109 private static final String SIZE = Messages.TmfTraceElement_Size;
110 private static final String TRACE_PROPERTIES_CATEGORY = Messages.TmfTraceElement_TraceProperties;
111
112 private static final ReadOnlyTextPropertyDescriptor NAME_DESCRIPTOR = new ReadOnlyTextPropertyDescriptor(NAME, NAME);
113 private static final ReadOnlyTextPropertyDescriptor PATH_DESCRIPTOR = new ReadOnlyTextPropertyDescriptor(PATH, PATH);
114 private static final ReadOnlyTextPropertyDescriptor LOCATION_DESCRIPTOR = new ReadOnlyTextPropertyDescriptor(LOCATION, LOCATION);
115 private static final ReadOnlyTextPropertyDescriptor TYPE_DESCRIPTOR = new ReadOnlyTextPropertyDescriptor(TRACE_TYPE, TRACE_TYPE);
116 private static final ReadOnlyTextPropertyDescriptor TYPE_ID_DESCRIPTOR = new ReadOnlyTextPropertyDescriptor(TRACE_TYPE_ID, TRACE_TYPE_ID);
117 private static final ReadOnlyTextPropertyDescriptor IS_LINKED_DESCRIPTOR = new ReadOnlyTextPropertyDescriptor(IS_LINKED_PROPERTY, IS_LINKED_PROPERTY);
118 private static final ReadOnlyTextPropertyDescriptor SOURCE_LOCATION_DESCRIPTOR = new ReadOnlyTextPropertyDescriptor(SOURCE_LOCATION, SOURCE_LOCATION);
119 private static final ReadOnlyTextPropertyDescriptor TIME_OFFSET_DESCRIPTOR = new ReadOnlyTextPropertyDescriptor(TIME_OFFSET, TIME_OFFSET);
120 private static final ReadOnlyTextPropertyDescriptor LAST_MODIFIED_DESCRIPTOR = new ReadOnlyTextPropertyDescriptor(LAST_MODIFIED, LAST_MODIFIED);
121 private static final ReadOnlyTextPropertyDescriptor SIZE_DESCRIPTOR = new ReadOnlyTextPropertyDescriptor(SIZE, SIZE);
122
123 private static final IPropertyDescriptor[] sfDescriptors = { NAME_DESCRIPTOR, PATH_DESCRIPTOR, LOCATION_DESCRIPTOR,
124 TYPE_DESCRIPTOR, TYPE_ID_DESCRIPTOR, IS_LINKED_DESCRIPTOR, SOURCE_LOCATION_DESCRIPTOR,
125 TIME_OFFSET_DESCRIPTOR, LAST_MODIFIED_DESCRIPTOR, SIZE_DESCRIPTOR };
126
127 static {
128 NAME_DESCRIPTOR.setCategory(RESOURCE_PROPERTIES_CATEGORY);
129 PATH_DESCRIPTOR.setCategory(RESOURCE_PROPERTIES_CATEGORY);
130 LOCATION_DESCRIPTOR.setCategory(RESOURCE_PROPERTIES_CATEGORY);
131 TYPE_DESCRIPTOR.setCategory(RESOURCE_PROPERTIES_CATEGORY);
132 TYPE_ID_DESCRIPTOR.setCategory(RESOURCE_PROPERTIES_CATEGORY);
133 IS_LINKED_DESCRIPTOR.setCategory(RESOURCE_PROPERTIES_CATEGORY);
134 SOURCE_LOCATION_DESCRIPTOR.setCategory(RESOURCE_PROPERTIES_CATEGORY);
135 TIME_OFFSET_DESCRIPTOR.setCategory(RESOURCE_PROPERTIES_CATEGORY);
136 LAST_MODIFIED_DESCRIPTOR.setCategory(RESOURCE_PROPERTIES_CATEGORY);
137 SIZE_DESCRIPTOR.setCategory(RESOURCE_PROPERTIES_CATEGORY);
138 }
139
140 private static final TmfTimestampFormat OFFSET_FORMAT = new TmfTimestampFormat("T.SSS SSS SSS s"); //$NON-NLS-1$
141
142 private static final int FOLDER_MAX_COUNT = 1024;
143
144 // ------------------------------------------------------------------------
145 // Static initialization
146 // ------------------------------------------------------------------------
147
148 // The mapping of available trace type IDs to their corresponding
149 // configuration element
150 private static final Map<String, IConfigurationElement> TRACE_TYPE_ATTRIBUTES = new HashMap<>();
151 private static final Map<String, IConfigurationElement> TRACE_TYPE_UI_ATTRIBUTES = new HashMap<>();
152 private static final Map<String, IConfigurationElement> TRACE_CATEGORIES = new HashMap<>();
153
154 /**
155 * Initialize statically at startup by getting extensions from the platform
156 * extension registry.
157 */
158 public static void init() {
159 /* Read the tmf.core "tracetype" extension point */
160 IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType.TMF_TRACE_TYPE_ID);
161 for (IConfigurationElement ce : config) {
162 switch (ce.getName()) {
163 case TmfTraceType.TYPE_ELEM:
164 String traceTypeId = ce.getAttribute(TmfTraceType.ID_ATTR);
165 TRACE_TYPE_ATTRIBUTES.put(traceTypeId, ce);
166 break;
167 case TmfTraceType.CATEGORY_ELEM:
168 String categoryId = ce.getAttribute(TmfTraceType.ID_ATTR);
169 TRACE_CATEGORIES.put(categoryId, ce);
170 break;
171 default:
172 }
173 }
174
175 /*
176 * Read the corresponding tmf.ui "tracetypeui" extension point for this
177 * trace type, if it exists.
178 */
179 config = Platform.getExtensionRegistry().getConfigurationElementsFor(TmfTraceTypeUIUtils.TMF_TRACE_TYPE_UI_ID);
180 for (IConfigurationElement ce : config) {
181 String elemName = ce.getName();
182 if (TmfTraceTypeUIUtils.TYPE_ELEM.equals(elemName)) {
183 String traceType = ce.getAttribute(TmfTraceTypeUIUtils.TRACETYPE_ATTR);
184 TRACE_TYPE_UI_ATTRIBUTES.put(traceType, ce);
185 }
186 }
187 }
188
189 // ------------------------------------------------------------------------
190 // Classes
191 // ------------------------------------------------------------------------
192
193 private class FileInfo {
194 long lastModified;
195 long size;
196 int count;
197 }
198
199 // ------------------------------------------------------------------------
200 // Attributes
201 // ------------------------------------------------------------------------
202
203 private FileInfo fFileInfo;
204 private ITmfTimestamp fStartTime = null;
205 private ITmfTimestamp fEndTime = null;
206
207 // ------------------------------------------------------------------------
208 // Constructors
209 // ------------------------------------------------------------------------
210 /**
211 * Constructor. Creates trace model element under the trace folder.
212 *
213 * @param name
214 * The name of trace
215 * @param trace
216 * The trace resource.
217 * @param parent
218 * The parent element (trace folder)
219 */
220 public TmfTraceElement(String name, IResource trace, TmfTraceFolder parent) {
221 super(name, trace, parent);
222 }
223
224 /**
225 * Constructor. Creates trace model element under the experiment folder.
226 *
227 * @param name
228 * The name of trace
229 * @param trace
230 * The trace resource.
231 * @param parent
232 * The parent element (experiment folder)
233 */
234 public TmfTraceElement(String name, IResource trace, TmfExperimentElement parent) {
235 super(name, trace, parent);
236 }
237
238 // ------------------------------------------------------------------------
239 // Operations
240 // ------------------------------------------------------------------------
241
242 /**
243 * @since 2.0
244 */
245 @Override
246 public @NonNull Image getIcon() {
247 Image icon = super.getIcon();
248 return (icon == null ? TmfProjectModelIcons.DEFAULT_TRACE_ICON : icon);
249 }
250
251 /**
252 * @since 2.0
253 */
254 @Override
255 public String getLabelText() {
256 if (getParent() instanceof TmfExperimentElement) {
257 return getElementPath();
258 }
259 return getName();
260 }
261
262 /**
263 * Instantiate a <code>ITmfTrace</code> object based on the trace type and
264 * the corresponding extension.
265 *
266 * @return the <code>ITmfTrace</code> or <code>null</code> for an error
267 */
268 @Override
269 public ITmfTrace instantiateTrace() {
270 try {
271
272 // make sure that supplementary folder exists
273 refreshSupplementaryFolder();
274
275 String traceTypeId = getTraceType();
276 if (traceTypeId != null) {
277 if (CustomTxtTrace.isCustomTraceTypeId(traceTypeId)) {
278 for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {
279 String id = CustomTxtTrace.buildTraceTypeId(def.categoryName, def.definitionName);
280 if (traceTypeId.equals(id)) {
281 return new CustomTxtTrace(def);
282 }
283 }
284 }
285 if (CustomXmlTrace.isCustomTraceTypeId(traceTypeId)) {
286 for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) {
287 String id = CustomXmlTrace.buildTraceTypeId(def.categoryName, def.definitionName);
288 if (traceTypeId.equals(id)) {
289 return new CustomXmlTrace(def);
290 }
291 }
292 }
293 IConfigurationElement ce = TRACE_TYPE_ATTRIBUTES.get(traceTypeId);
294 if (ce == null) {
295 return null;
296 }
297 ITmfTrace trace = (ITmfTrace) ce.createExecutableExtension(TmfTraceType.TRACE_TYPE_ATTR);
298 return trace;
299 }
300 } catch (CoreException e) {
301 Activator.getDefault().logError("Error instantiating ITmfTrace object for trace " + getName(), e); //$NON-NLS-1$
302 }
303 return null;
304 }
305
306 /**
307 * Instantiate a <code>ITmfEvent</code> object based on the trace type and
308 * the corresponding extension.
309 *
310 * @return the <code>ITmfEvent</code> or <code>null</code> for an error
311 */
312 public ITmfEvent instantiateEvent() {
313 try {
314 String traceTypeId = getTraceType();
315 if (traceTypeId != null) {
316 if (CustomTxtTrace.isCustomTraceTypeId(traceTypeId)) {
317 for (CustomTxtTraceDefinition def : CustomTxtTraceDefinition.loadAll()) {
318 String id = CustomTxtTrace.buildTraceTypeId(def.categoryName, def.definitionName);
319 if (traceTypeId.equals(id)) {
320 return new CustomTxtEvent(def);
321 }
322 }
323 }
324 if (CustomXmlTrace.isCustomTraceTypeId(traceTypeId)) {
325 for (CustomXmlTraceDefinition def : CustomXmlTraceDefinition.loadAll()) {
326 String id = CustomXmlTrace.buildTraceTypeId(def.categoryName, def.definitionName);
327 if (traceTypeId.equals(id)) {
328 return new CustomXmlEvent(def);
329 }
330 }
331 }
332 IConfigurationElement ce = TRACE_TYPE_ATTRIBUTES.get(traceTypeId);
333 if (ce == null) {
334 return null;
335 }
336 ITmfEvent event = (ITmfEvent) ce.createExecutableExtension(TmfTraceType.EVENT_TYPE_ATTR);
337 return event;
338 }
339 } catch (CoreException e) {
340 Activator.getDefault().logError("Error instantiating ITmfEvent object for trace " + getName(), e); //$NON-NLS-1$
341 }
342 return null;
343 }
344
345 @Override
346 public String getEditorId() {
347 String traceTypeId = getTraceType();
348 if (traceTypeId != null) {
349 if (CustomTxtTrace.isCustomTraceTypeId(traceTypeId) || CustomXmlTrace.isCustomTraceTypeId(traceTypeId)) {
350 return TmfEventsEditor.ID;
351 }
352
353 IConfigurationElement ce = TRACE_TYPE_UI_ATTRIBUTES.get(getTraceType());
354 if (ce == null) {
355 /* This trace type does not define UI attributes */
356 return null;
357 }
358 IConfigurationElement[] defaultEditorCE = ce.getChildren(TmfTraceTypeUIUtils.DEFAULT_EDITOR_ELEM);
359 if (defaultEditorCE.length == 1) {
360 return defaultEditorCE[0].getAttribute(TmfTraceType.ID_ATTR);
361 }
362 }
363 return null;
364 }
365
366 /**
367 * Returns the file resource used to store bookmarks after creating it if
368 * necessary. If the trace resource is a file, it is returned directly. If
369 * the trace resource is a folder, a linked file is returned. The file will
370 * be created if it does not exist.
371 *
372 * @return the bookmarks file
373 * @throws CoreException
374 * if the bookmarks file cannot be created
375 */
376 @Override
377 public IFile createBookmarksFile() throws CoreException {
378 IFile file = getBookmarksFile();
379 if (getResource() instanceof IFolder) {
380 TmfTraceFolder tracesFolder = getProject().getTracesFolder();
381 if (tracesFolder == null) {
382 throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.TmfProject_TracesFolderNotExists));
383 }
384 return createBookmarksFile(tracesFolder.getResource(), ITmfEventsEditorConstants.TRACE_EDITOR_INPUT_TYPE);
385 }
386 return file;
387 }
388
389 /**
390 * Returns the file resource used to store bookmarks. The file may not
391 * exist.
392 *
393 * @return the bookmarks file
394 */
395 @Override
396 public IFile getBookmarksFile() {
397 IFile file = null;
398 IResource resource = getResource();
399 if (resource instanceof IFile) {
400 file = (IFile) resource;
401 } else if (resource instanceof IFolder) {
402 final IFolder folder = (IFolder) resource;
403 file = folder.getFile(getName() + '_');
404 }
405 return file;
406 }
407
408 /**
409 * Returns the <code>TmfTraceElement</code> located under the
410 * <code>TmfTracesFolder</code>.
411 *
412 * @return <code>this</code> if this element is under the
413 * <code>TmfTracesFolder</code> else the corresponding
414 * <code>TmfTraceElement</code> if this element is under
415 * <code>TmfExperimentElement</code>.
416 */
417 public TmfTraceElement getElementUnderTraceFolder() {
418
419 // If trace is under an experiment, return original trace from the
420 // traces folder
421 if (getParent() instanceof TmfExperimentElement) {
422 TmfTraceFolder tracesFolder = getProject().getTracesFolder();
423 if (tracesFolder != null) {
424 for (TmfTraceElement aTrace : tracesFolder.getTraces()) {
425 if (aTrace.getElementPath().equals(getElementPath())) {
426 return aTrace;
427 }
428 }
429 }
430 }
431 return this;
432 }
433
434 @Override
435 public String getTypeName() {
436 return Messages.TmfTraceElement_TypeName;
437 }
438
439 // ------------------------------------------------------------------------
440 // IActionFilter
441 // ------------------------------------------------------------------------
442
443 @Override
444 public boolean testAttribute(Object target, String name, String value) {
445 if (name.equals(IS_LINKED)) {
446 boolean isLinked = getResource().isLinked();
447 return Boolean.toString(isLinked).equals(value);
448 }
449 return false;
450 }
451
452 // ------------------------------------------------------------------------
453 // IPropertySource2
454 // ------------------------------------------------------------------------
455
456 @Override
457 public Object getEditableValue() {
458 return null;
459 }
460
461 /**
462 * Get the trace properties of this traceElement if the corresponding trace
463 * is opened in an editor
464 *
465 * @return a map with the names and values of the trace properties
466 * respectively as keys and values
467 */
468 private Map<String, String> getTraceProperties() {
469 for (ITmfTrace openedTrace : TmfTraceManager.getInstance().getOpenedTraces()) {
470 for (ITmfTrace singleTrace : TmfTraceManager.getTraceSet(openedTrace)) {
471 if (getElementUnderTraceFolder().getResource().equals(singleTrace.getResource())) {
472 if (singleTrace instanceof ITmfPropertiesProvider) {
473 ITmfPropertiesProvider traceProperties = (ITmfPropertiesProvider) singleTrace;
474 return traceProperties.getProperties();
475 }
476 }
477 }
478 }
479 return new HashMap<>();
480 }
481
482 @Override
483 public IPropertyDescriptor[] getPropertyDescriptors() {
484 Map<String, String> traceProperties = getTraceProperties();
485 if (!traceProperties.isEmpty()) {
486 IPropertyDescriptor[] propertyDescriptorArray = new IPropertyDescriptor[traceProperties.size() + sfDescriptors.length];
487 int index = 0;
488 for (Map.Entry<String, String> varName : traceProperties.entrySet()) {
489 ReadOnlyTextPropertyDescriptor descriptor = new ReadOnlyTextPropertyDescriptor(this.getName() + "_" + varName.getKey(), varName.getKey()); //$NON-NLS-1$
490 descriptor.setCategory(TRACE_PROPERTIES_CATEGORY);
491 propertyDescriptorArray[index] = descriptor;
492 index++;
493 }
494 System.arraycopy(sfDescriptors, 0, propertyDescriptorArray, index, sfDescriptors.length);
495 return propertyDescriptorArray;
496 }
497 return Arrays.copyOf(sfDescriptors, sfDescriptors.length);
498 }
499
500 @Override
501 public Object getPropertyValue(Object id) {
502
503 if (NAME.equals(id)) {
504 return getName();
505 }
506
507 if (PATH.equals(id)) {
508 return getPath().toString();
509 }
510
511 if (LOCATION.equals(id)) {
512 return URIUtil.toUnencodedString(getLocation());
513 }
514
515 if (IS_LINKED_PROPERTY.equals(id)) {
516 return Boolean.valueOf(getResource().isLinked()).toString();
517 }
518
519 if (SOURCE_LOCATION.equals(id)) {
520 try {
521 String sourceLocation = getElementUnderTraceFolder().getResource().getPersistentProperty(TmfCommonConstants.SOURCE_LOCATION);
522 if (sourceLocation != null) {
523 return sourceLocation;
524 }
525 } catch (CoreException e) {
526 }
527 return ""; //$NON-NLS-1$
528 }
529
530 if (LAST_MODIFIED.equals(id)) {
531 FileInfo fileInfo = getFileInfo();
532 if (fileInfo == null) {
533 return ""; //$NON-NLS-1$
534 }
535 long date = fileInfo.lastModified;
536 DateFormat format = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.MEDIUM);
537 return format.format(new Date(date));
538 }
539
540 if (SIZE.equals(id)) {
541 FileInfo fileInfo = getFileInfo();
542 if (fileInfo == null) {
543 return ""; //$NON-NLS-1$
544 }
545 if (getResource() instanceof IFolder) {
546 if (fileInfo.count <= FOLDER_MAX_COUNT) {
547 return NLS.bind(Messages.TmfTraceElement_FolderSizeString,
548 NumberFormat.getInstance().format(fileInfo.size), fileInfo.count);
549 }
550 return NLS.bind(Messages.TmfTraceElement_FolderSizeOverflowString,
551 NumberFormat.getInstance().format(fileInfo.size), FOLDER_MAX_COUNT);
552 }
553 return NLS.bind(Messages.TmfTraceElement_FileSizeString, NumberFormat.getInstance().format(fileInfo.size));
554 }
555
556 if (TRACE_TYPE.equals(id)) {
557 if (getTraceType() != null) {
558 TraceTypeHelper helper = TmfTraceType.getTraceType(getTraceType());
559 if (helper != null) {
560 return helper.getLabel();
561 }
562 }
563 return ""; //$NON-NLS-1$
564 }
565
566 if (TRACE_TYPE_ID.equals(id)) {
567 if (getTraceType() != null) {
568 TraceTypeHelper helper = TmfTraceType.getTraceType(getTraceType());
569 if (helper != null) {
570 return helper.getTraceTypeId();
571 }
572 }
573 return ""; //$NON-NLS-1$
574 }
575
576 if (TIME_OFFSET.equals(id)) {
577 long offset = TimestampTransformFactory.getTimestampTransform(getElementUnderTraceFolder().getResource()).transform(0);
578 if (offset != 0) {
579 return OFFSET_FORMAT.format(offset);
580 }
581 return ""; //$NON-NLS-1$
582 }
583
584 Map<String, String> traceProperties = getTraceProperties();
585 if (id != null && !traceProperties.isEmpty()) {
586 String key = (String) id;
587 key = key.substring(this.getName().length() + 1); // remove name_
588 String value = traceProperties.get(key);
589 return value;
590 }
591
592 return null;
593 }
594
595 private FileInfo getFileInfo() {
596 /* FileInfo is needed for both 'last modified' and 'size' properties.
597 * It is freshly computed for one, and reused for the other, then
598 * cleared so that the information can be refreshed the next time.
599 */
600 FileInfo fileInfo;
601 if (fFileInfo == null) {
602 try {
603 fileInfo = computeFileInfo(new FileInfo(), getResource());
604 } catch (CoreException e) {
605 return null;
606 }
607 fFileInfo = fileInfo;
608 } else {
609 fileInfo = fFileInfo;
610 fFileInfo = null;
611 }
612 return fileInfo;
613 }
614
615 private FileInfo computeFileInfo(FileInfo fileInfo, IResource resource) throws CoreException {
616 if (fileInfo == null || fileInfo.count > FOLDER_MAX_COUNT) {
617 return fileInfo;
618 }
619 if (resource instanceof IFolder) {
620 IFolder folder = (IFolder) resource;
621 for (IResource member : folder.members()) {
622 computeFileInfo(fileInfo, member);
623 }
624 return fileInfo;
625 }
626 IFileInfo info = EFS.getStore(resource.getLocationURI()).fetchInfo();
627 fileInfo.lastModified = Math.max(fileInfo.lastModified, info.getLastModified());
628 fileInfo.size += info.getLength();
629 fileInfo.count++;
630 return fileInfo;
631 }
632
633 @Override
634 public void resetPropertyValue(Object id) {
635 }
636
637 @Override
638 public void setPropertyValue(Object id, Object value) {
639 }
640
641 @Override
642 public boolean isPropertyResettable(Object id) {
643 return false;
644 }
645
646 @Override
647 public boolean isPropertySet(Object id) {
648 return false;
649 }
650
651 /**
652 * Copy this trace in the trace folder. No other parameters are mentioned so
653 * the trace is copied in this element's project trace folder
654 *
655 * @param newName
656 * The new trace name
657 * @return the new Resource object
658 */
659 public TmfTraceElement copy(String newName) {
660 TmfTraceFolder folder = (TmfTraceFolder) getParent();
661 IResource res = super.copy(newName, false);
662 for (TmfTraceElement trace : folder.getTraces()) {
663 if (trace.getResource().equals(res)) {
664 return trace;
665 }
666 }
667 return null;
668 }
669
670 /**
671 * Close opened editors associated with this trace.
672 */
673 @Override
674 public void closeEditors() {
675 super.closeEditors();
676
677 // Close experiments that contain the trace if open
678 if (getParent() instanceof TmfTraceFolder) {
679 TmfExperimentFolder experimentsFolder = getProject().getExperimentsFolder();
680 if (experimentsFolder != null) {
681 for (TmfExperimentElement experiment : experimentsFolder.getExperiments()) {
682 for (TmfTraceElement trace : experiment.getTraces()) {
683 if (trace.getElementPath().equals(getElementPath())) {
684 experiment.closeEditors();
685 break;
686 }
687 }
688 }
689 }
690 } else if (getParent() instanceof TmfExperimentElement) {
691 TmfExperimentElement experiment = (TmfExperimentElement) getParent();
692 experiment.closeEditors();
693 }
694 }
695
696 /**
697 * Delete the trace resource, remove it from experiments and delete its
698 * supplementary files
699 *
700 * @param progressMonitor
701 * a progress monitor, or null if progress reporting is not
702 * desired
703 *
704 * @throws CoreException
705 * thrown when IResource.delete fails
706 */
707 public void delete(IProgressMonitor progressMonitor) throws CoreException {
708 // Close editors in UI Thread
709 Display.getDefault().syncExec(new Runnable() {
710 @Override
711 public void run() {
712 closeEditors();
713 }
714 });
715
716 IPath path = getResource().getLocation();
717 if (path != null) {
718 if (getParent() instanceof TmfTraceFolder) {
719 TmfExperimentFolder experimentFolder = getProject().getExperimentsFolder();
720
721 // Propagate the removal to traces
722 if (experimentFolder != null) {
723 for (TmfExperimentElement experiment : experimentFolder.getExperiments()) {
724 List<TmfTraceElement> toRemove = new LinkedList<>();
725 for (TmfTraceElement trace : experiment.getTraces()) {
726 if (trace.getElementPath().equals(getElementPath())) {
727 toRemove.add(trace);
728 }
729 }
730 for (TmfTraceElement child : toRemove) {
731 experiment.removeTrace(child);
732 }
733 }
734 }
735 // Delete supplementary files
736 deleteSupplementaryFolder();
737
738 } else if (getParent() instanceof TmfExperimentElement) {
739 TmfExperimentElement experimentElement = (TmfExperimentElement) getParent();
740 experimentElement.removeTrace(this);
741 }
742 }
743
744 // Finally, delete the trace
745 getResource().delete(true, progressMonitor);
746 }
747
748 /**
749 * Update the trace's start time
750 *
751 * @param startTime
752 * updated start time for this trace
753 * @since 2.4
754 */
755 public void setStartTime(ITmfTimestamp startTime) {
756 fStartTime = startTime;
757 }
758
759 /**
760 * Getter for the trace start time
761 *
762 * @return the start time from the trace if available, or from self when
763 * read in advance from supplementary files or from fast trace read.
764 * Return null if completely unknown.
765 * @since 2.4
766 */
767 public ITmfTimestamp getStartTime() {
768 ITmfTrace trace = getTrace();
769 if (trace != null) {
770 setStartTime(trace.getStartTime());
771 }
772 return fStartTime;
773 }
774
775 /**
776 * Update the trace's end time
777 *
778 * @param end
779 * updated end time for this trace
780 * @since 2.4
781 */
782 public void setEndTime(@NonNull ITmfTimestamp end) {
783 if (fEndTime == null || end.compareTo(fEndTime) > 0) {
784 fEndTime = end;
785 }
786 }
787
788 /**
789 * Getter for the trace end time
790 *
791 * @return the end time from the trace if available, or from self when read
792 * in advance from supplementary files or from fast trace read.
793 * Return null if completely unknown.
794 * @since 2.4
795 */
796 public ITmfTimestamp getEndTime() {
797 ITmfTrace trace = getTrace();
798 if (trace != null) {
799 setEndTime(trace.getEndTime());
800 }
801 return fEndTime;
802 }
803
804 @Override
805 public void deleteSupplementaryResources(IResource[] resources) {
806 /* Invalidate the cached trace bounds */
807 fStartTime = null;
808 fEndTime = null;
809
810 super.deleteSupplementaryResources(resources);
811 }
812
813 }
This page took 0.057865 seconds and 6 git commands to generate.