1 /*******************************************************************************
2 * Copyright (c) 2010, 2013 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, added
14 *******************************************************************************/
16 package org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
;
18 import java
.io
.ByteArrayInputStream
;
19 import java
.io
.InputStream
;
20 import java
.util
.Arrays
;
21 import java
.util
.HashMap
;
24 import org
.eclipse
.core
.resources
.IFile
;
25 import org
.eclipse
.core
.resources
.IFolder
;
26 import org
.eclipse
.core
.resources
.IResource
;
27 import org
.eclipse
.core
.runtime
.CoreException
;
28 import org
.eclipse
.core
.runtime
.IConfigurationElement
;
29 import org
.eclipse
.core
.runtime
.Platform
;
30 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Activator
;
31 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomTxtEvent
;
32 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomTxtTrace
;
33 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomTxtTraceDefinition
;
34 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomXmlEvent
;
35 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomXmlTrace
;
36 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomXmlTraceDefinition
;
37 import org
.eclipse
.linuxtools
.tmf
.core
.TmfCommonConstants
;
38 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
39 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
40 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfTrace
;
41 import org
.eclipse
.linuxtools
.tmf
.core
.util
.ReadOnlyTextPropertyDescriptor
;
42 import org
.eclipse
.linuxtools
.tmf
.ui
.editors
.TmfEventsEditor
;
43 import org
.eclipse
.ui
.IActionFilter
;
44 import org
.eclipse
.ui
.views
.properties
.IPropertyDescriptor
;
45 import org
.eclipse
.ui
.views
.properties
.IPropertySource2
;
48 * Implementation of trace model element representing a trace. It provides methods to instantiate
49 * <code>ITmfTrace</code> and <code>ITmfEvent</code> as well as editor ID from the trace type
50 * extension definition.
53 * @author Francois Chouinard
55 public class TmfTraceElement
extends TmfWithFolderElement
implements IActionFilter
, IPropertySource2
{
57 // ------------------------------------------------------------------------
59 // ------------------------------------------------------------------------
63 * Bundle attribute name
65 public static final String BUNDLE
= "bundle"; //$NON-NLS-1$
67 * IsLinked attribute name.
69 public static final String IS_LINKED
= "isLinked"; //$NON-NLS-1$
71 // Property View stuff
72 private static final String sfInfoCategory
= "Info"; //$NON-NLS-1$
73 private static final String sfName
= "name"; //$NON-NLS-1$
74 private static final String sfPath
= "path"; //$NON-NLS-1$
75 private static final String sfLocation
= "location"; //$NON-NLS-1$
76 private static final String sfEventType
= "type"; //$NON-NLS-1$
77 private static final String sfIsLinked
= "linked"; //$NON-NLS-1$
79 private static final ReadOnlyTextPropertyDescriptor sfNameDescriptor
= new ReadOnlyTextPropertyDescriptor(sfName
, sfName
);
80 private static final ReadOnlyTextPropertyDescriptor sfPathDescriptor
= new ReadOnlyTextPropertyDescriptor(sfPath
, sfPath
);
81 private static final ReadOnlyTextPropertyDescriptor sfLocationDescriptor
= new ReadOnlyTextPropertyDescriptor(sfLocation
, sfLocation
);
82 private static final ReadOnlyTextPropertyDescriptor sfTypeDescriptor
= new ReadOnlyTextPropertyDescriptor(sfEventType
, sfEventType
);
83 private static final ReadOnlyTextPropertyDescriptor sfIsLinkedDescriptor
= new ReadOnlyTextPropertyDescriptor(sfIsLinked
, sfIsLinked
);
85 private static final IPropertyDescriptor
[] sfDescriptors
= { sfNameDescriptor
, sfPathDescriptor
, sfLocationDescriptor
,
86 sfTypeDescriptor
, sfIsLinkedDescriptor
};
89 sfNameDescriptor
.setCategory(sfInfoCategory
);
90 sfPathDescriptor
.setCategory(sfInfoCategory
);
91 sfLocationDescriptor
.setCategory(sfInfoCategory
);
92 sfTypeDescriptor
.setCategory(sfInfoCategory
);
93 sfIsLinkedDescriptor
.setCategory(sfInfoCategory
);
96 private static final String BOOKMARKS_HIDDEN_FILE
= ".bookmarks"; //$NON-NLS-1$
98 // ------------------------------------------------------------------------
100 // ------------------------------------------------------------------------
102 // This trace type ID as defined in plugin.xml
103 private String fTraceTypeId
= null;
105 // ------------------------------------------------------------------------
106 // Static initialization
107 // ------------------------------------------------------------------------
109 // The mapping of available trace type IDs to their corresponding configuration element
110 private static final Map
<String
, IConfigurationElement
> sfTraceTypeAttributes
= new HashMap
<String
, IConfigurationElement
>();
111 private static final Map
<String
, IConfigurationElement
> sfTraceCategories
= new HashMap
<String
, IConfigurationElement
>();
114 * Initialize statically at startup by getting extensions from the platform extension registry.
116 public static void init() {
117 IConfigurationElement
[] config
= Platform
.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType
.TMF_TRACE_TYPE_ID
);
118 for (IConfigurationElement ce
: config
) {
119 String elementName
= ce
.getName();
120 if (elementName
.equals(TmfTraceType
.TYPE_ELEM
)) {
121 String traceTypeId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
122 sfTraceTypeAttributes
.put(traceTypeId
, ce
);
123 } else if (elementName
.equals(TmfTraceType
.CATEGORY_ELEM
)) {
124 String categoryId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
125 sfTraceCategories
.put(categoryId
, ce
);
130 // ------------------------------------------------------------------------
132 // ------------------------------------------------------------------------
135 * Creates trace model element under the trace folder.
136 * @param name The name of trace
137 * @param trace The trace resource.
138 * @param parent The parent element (trace folder)
140 public TmfTraceElement(String name
, IResource trace
, TmfTraceFolder parent
) {
141 this(name
, trace
, (TmfProjectModelElement
) parent
);
145 * Creates trace model element under the experiment folder.
146 * @param name The name of trace
147 * @param trace The trace resource.
148 * @param parent The parent element (experiment folder)
150 public TmfTraceElement(String name
, IResource trace
, TmfExperimentElement parent
) {
151 this(name
, trace
, (TmfProjectModelElement
) parent
);
154 private TmfTraceElement(String name
, IResource trace
, TmfProjectModelElement parent
) {
155 super(name
, trace
, parent
);
156 parent
.addChild(this);
160 // ------------------------------------------------------------------------
162 // ------------------------------------------------------------------------
164 * Returns the trace type ID.
165 * @return trace type ID.
167 public String
getTraceType() {
172 * Refreshes the trace type filed by reading the trace type persistent property of the resource
175 public void refreshTraceType() {
177 fTraceTypeId
= getResource().getPersistentProperty(TmfCommonConstants
.TRACETYPE
);
178 } catch (CoreException e
) {
179 Activator
.getDefault().logError("Error refreshing trace type pesistent property for trace " + getName(), e
); //$NON-NLS-1$
184 * Instantiate a <code>ITmfTrace</code> object based on the trace type and the corresponding extension.
186 * @return the <code>ITmfTrace</code> or <code>null</code> for an error
188 public ITmfTrace
instantiateTrace() {
191 // make sure that supplementary folder exists
192 refreshSupplementaryFolder();
194 if (fTraceTypeId
!= null) {
195 if (fTraceTypeId
.startsWith(CustomTxtTrace
.class.getCanonicalName())) {
196 for (CustomTxtTraceDefinition def
: CustomTxtTraceDefinition
.loadAll()) {
197 if (fTraceTypeId
.equals(CustomTxtTrace
.class.getCanonicalName() + ":" + def
.definitionName
)) { //$NON-NLS-1$
198 return new CustomTxtTrace(def
);
202 if (fTraceTypeId
.startsWith(CustomXmlTrace
.class.getCanonicalName())) {
203 for (CustomXmlTraceDefinition def
: CustomXmlTraceDefinition
.loadAll()) {
204 if (fTraceTypeId
.equals(CustomXmlTrace
.class.getCanonicalName() + ":" + def
.definitionName
)) { //$NON-NLS-1$
205 return new CustomXmlTrace(def
);
209 IConfigurationElement ce
= sfTraceTypeAttributes
.get(fTraceTypeId
);
210 ITmfTrace trace
= (ITmfTrace
) ce
.createExecutableExtension(TmfTraceType
.TRACE_TYPE_ATTR
);
213 } catch (CoreException e
) {
214 Activator
.getDefault().logError("Error instantiating ITmfTrace object for trace " + getName(), e
); //$NON-NLS-1$
220 * Instantiate a <code>ITmfEvent</code> object based on the trace type and the corresponding extension.
222 * @return the <code>ITmfEvent</code> or <code>null</code> for an error
224 public ITmfEvent
instantiateEvent() {
226 if (fTraceTypeId
!= null) {
227 if (fTraceTypeId
.startsWith(CustomTxtTrace
.class.getCanonicalName())) {
228 for (CustomTxtTraceDefinition def
: CustomTxtTraceDefinition
.loadAll()) {
229 if (fTraceTypeId
.equals(CustomTxtTrace
.class.getCanonicalName() + ":" + def
.definitionName
)) { //$NON-NLS-1$
230 return new CustomTxtEvent(def
);
234 if (fTraceTypeId
.startsWith(CustomXmlTrace
.class.getCanonicalName())) {
235 for (CustomXmlTraceDefinition def
: CustomXmlTraceDefinition
.loadAll()) {
236 if (fTraceTypeId
.equals(CustomXmlTrace
.class.getCanonicalName() + ":" + def
.definitionName
)) { //$NON-NLS-1$
237 return new CustomXmlEvent(def
);
241 IConfigurationElement ce
= sfTraceTypeAttributes
.get(fTraceTypeId
);
242 ITmfEvent event
= (ITmfEvent
) ce
.createExecutableExtension(TmfTraceType
.EVENT_TYPE_ATTR
);
245 } catch (CoreException e
) {
246 Activator
.getDefault().logError("Error instantiating ITmfEvent object for trace " + getName(), e
); //$NON-NLS-1$
252 * Returns the optional editor ID from the trace type extension.
253 * @return the editor ID or <code>null</code> if not defined.
255 public String
getEditorId() {
256 if (fTraceTypeId
!= null) {
257 if (fTraceTypeId
.startsWith(CustomTxtTrace
.class.getCanonicalName())) {
258 return TmfEventsEditor
.ID
;
260 if (fTraceTypeId
.startsWith(CustomXmlTrace
.class.getCanonicalName())) {
261 return TmfEventsEditor
.ID
;
263 IConfigurationElement ce
= sfTraceTypeAttributes
.get(fTraceTypeId
);
264 IConfigurationElement
[] defaultEditorCE
= ce
.getChildren(TmfTraceType
.DEFAULT_EDITOR_ELEM
);
265 if (defaultEditorCE
.length
== 1) {
266 return defaultEditorCE
[0].getAttribute(TmfTraceType
.ID_ATTR
);
273 * Returns the file resource used to store bookmarks after creating it if necessary.
274 * If the trace resource is a file, it is returned directly.
275 * If the trace resource is a folder, a linked file is returned.
276 * The file will be created if it does not exist.
277 * @return the bookmarks file
278 * @throws CoreException if the bookmarks file cannot be created
281 public IFile
createBookmarksFile() throws CoreException
{
282 IFile file
= getBookmarksFile();
283 if (fResource
instanceof IFolder
) {
284 if (!file
.exists()) {
285 final IFile bookmarksFile
= getProject().getTracesFolder().getResource().getFile(BOOKMARKS_HIDDEN_FILE
);
286 if (!bookmarksFile
.exists()) {
287 final InputStream source
= new ByteArrayInputStream(new byte[0]);
288 bookmarksFile
.create(source
, true, null);
290 bookmarksFile
.setHidden(true);
291 file
.createLink(bookmarksFile
.getLocation(), IResource
.REPLACE
, null);
292 file
.setHidden(true);
293 file
.setPersistentProperty(TmfCommonConstants
.TRACETYPE
, TmfTrace
.class.getCanonicalName());
300 * Returns the file resource used to store bookmarks.
301 * The file may not exist.
302 * @return the bookmarks file
305 public IFile
getBookmarksFile() {
307 if (fResource
instanceof IFile
) {
308 file
= (IFile
) fResource
;
309 } else if (fResource
instanceof IFolder
) {
310 final IFolder folder
= (IFolder
) fResource
;
311 file
= folder
.getFile(getName() + '_');
317 * Returns the <code>TmfTraceElement</code> located under the <code>TmfTracesFolder</code>.
319 * @return <code>this</code> if this element is under the <code>TmfTracesFolder</code>
320 * else the corresponding <code>TmfTraceElement</code> if this element is under
321 * <code>TmfExperimentElement</code>.
323 public TmfTraceElement
getElementUnderTraceFolder() {
325 // If trace is under an experiment, return original trace from the traces folder
326 if (getParent() instanceof TmfExperimentElement
) {
327 for (TmfTraceElement aTrace
: getProject().getTracesFolder().getTraces()) {
328 if (aTrace
.getName().equals(getName())) {
336 // ------------------------------------------------------------------------
338 // ------------------------------------------------------------------------
341 public boolean testAttribute(Object target
, String name
, String value
) {
342 if (name
.equals(IS_LINKED
)) {
343 boolean isLinked
= getResource().isLinked();
344 return Boolean
.toString(isLinked
).equals(value
);
349 // ------------------------------------------------------------------------
351 // ------------------------------------------------------------------------
354 * @see org.eclipse.linuxtools.tmf.ui.project.model.ITmfProjectModelElement#getProject()
357 public TmfProjectElement
getProject() {
358 if (getParent() instanceof TmfTraceFolder
) {
359 TmfTraceFolder folder
= (TmfTraceFolder
) getParent();
360 TmfProjectElement project
= (TmfProjectElement
) folder
.getParent();
363 if (getParent() instanceof TmfExperimentElement
) {
364 TmfExperimentElement experiment
= (TmfExperimentElement
) getParent();
365 TmfExperimentFolder folder
= (TmfExperimentFolder
) experiment
.getParent();
366 TmfProjectElement project
= (TmfProjectElement
) folder
.getParent();
372 // ------------------------------------------------------------------------
374 // ------------------------------------------------------------------------
378 * @see org.eclipse.ui.views.properties.IPropertySource#getEditableValue()
381 public Object
getEditableValue() {
387 * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors()
390 public IPropertyDescriptor
[] getPropertyDescriptors() {
391 return Arrays
.copyOf(sfDescriptors
, sfDescriptors
.length
);
396 * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(java.lang.Object)
399 public Object
getPropertyValue(Object id
) {
401 if (sfName
.equals(id
)) {
405 if (sfPath
.equals(id
)) {
406 return getPath().toString();
409 if (sfLocation
.equals(id
)) {
410 return getLocation().toString();
413 if (sfIsLinked
.equals(id
)) {
414 return Boolean
.valueOf(getResource().isLinked()).toString();
417 if (sfEventType
.equals(id
)) {
418 if (fTraceTypeId
!= null) {
419 IConfigurationElement ce
= sfTraceTypeAttributes
.get(fTraceTypeId
);
420 return (ce
!= null) ?
(getCategory(ce
) + " : " + ce
.getAttribute(TmfTraceType
.NAME_ATTR
)) : ""; //$NON-NLS-1$ //$NON-NLS-2$
427 private static String
getCategory(IConfigurationElement ce
) {
428 String categoryId
= ce
.getAttribute(TmfTraceType
.CATEGORY_ATTR
);
429 if (categoryId
!= null) {
430 IConfigurationElement category
= sfTraceCategories
.get(categoryId
);
431 if (category
!= null) {
432 return category
.getAttribute(TmfTraceType
.NAME_ATTR
);
435 return "[no category]"; //$NON-NLS-1$
440 * @see org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(java.lang.Object)
443 public void resetPropertyValue(Object id
) {
448 * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object, java.lang.Object)
451 public void setPropertyValue(Object id
, Object value
) {
456 * @see org.eclipse.ui.views.properties.IPropertySource2#isPropertyResettable(java.lang.Object)
459 public boolean isPropertyResettable(Object id
) {
465 * @see org.eclipse.ui.views.properties.IPropertySource2#isPropertySet(java.lang.Object)
468 public boolean isPropertySet(Object id
) {
473 * Copy this trace in the trace folder. No other parameters are mentioned so
474 * the trace is copied in this element's project trace folder
478 * @return the new Resource object
481 public TmfTraceElement
copy(String string
) {
482 TmfTraceFolder folder
= this.getProject().getTracesFolder();
483 IResource res
= super.copy(string
, false);
484 return new TmfTraceElement(string
, res
, folder
);