1 /*******************************************************************************
2 * Copyright (c) 2010, 2013 Ericsson
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 *******************************************************************************/
15 package org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
;
17 import java
.io
.ByteArrayInputStream
;
18 import java
.io
.InputStream
;
19 import java
.util
.Arrays
;
20 import java
.util
.HashMap
;
23 import org
.eclipse
.core
.resources
.IFile
;
24 import org
.eclipse
.core
.resources
.IFolder
;
25 import org
.eclipse
.core
.resources
.IResource
;
26 import org
.eclipse
.core
.runtime
.CoreException
;
27 import org
.eclipse
.core
.runtime
.IConfigurationElement
;
28 import org
.eclipse
.core
.runtime
.Platform
;
29 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Activator
;
30 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomTxtEvent
;
31 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomTxtTrace
;
32 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomTxtTraceDefinition
;
33 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomXmlEvent
;
34 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomXmlTrace
;
35 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomXmlTraceDefinition
;
36 import org
.eclipse
.linuxtools
.tmf
.core
.TmfCommonConstants
;
37 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
38 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
39 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfTrace
;
40 import org
.eclipse
.linuxtools
.tmf
.ui
.editors
.TmfEventsEditor
;
41 import org
.eclipse
.ui
.IActionFilter
;
42 import org
.eclipse
.ui
.views
.properties
.IPropertyDescriptor
;
43 import org
.eclipse
.ui
.views
.properties
.IPropertySource2
;
44 import org
.eclipse
.ui
.views
.properties
.TextPropertyDescriptor
;
47 * Implementation of trace model element representing a trace. It provides methods to instantiate
48 * <code>ITmfTrace</code> and <code>ITmfEvent</code> as well as editor ID from the trace type
49 * extension definition.
52 * @author Francois Chouinard
54 public class TmfTraceElement
extends TmfWithFolderElement
implements IActionFilter
, IPropertySource2
{
56 // ------------------------------------------------------------------------
58 // ------------------------------------------------------------------------
62 * Bundle attribute name
64 public static final String BUNDLE
= "bundle"; //$NON-NLS-1$
66 * IsLinked attribute name.
68 public static final String IS_LINKED
= "isLinked"; //$NON-NLS-1$
70 // Property View stuff
71 private static final String sfInfoCategory
= "Info"; //$NON-NLS-1$
72 private static final String sfName
= "name"; //$NON-NLS-1$
73 private static final String sfPath
= "path"; //$NON-NLS-1$
74 private static final String sfLocation
= "location"; //$NON-NLS-1$
75 private static final String sfEventType
= "type"; //$NON-NLS-1$
76 private static final String sfIsLinked
= "linked"; //$NON-NLS-1$
78 private static final TextPropertyDescriptor sfNameDescriptor
= new TextPropertyDescriptor(sfName
, sfName
);
79 private static final TextPropertyDescriptor sfPathDescriptor
= new TextPropertyDescriptor(sfPath
, sfPath
);
80 private static final TextPropertyDescriptor sfLocationDescriptor
= new TextPropertyDescriptor(sfLocation
, sfLocation
);
81 private static final TextPropertyDescriptor sfTypeDescriptor
= new TextPropertyDescriptor(sfEventType
, sfEventType
);
82 private static final TextPropertyDescriptor sfIsLinkedDescriptor
= new TextPropertyDescriptor(sfIsLinked
, sfIsLinked
);
84 private static final IPropertyDescriptor
[] sfDescriptors
= { sfNameDescriptor
, sfPathDescriptor
, sfLocationDescriptor
,
85 sfTypeDescriptor
, sfIsLinkedDescriptor
};
88 sfNameDescriptor
.setCategory(sfInfoCategory
);
89 sfPathDescriptor
.setCategory(sfInfoCategory
);
90 sfLocationDescriptor
.setCategory(sfInfoCategory
);
91 sfTypeDescriptor
.setCategory(sfInfoCategory
);
92 sfIsLinkedDescriptor
.setCategory(sfInfoCategory
);
95 private static final String BOOKMARKS_HIDDEN_FILE
= ".bookmarks"; //$NON-NLS-1$
97 // ------------------------------------------------------------------------
99 // ------------------------------------------------------------------------
101 // This trace type ID as defined in plugin.xml
102 private String fTraceTypeId
= null;
104 // ------------------------------------------------------------------------
105 // Static initialization
106 // ------------------------------------------------------------------------
108 // The mapping of available trace type IDs to their corresponding configuration element
109 private static final Map
<String
, IConfigurationElement
> sfTraceTypeAttributes
= new HashMap
<String
, IConfigurationElement
>();
110 private static final Map
<String
, IConfigurationElement
> sfTraceCategories
= new HashMap
<String
, IConfigurationElement
>();
113 * Initialize statically at startup by getting extensions from the platform extension registry.
115 public static void init() {
116 IConfigurationElement
[] config
= Platform
.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType
.TMF_TRACE_TYPE_ID
);
117 for (IConfigurationElement ce
: config
) {
118 String elementName
= ce
.getName();
119 if (elementName
.equals(TmfTraceType
.TYPE_ELEM
)) {
120 String traceTypeId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
121 sfTraceTypeAttributes
.put(traceTypeId
, ce
);
122 } else if (elementName
.equals(TmfTraceType
.CATEGORY_ELEM
)) {
123 String categoryId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
124 sfTraceCategories
.put(categoryId
, ce
);
129 // ------------------------------------------------------------------------
131 // ------------------------------------------------------------------------
134 * Creates trace model element under the trace folder.
135 * @param name The name of trace
136 * @param trace The trace resource.
137 * @param parent The parent element (trace folder)
139 public TmfTraceElement(String name
, IResource trace
, TmfTraceFolder parent
) {
140 this(name
, trace
, (TmfProjectModelElement
) parent
);
144 * Creates trace model element under the experiment folder.
145 * @param name The name of trace
146 * @param trace The trace resource.
147 * @param parent The parent element (experiment folder)
149 public TmfTraceElement(String name
, IResource trace
, TmfExperimentElement parent
) {
150 this(name
, trace
, (TmfProjectModelElement
) parent
);
153 private TmfTraceElement(String name
, IResource trace
, TmfProjectModelElement parent
) {
154 super(name
, trace
, parent
);
155 parent
.addChild(this);
159 // ------------------------------------------------------------------------
161 // ------------------------------------------------------------------------
163 * Returns the trace type ID.
164 * @return trace type ID.
166 public String
getTraceType() {
171 * Refreshes the trace type filed by reading the trace type persistent property of the resource
174 public void refreshTraceType() {
176 fTraceTypeId
= getResource().getPersistentProperty(TmfCommonConstants
.TRACETYPE
);
177 } catch (CoreException e
) {
178 Activator
.getDefault().logError("Error refreshing trace type pesistent property for trace " + getName(), e
); //$NON-NLS-1$
183 * Instantiate a <code>ITmfTrace</code> object based on the trace type and the corresponding extension.
185 * @return the <code>ITmfTrace</code> or <code>null</code> for an error
187 public ITmfTrace
instantiateTrace() {
190 // make sure that supplementary folder exists
191 refreshSupplementaryFolder();
193 if (fTraceTypeId
!= null) {
194 if (fTraceTypeId
.startsWith(CustomTxtTrace
.class.getCanonicalName())) {
195 for (CustomTxtTraceDefinition def
: CustomTxtTraceDefinition
.loadAll()) {
196 if (fTraceTypeId
.equals(CustomTxtTrace
.class.getCanonicalName() + ":" + def
.definitionName
)) { //$NON-NLS-1$
197 return new CustomTxtTrace(def
);
201 if (fTraceTypeId
.startsWith(CustomXmlTrace
.class.getCanonicalName())) {
202 for (CustomXmlTraceDefinition def
: CustomXmlTraceDefinition
.loadAll()) {
203 if (fTraceTypeId
.equals(CustomXmlTrace
.class.getCanonicalName() + ":" + def
.definitionName
)) { //$NON-NLS-1$
204 return new CustomXmlTrace(def
);
208 IConfigurationElement ce
= sfTraceTypeAttributes
.get(fTraceTypeId
);
209 ITmfTrace trace
= (ITmfTrace
) ce
.createExecutableExtension(TmfTraceType
.TRACE_TYPE_ATTR
);
212 } catch (CoreException e
) {
213 Activator
.getDefault().logError("Error instantiating ITmfTrace object for trace " + getName(), e
); //$NON-NLS-1$
219 * Instantiate a <code>ITmfEvent</code> object based on the trace type and the corresponding extension.
221 * @return the <code>ITmfEvent</code> or <code>null</code> for an error
223 public ITmfEvent
instantiateEvent() {
225 if (fTraceTypeId
!= null) {
226 if (fTraceTypeId
.startsWith(CustomTxtTrace
.class.getCanonicalName())) {
227 for (CustomTxtTraceDefinition def
: CustomTxtTraceDefinition
.loadAll()) {
228 if (fTraceTypeId
.equals(CustomTxtTrace
.class.getCanonicalName() + ":" + def
.definitionName
)) { //$NON-NLS-1$
229 return new CustomTxtEvent(def
);
233 if (fTraceTypeId
.startsWith(CustomXmlTrace
.class.getCanonicalName())) {
234 for (CustomXmlTraceDefinition def
: CustomXmlTraceDefinition
.loadAll()) {
235 if (fTraceTypeId
.equals(CustomXmlTrace
.class.getCanonicalName() + ":" + def
.definitionName
)) { //$NON-NLS-1$
236 return new CustomXmlEvent(def
);
240 IConfigurationElement ce
= sfTraceTypeAttributes
.get(fTraceTypeId
);
241 ITmfEvent event
= (ITmfEvent
) ce
.createExecutableExtension(TmfTraceType
.EVENT_TYPE_ATTR
);
244 } catch (CoreException e
) {
245 Activator
.getDefault().logError("Error instantiating ITmfEvent object for trace " + getName(), e
); //$NON-NLS-1$
251 * Returns the optional editor ID from the trace type extension.
252 * @return the editor ID or <code>null</code> if not defined.
254 public String
getEditorId() {
255 if (fTraceTypeId
!= null) {
256 if (fTraceTypeId
.startsWith(CustomTxtTrace
.class.getCanonicalName())) {
257 return TmfEventsEditor
.ID
;
259 if (fTraceTypeId
.startsWith(CustomXmlTrace
.class.getCanonicalName())) {
260 return TmfEventsEditor
.ID
;
262 IConfigurationElement ce
= sfTraceTypeAttributes
.get(fTraceTypeId
);
263 IConfigurationElement
[] defaultEditorCE
= ce
.getChildren(TmfTraceType
.DEFAULT_EDITOR_ELEM
);
264 if (defaultEditorCE
.length
== 1) {
265 return defaultEditorCE
[0].getAttribute(TmfTraceType
.ID_ATTR
);
272 * Returns the file resource used to store bookmarks after creating it if necessary.
273 * If the trace resource is a file, it is returned directly.
274 * If the trace resource is a folder, a linked file is returned.
275 * The file will be created if it does not exist.
276 * @return the bookmarks file
277 * @throws CoreException if the bookmarks file cannot be created
280 public IFile
createBookmarksFile() throws CoreException
{
281 IFile file
= getBookmarksFile();
282 if (fResource
instanceof IFolder
) {
283 if (!file
.exists()) {
284 final IFile bookmarksFile
= getProject().getTracesFolder().getResource().getFile(BOOKMARKS_HIDDEN_FILE
);
285 if (!bookmarksFile
.exists()) {
286 final InputStream source
= new ByteArrayInputStream(new byte[0]);
287 bookmarksFile
.create(source
, true, null);
289 bookmarksFile
.setHidden(true);
290 file
.createLink(bookmarksFile
.getLocation(), IResource
.REPLACE
, null);
291 file
.setHidden(true);
292 file
.setPersistentProperty(TmfCommonConstants
.TRACETYPE
, TmfTrace
.class.getCanonicalName());
299 * Returns the file resource used to store bookmarks.
300 * The file may not exist.
301 * @return the bookmarks file
304 public IFile
getBookmarksFile() {
306 if (fResource
instanceof IFile
) {
307 file
= (IFile
) fResource
;
308 } else if (fResource
instanceof IFolder
) {
309 final IFolder folder
= (IFolder
) fResource
;
310 file
= folder
.getFile(getName() + '_');
316 * Returns the <code>TmfTraceElement</code> located under the <code>TmfTracesFolder</code>.
318 * @return <code>this</code> if this element is under the <code>TmfTracesFolder</code>
319 * else the corresponding <code>TmfTraceElement</code> if this element is under
320 * <code>TmfExperimentElement</code>.
322 public TmfTraceElement
getElementUnderTraceFolder() {
324 // If trace is under an experiment, return original trace from the traces folder
325 if (getParent() instanceof TmfExperimentElement
) {
326 for (TmfTraceElement aTrace
: getProject().getTracesFolder().getTraces()) {
327 if (aTrace
.getName().equals(getName())) {
335 // ------------------------------------------------------------------------
337 // ------------------------------------------------------------------------
340 public boolean testAttribute(Object target
, String name
, String value
) {
341 if (name
.equals(IS_LINKED
)) {
342 boolean isLinked
= getResource().isLinked();
343 return Boolean
.toString(isLinked
).equals(value
);
348 // ------------------------------------------------------------------------
350 // ------------------------------------------------------------------------
353 * @see org.eclipse.linuxtools.tmf.ui.project.model.ITmfProjectModelElement#getProject()
356 public TmfProjectElement
getProject() {
357 if (getParent() instanceof TmfTraceFolder
) {
358 TmfTraceFolder folder
= (TmfTraceFolder
) getParent();
359 TmfProjectElement project
= (TmfProjectElement
) folder
.getParent();
362 if (getParent() instanceof TmfExperimentElement
) {
363 TmfExperimentElement experiment
= (TmfExperimentElement
) getParent();
364 TmfExperimentFolder folder
= (TmfExperimentFolder
) experiment
.getParent();
365 TmfProjectElement project
= (TmfProjectElement
) folder
.getParent();
371 // ------------------------------------------------------------------------
373 // ------------------------------------------------------------------------
377 * @see org.eclipse.ui.views.properties.IPropertySource#getEditableValue()
380 public Object
getEditableValue() {
386 * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors()
389 public IPropertyDescriptor
[] getPropertyDescriptors() {
390 return Arrays
.copyOf(sfDescriptors
, sfDescriptors
.length
);
395 * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(java.lang.Object)
398 public Object
getPropertyValue(Object id
) {
400 if (sfName
.equals(id
)) {
404 if (sfPath
.equals(id
)) {
405 return getPath().toString();
408 if (sfLocation
.equals(id
)) {
409 return getLocation().toString();
412 if (sfIsLinked
.equals(id
)) {
413 return Boolean
.valueOf(getResource().isLinked()).toString();
416 if (sfEventType
.equals(id
)) {
417 if (fTraceTypeId
!= null) {
418 IConfigurationElement ce
= sfTraceTypeAttributes
.get(fTraceTypeId
);
419 return (ce
!= null) ?
(getCategory(ce
) + " : " + ce
.getAttribute(TmfTraceType
.NAME_ATTR
)) : ""; //$NON-NLS-1$ //$NON-NLS-2$
426 private static String
getCategory(IConfigurationElement ce
) {
427 String categoryId
= ce
.getAttribute(TmfTraceType
.CATEGORY_ATTR
);
428 if (categoryId
!= null) {
429 IConfigurationElement category
= sfTraceCategories
.get(categoryId
);
430 if (category
!= null) {
431 return category
.getAttribute(TmfTraceType
.NAME_ATTR
);
434 return "[no category]"; //$NON-NLS-1$
439 * @see org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(java.lang.Object)
442 public void resetPropertyValue(Object id
) {
447 * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object, java.lang.Object)
450 public void setPropertyValue(Object id
, Object value
) {
455 * @see org.eclipse.ui.views.properties.IPropertySource2#isPropertyResettable(java.lang.Object)
458 public boolean isPropertyResettable(Object id
) {
464 * @see org.eclipse.ui.views.properties.IPropertySource2#isPropertySet(java.lang.Object)
467 public boolean isPropertySet(Object id
) {