8826f9a22e8577366dd795f345fcdd50151a1d83
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / project / model / TmfTraceElement.java
1 /*******************************************************************************
2 * Copyright (c) 2010, 2011, 2012 Ericsson
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 *******************************************************************************/
13
14 package org.eclipse.linuxtools.tmf.ui.project.model;
15
16 import java.io.ByteArrayInputStream;
17 import java.io.InputStream;
18 import java.util.Arrays;
19 import java.util.HashMap;
20 import java.util.Map;
21
22 import org.eclipse.core.resources.IFile;
23 import org.eclipse.core.resources.IFolder;
24 import org.eclipse.core.resources.IResource;
25 import org.eclipse.core.runtime.CoreException;
26 import org.eclipse.core.runtime.IConfigurationElement;
27 import org.eclipse.core.runtime.NullProgressMonitor;
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;
45
46 /**
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.
50 *
51 * @version 1.0
52 * @author Francois Chouinard
53 */
54 public class TmfTraceElement extends TmfProjectModelElement implements IActionFilter, IPropertySource2 {
55
56 // ------------------------------------------------------------------------
57 // Constants
58 // ------------------------------------------------------------------------
59
60 // Other attributes
61 /**
62 * Bundle attribute name
63 */
64 public static final String BUNDLE = "bundle"; //$NON-NLS-1$
65 /**
66 * IsLinked attribute name.
67 */
68 public static final String IS_LINKED = "isLinked"; //$NON-NLS-1$
69
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$
77
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);
83
84 private static final IPropertyDescriptor[] sfDescriptors = { sfNameDescriptor, sfPathDescriptor, sfLocationDescriptor,
85 sfTypeDescriptor, sfIsLinkedDescriptor };
86
87 static {
88 sfNameDescriptor.setCategory(sfInfoCategory);
89 sfPathDescriptor.setCategory(sfInfoCategory);
90 sfLocationDescriptor.setCategory(sfInfoCategory);
91 sfTypeDescriptor.setCategory(sfInfoCategory);
92 sfIsLinkedDescriptor.setCategory(sfInfoCategory);
93 }
94
95 private static final String BOOKMARKS_HIDDEN_FILE = ".bookmarks"; //$NON-NLS-1$
96
97 // ------------------------------------------------------------------------
98 // Attributes
99 // ------------------------------------------------------------------------
100
101 // This trace type ID as defined in plugin.xml
102 private String fTraceTypeId = null;
103
104 // ------------------------------------------------------------------------
105 // Static initialization
106 // ------------------------------------------------------------------------
107
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>();
111
112 /**
113 * Initialize statically at startup by getting extensions from the platform extension registry.
114 */
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);
125 }
126 }
127 }
128
129 // ------------------------------------------------------------------------
130 // Constructors
131 // ------------------------------------------------------------------------
132 /**
133 * Constructor.
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)
138 */
139 public TmfTraceElement(String name, IResource trace, TmfTraceFolder parent) {
140 this(name, trace, (TmfProjectModelElement) parent);
141 }
142 /**
143 * Constructor.
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)
148 */
149 public TmfTraceElement(String name, IResource trace, TmfExperimentElement parent) {
150 this(name, trace, (TmfProjectModelElement) parent);
151 }
152
153 private TmfTraceElement(String name, IResource trace, TmfProjectModelElement parent) {
154 super(name, trace, parent);
155 parent.addChild(this);
156 refreshTraceType();
157 }
158
159 // ------------------------------------------------------------------------
160 // Operations
161 // ------------------------------------------------------------------------
162 /**
163 * Returns the trace type ID.
164 * @return trace type ID.
165 */
166 public String getTraceType() {
167 return fTraceTypeId;
168 }
169
170 /**
171 * Refreshes the trace type filed by reading the trace type persistent property of the resource
172 * referenece.
173 */
174 public void refreshTraceType() {
175 try {
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$
179 }
180 }
181
182 /**
183 * Instantiate a <code>ITmfTrace</code> object based on the trace type and the corresponding extension.
184 *
185 * @return the <code>ITmfTrace</code> or <code>null</code> for an error
186 */
187 public ITmfTrace instantiateTrace() {
188 try {
189
190 // make sure that supplementary folder exists
191 refreshSupplementaryFolder();
192
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);
198 }
199 }
200 }
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);
205 }
206 }
207 }
208 IConfigurationElement ce = sfTraceTypeAttributes.get(fTraceTypeId);
209 ITmfTrace trace = (ITmfTrace) ce.createExecutableExtension(TmfTraceType.TRACE_TYPE_ATTR);
210 return trace;
211 }
212 } catch (CoreException e) {
213 Activator.getDefault().logError("Error instantiating ITmfTrace object for trace " + getName(), e); //$NON-NLS-1$
214 }
215 return null;
216 }
217
218 /**
219 * Instantiate a <code>ITmfEvent</code> object based on the trace type and the corresponding extension.
220 *
221 * @return the <code>ITmfEvent</code> or <code>null</code> for an error
222 */
223 public ITmfEvent instantiateEvent() {
224 try {
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);
230 }
231 }
232 }
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);
237 }
238 }
239 }
240 IConfigurationElement ce = sfTraceTypeAttributes.get(fTraceTypeId);
241 ITmfEvent event = (ITmfEvent) ce.createExecutableExtension(TmfTraceType.EVENT_TYPE_ATTR);
242 return event;
243 }
244 } catch (CoreException e) {
245 Activator.getDefault().logError("Error instantiating ITmfEvent object for trace " + getName(), e); //$NON-NLS-1$
246 }
247 return null;
248 }
249
250 /**
251 * Returns the optional editor ID from the trace type extension.
252 * @return the editor ID or <code>null</code> if not defined.
253 */
254 public String getEditorId() {
255 if (fTraceTypeId != null) {
256 if (fTraceTypeId.startsWith(CustomTxtTrace.class.getCanonicalName())) {
257 return TmfEventsEditor.ID;
258 }
259 if (fTraceTypeId.startsWith(CustomXmlTrace.class.getCanonicalName())) {
260 return TmfEventsEditor.ID;
261 }
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);
266 }
267 }
268 return null;
269 }
270
271 /**
272 * Returns the file resource used to store bookmarks.
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 linked file will be created if it doesn't exist.
276 * @return the bookmarks file
277 * @throws CoreException if the bookmarks file cannot be created
278 * @since 2.0
279 */
280 public IFile getBookmarksFile() throws CoreException {
281 IFile file = null;
282 if (fResource instanceof IFile) {
283 file = (IFile) fResource;
284 } else if (fResource instanceof IFolder) {
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);
289 }
290 bookmarksFile.setHidden(true);
291
292 final IFolder folder = (IFolder) fResource;
293 file = folder.getFile(getName() + '_');
294 if (!file.exists()) {
295 file.createLink(bookmarksFile.getLocation(), IResource.REPLACE, null);
296 }
297 file.setHidden(true);
298 file.setPersistentProperty(TmfCommonConstants.TRACETYPE, TmfTrace.class.getCanonicalName());
299 }
300 return file;
301 }
302
303 /**
304 * Returns the <code>TmfTraceElement</code> located under the <code>TmfTracesFolder</code>.
305 *
306 * @return <code>this</code> if this element is under the <code>TmfTracesFolder</code>
307 * else the corresponding <code>TmfTraceElement</code> if this element is under
308 * <code>TmfExperimentElement</code>.
309 */
310 public TmfTraceElement getElementUnderTraceFolder() {
311
312 // If trace is under an experiment, return original trace from the traces folder
313 if (getParent() instanceof TmfExperimentElement) {
314 for (TmfTraceElement aTrace : getProject().getTracesFolder().getTraces()) {
315 if (aTrace.getName().equals(getName())) {
316 return aTrace;
317 }
318 }
319 }
320 return this;
321 }
322
323 /**
324 * Deletes the trace specific supplementary folder.
325 */
326 public void deleteSupplementaryFolder() {
327 IFolder supplFolder = getTraceSupplementaryFolder(fResource.getName());
328 if (supplFolder.exists()) {
329 try {
330 supplFolder.delete(true, new NullProgressMonitor());
331 } catch (CoreException e) {
332 Activator.getDefault().logError("Error deleting supplementary folder " + supplFolder, e); //$NON-NLS-1$
333 }
334 }
335 }
336
337 /**
338 * Renames the trace specific supplementary folder according to the new trace name.
339 *
340 * @param newTraceName The new trace name
341 */
342 public void renameSupplementaryFolder(String newTraceName) {
343 IFolder oldSupplFolder = getTraceSupplementaryFolder(fResource.getName());
344 IFolder newSupplFolder = getTraceSupplementaryFolder(newTraceName);
345
346 // Rename supplementary folder
347 if (oldSupplFolder.exists()) {
348 try {
349 oldSupplFolder.move(newSupplFolder.getFullPath(), true, new NullProgressMonitor());
350 } catch (CoreException e) {
351 Activator.getDefault().logError("Error renaming supplementary folder " + oldSupplFolder, e); //$NON-NLS-1$
352 }
353 }
354 }
355
356 /**
357 * Copies the trace specific supplementary folder to the new trace name.
358 *
359 * @param newTraceName The new trace name
360 */
361 public void copySupplementaryFolder(String newTraceName) {
362 IFolder oldSupplFolder = getTraceSupplementaryFolder(fResource.getName());
363 IFolder newSupplFolder = getTraceSupplementaryFolder(newTraceName);
364
365 // copy supplementary folder
366 if (oldSupplFolder.exists()) {
367 try {
368 oldSupplFolder.copy(newSupplFolder.getFullPath(), true, new NullProgressMonitor());
369 } catch (CoreException e) {
370 Activator.getDefault().logError("Error renaming supplementary folder " + oldSupplFolder, e); //$NON-NLS-1$
371 }
372 }
373 }
374
375 /**
376 * Copies the trace specific supplementary folder a new folder.
377 *
378 * @param destination The destination folder to copy to.
379 */
380 public void copySupplementaryFolder(IFolder destination) {
381 IFolder oldSupplFolder = getTraceSupplementaryFolder(fResource.getName());
382
383 // copy supplementary folder
384 if (oldSupplFolder.exists()) {
385 try {
386 oldSupplFolder.copy(destination.getFullPath(), true, new NullProgressMonitor());
387 } catch (CoreException e) {
388 Activator.getDefault().logError("Error copying supplementary folder " + oldSupplFolder, e); //$NON-NLS-1$
389 }
390 }
391 }
392
393
394 /**
395 * Refreshes the trace specific supplementary folder information. It creates the folder if not exists.
396 * It sets the persistence property of the trace resource
397 */
398 public void refreshSupplementaryFolder() {
399 createSupplementaryDirectory();
400 }
401
402 /**
403 * Checks if supplementary resource exist or not.
404 *
405 * @return <code>true</code> if one or more files are under the trace supplementary folder
406 */
407 public boolean hasSupplementaryResources() {
408 IResource[] resources = getSupplementaryResources();
409 return (resources.length > 0);
410 }
411
412 /**
413 * Returns the supplementary resources under the trace supplementary folder.
414 *
415 * @return array of resources under the trace supplementary folder.
416 */
417 public IResource[] getSupplementaryResources() {
418 IFolder supplFolder = getTraceSupplementaryFolder(fResource.getName());
419 if (supplFolder.exists()) {
420 try {
421 return supplFolder.members();
422 } catch (CoreException e) {
423 Activator.getDefault().logError("Error deleting supplementary folder " + supplFolder, e); //$NON-NLS-1$
424 }
425 }
426 return new IResource[0];
427 }
428
429 /**
430 * Deletes the given resources.
431 *
432 * @param resources array of resources to delete.
433 */
434 public void deleteSupplementaryResources(IResource[] resources) {
435
436 for (int i = 0; i < resources.length; i++) {
437 try {
438 resources[i].delete(true, new NullProgressMonitor());
439 } catch (CoreException e) {
440 Activator.getDefault().logError("Error deleting supplementary resource " + resources[i], e); //$NON-NLS-1$
441 }
442 }
443 }
444
445 private void createSupplementaryDirectory() {
446 IFolder supplFolder = getTraceSupplementaryFolder(fResource.getName());
447 if (!supplFolder.exists()) {
448 try {
449 supplFolder.create(true, true, new NullProgressMonitor());
450 } catch (CoreException e) {
451 Activator.getDefault().logError("Error creating resource supplementary file " + supplFolder, e); //$NON-NLS-1$
452 }
453 }
454
455 try {
456 fResource.setPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER, supplFolder.getLocationURI().getPath());
457 } catch (CoreException e) {
458 Activator.getDefault().logError("Error setting persistant property " + TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER, e); //$NON-NLS-1$
459 }
460
461 }
462
463 // ------------------------------------------------------------------------
464 // IActionFilter
465 // ------------------------------------------------------------------------
466
467 @Override
468 public boolean testAttribute(Object target, String name, String value) {
469 if (name.equals(IS_LINKED)) {
470 boolean isLinked = getResource().isLinked();
471 return Boolean.toString(isLinked).equals(value);
472 }
473 return false;
474 }
475
476 // ------------------------------------------------------------------------
477 // TmfTraceElement
478 // ------------------------------------------------------------------------
479 /*
480 * (non-Javadoc)
481 * @see org.eclipse.linuxtools.tmf.ui.project.model.ITmfProjectModelElement#getProject()
482 */
483 @Override
484 public TmfProjectElement getProject() {
485 if (getParent() instanceof TmfTraceFolder) {
486 TmfTraceFolder folder = (TmfTraceFolder) getParent();
487 TmfProjectElement project = (TmfProjectElement) folder.getParent();
488 return project;
489 }
490 if (getParent() instanceof TmfExperimentElement) {
491 TmfExperimentElement experiment = (TmfExperimentElement) getParent();
492 TmfExperimentFolder folder = (TmfExperimentFolder) experiment.getParent();
493 TmfProjectElement project = (TmfProjectElement) folder.getParent();
494 return project;
495 }
496 return null;
497 }
498
499 // ------------------------------------------------------------------------
500 // IPropertySource2
501 // ------------------------------------------------------------------------
502
503 /*
504 * (non-Javadoc)
505 * @see org.eclipse.ui.views.properties.IPropertySource#getEditableValue()
506 */
507 @Override
508 public Object getEditableValue() {
509 return null;
510 }
511
512 /*
513 * (non-Javadoc)
514 * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyDescriptors()
515 */
516 @Override
517 public IPropertyDescriptor[] getPropertyDescriptors() {
518 return (sfDescriptors != null) ? Arrays.copyOf(sfDescriptors, sfDescriptors.length) : null;
519 }
520
521 /*
522 * (non-Javadoc)
523 * @see org.eclipse.ui.views.properties.IPropertySource#getPropertyValue(java.lang.Object)
524 */
525 @Override
526 public Object getPropertyValue(Object id) {
527
528 if (sfName.equals(id)) {
529 return getName();
530 }
531
532 if (sfPath.equals(id)) {
533 return getPath().toString();
534 }
535
536 if (sfLocation.equals(id)) {
537 return getLocation().toString();
538 }
539
540 if (sfIsLinked.equals(id)) {
541 return Boolean.valueOf(getResource().isLinked()).toString();
542 }
543
544 if (sfEventType.equals(id)) {
545 if (fTraceTypeId != null) {
546 IConfigurationElement ce = sfTraceTypeAttributes.get(fTraceTypeId);
547 return (ce != null) ? (getCategory(ce) + " : " + ce.getAttribute(TmfTraceType.NAME_ATTR)) : ""; //$NON-NLS-1$ //$NON-NLS-2$
548 }
549 }
550
551 return null;
552 }
553
554 private static String getCategory(IConfigurationElement ce) {
555 String categoryId = ce.getAttribute(TmfTraceType.CATEGORY_ATTR);
556 if (categoryId != null) {
557 IConfigurationElement category = sfTraceCategories.get(categoryId);
558 if (category != null) {
559 return category.getAttribute(TmfTraceType.NAME_ATTR);
560 }
561 }
562 return "[no category]"; //$NON-NLS-1$
563 }
564
565 /*
566 * (non-Javadoc)
567 * @see org.eclipse.ui.views.properties.IPropertySource#resetPropertyValue(java.lang.Object)
568 */
569 @Override
570 public void resetPropertyValue(Object id) {
571 }
572
573 /*
574 * (non-Javadoc)
575 * @see org.eclipse.ui.views.properties.IPropertySource#setPropertyValue(java.lang.Object, java.lang.Object)
576 */
577 @Override
578 public void setPropertyValue(Object id, Object value) {
579 }
580
581 /*
582 * (non-Javadoc)
583 * @see org.eclipse.ui.views.properties.IPropertySource2#isPropertyResettable(java.lang.Object)
584 */
585 @Override
586 public boolean isPropertyResettable(Object id) {
587 return false;
588 }
589
590 /*
591 * (non-Javadoc)
592 * @see org.eclipse.ui.views.properties.IPropertySource2#isPropertySet(java.lang.Object)
593 */
594 @Override
595 public boolean isPropertySet(Object id) {
596 return false;
597 }
598
599 }
This page took 0.044216 seconds and 5 git commands to generate.