1 /*******************************************************************************
2 * Copyright (c) 2010, 2011, 2012 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 *******************************************************************************/
14 package org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
;
16 import java
.util
.Arrays
;
17 import java
.util
.HashMap
;
20 import org
.eclipse
.core
.resources
.IFolder
;
21 import org
.eclipse
.core
.resources
.IResource
;
22 import org
.eclipse
.core
.runtime
.CoreException
;
23 import org
.eclipse
.core
.runtime
.IConfigurationElement
;
24 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
25 import org
.eclipse
.core
.runtime
.Platform
;
26 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Activator
;
27 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomTxtEvent
;
28 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomTxtTrace
;
29 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomTxtTraceDefinition
;
30 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomXmlEvent
;
31 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomXmlTrace
;
32 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomXmlTraceDefinition
;
33 import org
.eclipse
.linuxtools
.tmf
.core
.TmfCommonConstants
;
34 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
35 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
36 import org
.eclipse
.linuxtools
.tmf
.ui
.editors
.TmfEventsEditor
;
37 import org
.eclipse
.ui
.IActionFilter
;
38 import org
.eclipse
.ui
.views
.properties
.IPropertyDescriptor
;
39 import org
.eclipse
.ui
.views
.properties
.IPropertySource2
;
40 import org
.eclipse
.ui
.views
.properties
.TextPropertyDescriptor
;
43 * Implementation of trace model element representing a trace. It provides methods to instantiate
44 * <code>ITmfTrace</code> and <code>ITmfEvent</code> as well as editor ID from the trace type
45 * extension definition.
48 * @author Francois Chouinard
50 public class TmfTraceElement
extends TmfProjectModelElement
implements IActionFilter
, IPropertySource2
{
52 // ------------------------------------------------------------------------
54 // ------------------------------------------------------------------------
58 * Bundle attribute name
60 public static final String BUNDLE
= "bundle"; //$NON-NLS-1$
62 * IsLinked attribute name.
64 public static final String IS_LINKED
= "isLinked"; //$NON-NLS-1$
66 // Property View stuff
67 private static final String sfInfoCategory
= "Info"; //$NON-NLS-1$
68 private static final String sfName
= "name"; //$NON-NLS-1$
69 private static final String sfPath
= "path"; //$NON-NLS-1$
70 private static final String sfLocation
= "location"; //$NON-NLS-1$
71 private static final String sfEventType
= "type"; //$NON-NLS-1$
72 private static final String sfIsLinked
= "linked"; //$NON-NLS-1$
74 private static final TextPropertyDescriptor sfNameDescriptor
= new TextPropertyDescriptor(sfName
, sfName
);
75 private static final TextPropertyDescriptor sfPathDescriptor
= new TextPropertyDescriptor(sfPath
, sfPath
);
76 private static final TextPropertyDescriptor sfLocationDescriptor
= new TextPropertyDescriptor(sfLocation
, sfLocation
);
77 private static final TextPropertyDescriptor sfTypeDescriptor
= new TextPropertyDescriptor(sfEventType
, sfEventType
);
78 private static final TextPropertyDescriptor sfIsLinkedDescriptor
= new TextPropertyDescriptor(sfIsLinked
, sfIsLinked
);
80 private static final IPropertyDescriptor
[] sfDescriptors
= { sfNameDescriptor
, sfPathDescriptor
, sfLocationDescriptor
,
81 sfTypeDescriptor
, sfIsLinkedDescriptor
};
84 sfNameDescriptor
.setCategory(sfInfoCategory
);
85 sfPathDescriptor
.setCategory(sfInfoCategory
);
86 sfLocationDescriptor
.setCategory(sfInfoCategory
);
87 sfTypeDescriptor
.setCategory(sfInfoCategory
);
88 sfIsLinkedDescriptor
.setCategory(sfInfoCategory
);
91 // ------------------------------------------------------------------------
93 // ------------------------------------------------------------------------
95 // This trace type ID as defined in plugin.xml
96 private String fTraceTypeId
= null;
98 // ------------------------------------------------------------------------
99 // Static initialization
100 // ------------------------------------------------------------------------
102 // The mapping of available trace type IDs to their corresponding configuration element
103 private static final Map
<String
, IConfigurationElement
> sfTraceTypeAttributes
= new HashMap
<String
, IConfigurationElement
>();
104 private static final Map
<String
, IConfigurationElement
> sfTraceCategories
= new HashMap
<String
, IConfigurationElement
>();
107 * Initialize statically at startup by getting extensions from the platform extension registry.
109 public static void init() {
110 IConfigurationElement
[] config
= Platform
.getExtensionRegistry().getConfigurationElementsFor(TmfTraceType
.TMF_TRACE_TYPE_ID
);
111 for (IConfigurationElement ce
: config
) {
112 String elementName
= ce
.getName();
113 if (elementName
.equals(TmfTraceType
.TYPE_ELEM
)) {
114 String traceTypeId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
115 sfTraceTypeAttributes
.put(traceTypeId
, ce
);
116 } else if (elementName
.equals(TmfTraceType
.CATEGORY_ELEM
)) {
117 String categoryId
= ce
.getAttribute(TmfTraceType
.ID_ATTR
);
118 sfTraceCategories
.put(categoryId
, ce
);
123 // ------------------------------------------------------------------------
125 // ------------------------------------------------------------------------
128 * Creates trace model element under the trace folder.
129 * @param name The name of trace
130 * @param trace The trace resource.
131 * @param parent The parent element (trace folder)
133 public TmfTraceElement(String name
, IResource trace
, TmfTraceFolder parent
) {
134 this(name
, trace
, (TmfProjectModelElement
) parent
);
138 * Creates trace model element under the experiment folder.
139 * @param name The name of trace
140 * @param trace The trace resource.
141 * @param parent The parent element (experiment folder)
143 public TmfTraceElement(String name
, IResource trace
, TmfExperimentElement parent
) {
144 this(name
, trace
, (TmfProjectModelElement
) parent
);
147 private TmfTraceElement(String name
, IResource trace
, TmfProjectModelElement parent
) {
148 super(name
, trace
, parent
);
149 parent
.addChild(this);
153 // ------------------------------------------------------------------------
155 // ------------------------------------------------------------------------
157 * Returns the trace type ID.
158 * @return trace type ID.
160 public String
getTraceType() {
165 * Refreshes the trace type filed by reading the trace type persistent property of the resource
168 public void refreshTraceType() {
170 fTraceTypeId
= getResource().getPersistentProperty(TmfCommonConstants
.TRACETYPE
);
171 } catch (CoreException e
) {
172 Activator
.getDefault().logError("Error refreshing trace type pesistent property for trace " + getName(), e
); //$NON-NLS-1$
177 * Instantiate a <code>ITmfTrace</code> object based on the trace type and the corresponding extension.
179 * @return the <code>ITmfTrace</code> or <code>null</code> for an error
181 public ITmfTrace
instantiateTrace() {
184 // make sure that supplementary folder exists
185 refreshSupplementaryFolder();
187 if (fTraceTypeId
!= null) {
188 if (fTraceTypeId
.startsWith(CustomTxtTrace
.class.getCanonicalName())) {
189 for (CustomTxtTraceDefinition def
: CustomTxtTraceDefinition
.loadAll()) {
190 if (fTraceTypeId
.equals(CustomTxtTrace
.class.getCanonicalName() + ":" + def
.definitionName
)) { //$NON-NLS-1$
191 return new CustomTxtTrace(def
);
195 if (fTraceTypeId
.startsWith(CustomXmlTrace
.class.getCanonicalName())) {
196 for (CustomXmlTraceDefinition def
: CustomXmlTraceDefinition
.loadAll()) {
197 if (fTraceTypeId
.equals(CustomXmlTrace
.class.getCanonicalName() + ":" + def
.definitionName
)) { //$NON-NLS-1$
198 return new CustomXmlTrace(def
);
202 IConfigurationElement ce
= sfTraceTypeAttributes
.get(fTraceTypeId
);
203 ITmfTrace trace
= (ITmfTrace
) ce
.createExecutableExtension(TmfTraceType
.TRACE_TYPE_ATTR
);
206 } catch (CoreException e
) {
207 Activator
.getDefault().logError("Error instantiating ITmfTrace object for trace " + getName(), e
); //$NON-NLS-1$
213 * Instantiate a <code>ITmfEvent</code> object based on the trace type and the corresponding extension.
215 * @return the <code>ITmfEvent</code> or <code>null</code> for an error
217 public ITmfEvent
instantiateEvent() {
219 if (fTraceTypeId
!= null) {
220 if (fTraceTypeId
.startsWith(CustomTxtTrace
.class.getCanonicalName())) {
221 for (CustomTxtTraceDefinition def
: CustomTxtTraceDefinition
.loadAll()) {
222 if (fTraceTypeId
.equals(CustomTxtTrace
.class.getCanonicalName() + ":" + def
.definitionName
)) { //$NON-NLS-1$
223 return new CustomTxtEvent(def
);
227 if (fTraceTypeId
.startsWith(CustomXmlTrace
.class.getCanonicalName())) {
228 for (CustomXmlTraceDefinition def
: CustomXmlTraceDefinition
.loadAll()) {
229 if (fTraceTypeId
.equals(CustomXmlTrace
.class.getCanonicalName() + ":" + def
.definitionName
)) { //$NON-NLS-1$
230 return new CustomXmlEvent(def
);
234 IConfigurationElement ce
= sfTraceTypeAttributes
.get(fTraceTypeId
);
235 ITmfEvent event
= (ITmfEvent
) ce
.createExecutableExtension(TmfTraceType
.EVENT_TYPE_ATTR
);
238 } catch (CoreException e
) {
239 Activator
.getDefault().logError("Error instantiating ITmfEvent object for trace " + getName(), e
); //$NON-NLS-1$
245 * Returns the optional editor ID from the trace type extension.
246 * @return the editor ID or <code>null</code> if not defined.
248 public String
getEditorId() {
249 if (fTraceTypeId
!= null) {
250 if (fTraceTypeId
.startsWith(CustomTxtTrace
.class.getCanonicalName())) {
251 return TmfEventsEditor
.ID
;
253 if (fTraceTypeId
.startsWith(CustomXmlTrace
.class.getCanonicalName())) {
254 return TmfEventsEditor
.ID
;
256 IConfigurationElement ce
= sfTraceTypeAttributes
.get(fTraceTypeId
);
257 IConfigurationElement
[] defaultEditorCE
= ce
.getChildren(TmfTraceType
.DEFAULT_EDITOR_ELEM
);
258 if (defaultEditorCE
.length
== 1) {
259 return defaultEditorCE
[0].getAttribute(TmfTraceType
.ID_ATTR
);
266 * Returns the <code>TmfTraceElement</code> located under the <code>TmfTracesFolder</code>.
268 * @return <code>this</code> if this element is under the <code>TmfTracesFolder</code>
269 * else the corresponding <code>TmfTraceElement</code> if this element is under
270 * <code>TmfExperimentElement</code>.
272 public TmfTraceElement
getElementUnderTraceFolder() {
274 // If trace is under an experiment, return original trace from the traces folder
275 if (getParent() instanceof TmfExperimentElement
) {
276 for (TmfTraceElement aTrace
: getProject().getTracesFolder().getTraces()) {
277 if (aTrace
.getName().equals(getName())) {
286 * Deletes the trace specific supplementary folder.
288 public void deleteSupplementaryFolder() {
289 IFolder supplFolder
= getTraceSupplementaryFolder(fResource
.getName());
290 if (supplFolder
.exists()) {
292 supplFolder
.delete(true, new NullProgressMonitor());
293 } catch (CoreException e
) {
294 Activator
.getDefault().logError("Error deleting supplementary folder " + supplFolder
, e
); //$NON-NLS-1$
300 * Renames the trace specific supplementary folder according to the new trace name.
302 * @param newTraceName The new trace name
304 public void renameSupplementaryFolder(String newTraceName
) {
305 IFolder oldSupplFolder
= getTraceSupplementaryFolder(fResource
.getName());
306 IFolder newSupplFolder
= getTraceSupplementaryFolder(newTraceName
);
308 // Rename supplementary folder
309 if (oldSupplFolder
.exists()) {
311 oldSupplFolder
.move(newSupplFolder
.getFullPath(), true, new NullProgressMonitor());
312 } catch (CoreException e
) {
313 Activator
.getDefault().logError("Error renaming supplementary folder " + oldSupplFolder
, e
); //$NON-NLS-1$
319 * Copies the trace specific supplementary folder to the new trace name.
321 * @param newTraceName The new trace name
323 public void copySupplementaryFolder(String newTraceName
) {
324 IFolder oldSupplFolder
= getTraceSupplementaryFolder(fResource
.getName());
325 IFolder newSupplFolder
= getTraceSupplementaryFolder(newTraceName
);
327 // copy supplementary folder
328 if (oldSupplFolder
.exists()) {
330 oldSupplFolder
.copy(newSupplFolder
.getFullPath(), true, new NullProgressMonitor());
331 } catch (CoreException e
) {
332 Activator
.getDefault().logError("Error renaming supplementary folder " + oldSupplFolder
, e
); //$NON-NLS-1$
338 * Copies the trace specific supplementary folder a new folder.
340 * @param destination The destination folder to copy to.
342 public void copySupplementaryFolder(IFolder destination
) {
343 IFolder oldSupplFolder
= getTraceSupplementaryFolder(fResource
.getName());
345 // copy supplementary folder
346 if (oldSupplFolder
.exists()) {
348 oldSupplFolder
.copy(destination
.getFullPath(), true, new NullProgressMonitor());
349 } catch (CoreException e
) {
350 Activator
.getDefault().logError("Error copying supplementary folder " + oldSupplFolder
, e
); //$NON-NLS-1$
357 * Refreshes the trace specific supplementary folder information. It creates the folder if not exists.
358 * It sets the persistence property of the trace resource
360 public void refreshSupplementaryFolder() {
361 createSupplementaryDirectory();
365 * Checks if supplementary resource exist or not.
367 * @return <code>true</code> if one or more files are under the trace supplementary folder
369 public boolean hasSupplementaryResources() {
370 IResource
[] resources
= getSupplementaryResources();
371 return (resources
.length
> 0);
375 * Returns the supplementary resources under the trace supplementary folder.
377 * @return array of resources under the trace supplementary folder.
379 public IResource
[] getSupplementaryResources() {
380 IFolder supplFolder
= getTraceSupplementaryFolder(fResource
.getName());
381 if (supplFolder
.exists()) {
383 return supplFolder
.members();
384 } catch (CoreException e
) {
385 Activator
.getDefault().logError("Error deleting supplementary folder " + supplFolder
, e
); //$NON-NLS-1$
388 return new IResource
[0];
392 * Deletes the given resources.
394 * @param resources array of resources to delete.
396 public void deleteSupplementaryResources(IResource
[] resources
) {
398 for (int i
= 0; i
< resources
.length
; i
++) {
400 resources
[i
].delete(true, new NullProgressMonitor());
401 } catch (CoreException e
) {
402 Activator
.getDefault().logError("Error deleting supplementary resource " + resources
[i
], e
); //$NON-NLS-1$
407 private void createSupplementaryDirectory() {
408 IFolder supplFolder
= getTraceSupplementaryFolder(fResource
.getName());
409 if (!supplFolder
.exists()) {
411 supplFolder
.create(true, true, new NullProgressMonitor());
412 } catch (CoreException e
) {
413 Activator
.getDefault().logError("Error creating resource supplementary file " + supplFolder
, e
); //$NON-NLS-1$
418 fResource
.setPersistentProperty(TmfCommonConstants
.TRACE_SUPPLEMENTARY_FOLDER
, supplFolder
.getLocationURI().getPath());
419 } catch (CoreException e
) {
420 Activator
.getDefault().logError("Error setting persistant property " + TmfCommonConstants
.TRACE_SUPPLEMENTARY_FOLDER
, e
); //$NON-NLS-1$
425 // ------------------------------------------------------------------------
427 // ------------------------------------------------------------------------
430 public boolean testAttribute(Object target
, String name
, String value
) {
431 if (name
.equals(IS_LINKED
)) {
432 boolean isLinked
= getResource().isLinked();
433 return Boolean
.toString(isLinked
).equals(value
);
438 // ------------------------------------------------------------------------
440 // ------------------------------------------------------------------------
443 * @see org.eclipse.linuxtools.tmf.ui.project.model.ITmfProjectModelElement#getProject()
446 public TmfProjectElement
getProject() {
447 if (getParent() instanceof TmfTraceFolder
) {
448 TmfTraceFolder folder
= (TmfTraceFolder
) getParent();
449 TmfProjectElement project
= (TmfProjectElement
) folder
.getParent();
452 if (getParent() instanceof TmfExperimentElement
) {
453 TmfExperimentElement experiment
= (TmfExperimentElement
) getParent();
454 TmfExperimentFolder folder
= (TmfExperimentFolder
) experiment
.getParent();
455 TmfProjectElement project
= (TmfProjectElement
) folder
.getParent();
461 // ------------------------------------------------------------------------
463 // ------------------------------------------------------------------------
467 * @see org.eclipse.ui.views.properties.IPropertySource#getEditableValue()
470 public Object
getEditableValue() {
476 * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors()
479 public IPropertyDescriptor
[] getPropertyDescriptors() {
480 return (sfDescriptors
!= null) ? Arrays
.copyOf(sfDescriptors
, sfDescriptors
.length
) : null;
485 * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(java.lang.Object)
488 public Object
getPropertyValue(Object id
) {
490 if (sfName
.equals(id
)) {
494 if (sfPath
.equals(id
)) {
495 return getPath().toString();
498 if (sfLocation
.equals(id
)) {
499 return getLocation().toString();
502 if (sfIsLinked
.equals(id
)) {
503 return Boolean
.valueOf(getResource().isLinked()).toString();
506 if (sfEventType
.equals(id
)) {
507 if (fTraceTypeId
!= null) {
508 IConfigurationElement ce
= sfTraceTypeAttributes
.get(fTraceTypeId
);
509 return (ce
!= null) ?
(getCategory(ce
) + " : " + ce
.getAttribute(TmfTraceType
.NAME_ATTR
)) : ""; //$NON-NLS-1$ //$NON-NLS-2$
516 private static String
getCategory(IConfigurationElement ce
) {
517 String categoryId
= ce
.getAttribute(TmfTraceType
.CATEGORY_ATTR
);
518 if (categoryId
!= null) {
519 IConfigurationElement category
= sfTraceCategories
.get(categoryId
);
520 if (category
!= null) {
521 return category
.getAttribute(TmfTraceType
.NAME_ATTR
);
524 return "[no category]"; //$NON-NLS-1$
529 * @see org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(java.lang.Object)
532 public void resetPropertyValue(Object id
) {
537 * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object, java.lang.Object)
540 public void setPropertyValue(Object id
, Object value
) {
545 * @see org.eclipse.ui.views.properties.IPropertySource2#isPropertyResettable(java.lang.Object)
548 public boolean isPropertyResettable(Object id
) {
554 * @see org.eclipse.ui.views.properties.IPropertySource2#isPropertySet(java.lang.Object)
557 public boolean isPropertySet(Object id
) {