1 /*******************************************************************************
2 * Copyright (c) 2010 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 * Patrick Tasse - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.ui
.editors
;
15 import java
.io
.FileNotFoundException
;
16 import java
.lang
.reflect
.Constructor
;
17 import java
.lang
.reflect
.InvocationTargetException
;
18 import java
.util
.List
;
20 import org
.eclipse
.core
.resources
.IFile
;
21 import org
.eclipse
.core
.resources
.IMarker
;
22 import org
.eclipse
.core
.resources
.IMarkerDelta
;
23 import org
.eclipse
.core
.resources
.IResource
;
24 import org
.eclipse
.core
.resources
.IResourceChangeEvent
;
25 import org
.eclipse
.core
.resources
.IResourceChangeListener
;
26 import org
.eclipse
.core
.resources
.IResourceDelta
;
27 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
28 import org
.eclipse
.core
.runtime
.CoreException
;
29 import org
.eclipse
.core
.runtime
.IConfigurationElement
;
30 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
31 import org
.eclipse
.core
.runtime
.InvalidRegistryObjectException
;
32 import org
.eclipse
.core
.runtime
.Platform
;
33 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfEvent
;
34 import org
.eclipse
.linuxtools
.tmf
.core
.experiment
.TmfExperiment
;
35 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignalHandler
;
36 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceSelectedSignal
;
37 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
38 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfTrace
;
39 import org
.eclipse
.linuxtools
.tmf
.core
.util
.TmfTraceType
;
40 import org
.eclipse
.linuxtools
.tmf
.ui
.parsers
.custom
.CustomEventsTable
;
41 import org
.eclipse
.linuxtools
.tmf
.ui
.parsers
.custom
.CustomTxtTrace
;
42 import org
.eclipse
.linuxtools
.tmf
.ui
.parsers
.custom
.CustomXmlTrace
;
43 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.handlers
.Messages
;
44 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.ITmfProjectModelElement
;
45 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfExperimentElement
;
46 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfNavigatorContentProvider
;
47 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfProjectElement
;
48 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfProjectRegistry
;
49 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceElement
;
50 import org
.eclipse
.linuxtools
.tmf
.ui
.signal
.TmfTraceClosedSignal
;
51 import org
.eclipse
.linuxtools
.tmf
.ui
.signal
.TmfTraceOpenedSignal
;
52 import org
.eclipse
.linuxtools
.tmf
.ui
.signal
.TmfTraceParserUpdatedSignal
;
53 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.events
.TmfEventsTable
;
54 import org
.eclipse
.swt
.widgets
.Composite
;
55 import org
.eclipse
.swt
.widgets
.Display
;
56 import org
.eclipse
.ui
.IEditorInput
;
57 import org
.eclipse
.ui
.IEditorPart
;
58 import org
.eclipse
.ui
.IEditorSite
;
59 import org
.eclipse
.ui
.IFileEditorInput
;
60 import org
.eclipse
.ui
.IPropertyListener
;
61 import org
.eclipse
.ui
.IReusableEditor
;
62 import org
.eclipse
.ui
.PartInitException
;
63 import org
.eclipse
.ui
.ide
.IGotoMarker
;
64 import org
.eclipse
.ui
.part
.FileEditorInput
;
65 import org
.osgi
.framework
.Bundle
;
68 * <b><u>TmfEventsEditor</u></b>
70 public class TmfEventsEditor
extends TmfEditor
implements ITmfTraceEditor
, IReusableEditor
, IPropertyListener
, IResourceChangeListener
{
72 public static final String ID
= "org.eclipse.linuxtools.tmf.ui.editors.events"; //$NON-NLS-1$
74 private TmfEventsTable fEventsTable
;
76 @SuppressWarnings("rawtypes")
77 private ITmfTrace fTrace
;
78 private Composite fParent
;
81 public void doSave(IProgressMonitor monitor
) {
85 public void doSaveAs() {
88 @SuppressWarnings({ "unchecked", "rawtypes" })
90 public void init(IEditorSite site
, IEditorInput input
) throws PartInitException
{
91 if (input
instanceof TmfEditorInput
) {
92 fFile
= ((TmfEditorInput
) input
).getFile();
93 fTrace
= ((TmfEditorInput
) input
).getTrace();
94 input
= new FileEditorInput(fFile
);
95 } else if (input
instanceof IFileEditorInput
) {
96 fFile
= ((IFileEditorInput
) input
).getFile();
98 throw new PartInitException("Invalid IFileEditorInput: " + input
); //$NON-NLS-1$
101 String traceTypeId
= fFile
.getPersistentProperty(TmfTraceElement
.TRACETYPE
);
102 if (traceTypeId
== null) {
103 throw new PartInitException(Messages
.OpenTraceHandler_NoTraceType
);
105 if (traceTypeId
.equals(TmfExperiment
.class.getCanonicalName())) {
106 // Special case: experiment bookmark resource
107 TmfNavigatorContentProvider ncp
= new TmfNavigatorContentProvider();
108 ncp
.getChildren(fFile
.getProject()); // force the model to be populated
109 TmfProjectElement project
= TmfProjectRegistry
.getProject(fFile
.getProject());
110 if (project
== null) {
111 throw new PartInitException(Messages
.OpenExperimentHandler_NoTraceType
);
113 for (ITmfProjectModelElement projectElement
: project
.getExperimentsFolder().getChildren()) {
114 String traceName
= fFile
.getParent().getName();
115 if (projectElement
.getName().equals(traceName
)) {
116 TmfExperimentElement experimentElement
= (TmfExperimentElement
) projectElement
;
117 // Instantiate the experiment's traces
118 List
<TmfTraceElement
> traceEntries
= experimentElement
.getTraces();
119 int nbTraces
= traceEntries
.size();
120 int cacheSize
= Integer
.MAX_VALUE
;
121 ITmfTrace
<?
>[] traces
= new ITmfTrace
[nbTraces
];
122 for (int i
= 0; i
< nbTraces
; i
++) {
123 TmfTraceElement traceElement
= traceEntries
.get(i
);
124 ITmfTrace trace
= traceElement
.instantiateTrace();
125 TmfEvent traceEvent
= traceElement
.instantiateEvent();
126 if (trace
== null || traceEvent
== null) {
127 for (int j
= 0; j
< i
; j
++) {
130 throw new PartInitException(Messages
.OpenExperimentHandler_NoTraceType
);
133 trace
.initTrace(traceElement
.getName(), traceElement
.getLocation().getPath(), traceEvent
.getClass(), false);
134 } catch (FileNotFoundException e
) {
136 trace
.setResource(traceElement
.getResource());
137 cacheSize
= Math
.min(cacheSize
, trace
.getCacheSize());
140 TmfExperiment experiment
= new TmfExperiment(TmfEvent
.class, experimentElement
.getName(), traces
, cacheSize
);
141 experiment
.setBookmarksFile(fFile
);
143 experiment
.initTrace(null, null, null, true);
147 } else if (traceTypeId
.equals(TmfTrace
.class.getCanonicalName())) {
148 // Special case: trace bookmark resource
149 TmfNavigatorContentProvider ncp
= new TmfNavigatorContentProvider();
150 ncp
.getChildren(fFile
.getProject()); // force the model to be populated
151 TmfProjectElement project
= TmfProjectRegistry
.getProject(fFile
.getProject());
152 for (ITmfProjectModelElement projectElement
: project
.getTracesFolder().getChildren()) {
153 String traceName
= fFile
.getParent().getName();
154 if (projectElement
.getName().equals(traceName
)) {
155 TmfTraceElement traceElement
= (TmfTraceElement
) projectElement
;
156 // Instantiate the trace
157 ITmfTrace trace
= traceElement
.instantiateTrace();
158 TmfEvent traceEvent
= traceElement
.instantiateEvent();
159 if (trace
== null || traceEvent
== null) {
160 throw new PartInitException(Messages
.OpenTraceHandler_NoTraceType
);
163 trace
.initTrace(traceElement
.getName(), traceElement
.getLocation().getPath(), traceEvent
.getClass(), true);
164 } catch (FileNotFoundException e
) {
166 trace
.setResource(traceElement
.getResource());
172 TmfNavigatorContentProvider ncp
= new TmfNavigatorContentProvider();
173 ncp
.getChildren(fFile
.getProject()); // force the model to be populated
174 TmfProjectElement project
= TmfProjectRegistry
.getProject(fFile
.getProject());
175 for (ITmfProjectModelElement projectElement
: project
.getTracesFolder().getChildren()) {
176 if (projectElement
.getResource().equals(fFile
)) {
177 TmfTraceElement traceElement
= (TmfTraceElement
) projectElement
;
178 // Instantiate the trace
179 ITmfTrace trace
= traceElement
.instantiateTrace();
180 TmfEvent traceEvent
= traceElement
.instantiateEvent();
181 if (trace
== null || traceEvent
== null) {
182 throw new PartInitException(Messages
.OpenTraceHandler_NoTraceType
);
185 trace
.initTrace(traceElement
.getName(), traceElement
.getLocation().getPath(), traceEvent
.getClass(), true);
186 } catch (FileNotFoundException e
) {
188 if (trace
instanceof TmfTrace
) {
189 ((TmfTrace
) trace
).setResource(traceElement
.getResource());
196 } catch (InvalidRegistryObjectException e
) {
198 } catch (PartInitException e
) {
200 } catch (CoreException e
) {
204 throw new PartInitException("Invalid IEditorInput: " + input
.getClass()); //$NON-NLS-1$
206 if (fTrace
== null) {
207 throw new PartInitException("Invalid IEditorInput: " + fFile
.getName()); //$NON-NLS-1$
210 super.setInput(input
);
214 public boolean isDirty() {
219 public boolean isSaveAsAllowed() {
224 public void setInput(IEditorInput input
) {
225 super.setInput(input
);
226 firePropertyChange(IEditorPart
.PROP_INPUT
);
230 public void propertyChanged(Object source
, int propId
) {
231 if (propId
== IEditorPart
.PROP_INPUT
) {
232 broadcast(new TmfTraceClosedSignal(this, fTrace
));
233 fFile
= ((TmfEditorInput
) getEditorInput()).getFile();
234 fTrace
= ((TmfEditorInput
) getEditorInput()).getTrace();
235 super.setInput(new FileEditorInput(fFile
));
236 fEventsTable
.dispose();
237 if (fTrace
!= null) {
238 fEventsTable
= createEventsTable(fParent
, fTrace
.getCacheSize());
239 fEventsTable
.setTrace(fTrace
, true);
240 fEventsTable
.refreshBookmarks(fFile
);
241 broadcast(new TmfTraceOpenedSignal(this, fTrace
, fFile
, fEventsTable
));
243 fEventsTable
= new TmfEventsTable(fParent
, 0);
250 public void createPartControl(Composite parent
) {
252 if (fTrace
!= null) {
253 setPartName(fTrace
.getName());
254 fEventsTable
= createEventsTable(parent
, fTrace
.getCacheSize());
255 fEventsTable
.setTrace(fTrace
, true);
256 fEventsTable
.refreshBookmarks(fFile
);
257 broadcast(new TmfTraceOpenedSignal(this, fTrace
, fFile
, fEventsTable
));
259 setPartName(getEditorInput().getName());
260 fEventsTable
= new TmfEventsTable(parent
, 0);
262 addPropertyListener(this);
263 ResourcesPlugin
.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent
.POST_CHANGE
);
267 public void dispose() {
268 ResourcesPlugin
.getWorkspace().removeResourceChangeListener(this);
269 removePropertyListener(this);
270 if (fTrace
!= null) {
271 broadcast(new TmfTraceClosedSignal(this, fTrace
));
273 if (fEventsTable
!= null) {
274 fEventsTable
.dispose();
279 protected TmfEventsTable
createEventsTable(Composite parent
, int cacheSize
) {
280 TmfEventsTable eventsTable
= getEventsTable(parent
, cacheSize
);
281 if (eventsTable
== null) {
282 eventsTable
= new TmfEventsTable(parent
, cacheSize
);
287 private TmfEventsTable
getEventsTable(Composite parent
, int cacheSize
) {
288 if (fTrace
instanceof TmfExperiment
) {
289 return getExperimentEventsTable((TmfExperiment
<?
>) fTrace
, parent
, cacheSize
);
291 TmfEventsTable eventsTable
= null;
293 String traceType
= null;
294 traceType
= fTrace
.getResource().getPersistentProperty(TmfTraceElement
.TRACETYPE
);
295 if (traceType
== null) {
298 if (traceType
.startsWith(CustomTxtTrace
.class.getCanonicalName())) {
299 return new CustomEventsTable(((CustomTxtTrace
) fTrace
).getDefinition(), parent
, cacheSize
);
301 if (traceType
.startsWith(CustomXmlTrace
.class.getCanonicalName())) {
302 return new CustomEventsTable(((CustomXmlTrace
) fTrace
).getDefinition(), parent
, cacheSize
);
304 for (IConfigurationElement ce
: TmfTraceType
.getTypeElements()) {
305 if (ce
.getAttribute(TmfTraceType
.ID_ATTR
).equals(traceType
)) {
306 IConfigurationElement
[] eventsTableTypeCE
= ce
.getChildren(TmfTraceType
.EVENTS_TABLE_TYPE_ELEM
);
307 if (eventsTableTypeCE
.length
!= 1) {
310 String eventsTableType
= eventsTableTypeCE
[0].getAttribute(TmfTraceType
.CLASS_ATTR
);
311 if (eventsTableType
== null || eventsTableType
.length() == 0) {
314 Bundle bundle
= Platform
.getBundle(ce
.getContributor().getName());
315 Class
<?
> c
= bundle
.loadClass(eventsTableType
);
316 Class
<?
>[] constructorArgs
= new Class
[] { Composite
.class, int.class };
317 Constructor
<?
> constructor
= c
.getConstructor(constructorArgs
);
318 Object
[] args
= new Object
[] { parent
, cacheSize
};
319 eventsTable
= (TmfEventsTable
) constructor
.newInstance(args
);
323 } catch (InvalidRegistryObjectException e
) {
325 } catch (CoreException e
) {
327 } catch (ClassNotFoundException e
) {
329 } catch (SecurityException e
) {
331 } catch (NoSuchMethodException e
) {
333 } catch (IllegalArgumentException e
) {
335 } catch (InstantiationException e
) {
337 } catch (IllegalAccessException e
) {
339 } catch (InvocationTargetException e
) {
346 * Get the events table for an experiment.
347 * If all traces in the experiment are of the same type,
348 * use the extension point specified event table
349 * @param experiment the experiment
350 * @param parent the parent Composite
351 * @param cacheSize the event table cache size
352 * @return an events table of the appropriate type
354 private TmfEventsTable
getExperimentEventsTable(TmfExperiment
<?
> experiment
, Composite parent
, int cacheSize
) {
355 TmfEventsTable eventsTable
= null;
356 String commonTraceType
= null;
358 for (ITmfTrace
<?
> trace
: experiment
.getTraces()) {
359 IResource resource
= trace
.getResource();
360 if (resource
== null) {
363 String traceType
= resource
.getPersistentProperty(TmfTraceElement
.TRACETYPE
);
364 if (commonTraceType
!= null && !commonTraceType
.equals(traceType
)) {
367 commonTraceType
= traceType
;
369 if (commonTraceType
== null) {
372 if (commonTraceType
.startsWith(CustomTxtTrace
.class.getCanonicalName())) {
373 return new CustomEventsTable(((CustomTxtTrace
) experiment
.getTraces()[0]).getDefinition(), parent
, cacheSize
);
375 if (commonTraceType
.startsWith(CustomXmlTrace
.class.getCanonicalName())) {
376 return new CustomEventsTable(((CustomXmlTrace
) experiment
.getTraces()[0]).getDefinition(), parent
, cacheSize
);
378 for (IConfigurationElement ce
: TmfTraceType
.getTypeElements()) {
379 if (ce
.getAttribute(TmfTraceType
.ID_ATTR
).equals(commonTraceType
)) {
380 IConfigurationElement
[] eventsTableTypeCE
= ce
.getChildren(TmfTraceType
.EVENTS_TABLE_TYPE_ELEM
);
381 if (eventsTableTypeCE
.length
!= 1) {
384 String eventsTableType
= eventsTableTypeCE
[0].getAttribute(TmfTraceType
.CLASS_ATTR
);
385 if (eventsTableType
== null || eventsTableType
.length() == 0) {
388 Bundle bundle
= Platform
.getBundle(ce
.getContributor().getName());
389 Class
<?
> c
= bundle
.loadClass(eventsTableType
);
390 Class
<?
>[] constructorArgs
= new Class
[] { Composite
.class, int.class };
391 Constructor
<?
> constructor
= c
.getConstructor(constructorArgs
);
392 Object
[] args
= new Object
[] { parent
, cacheSize
};
393 eventsTable
= (TmfEventsTable
) constructor
.newInstance(args
);
397 } catch (CoreException e
) {
399 } catch (InvalidRegistryObjectException e
) {
401 } catch (SecurityException e
) {
403 } catch (IllegalArgumentException e
) {
405 } catch (ClassNotFoundException e
) {
407 } catch (NoSuchMethodException e
) {
409 } catch (InstantiationException e
) {
411 } catch (IllegalAccessException e
) {
413 } catch (InvocationTargetException e
) {
420 public ITmfTrace
<?
> getTrace() {
425 public IFile
getBookmarksFile() {
430 public void setFocus() {
431 fEventsTable
.setFocus();
432 if (fTrace
!= null) {
433 broadcast(new TmfTraceSelectedSignal(this, fTrace
));
438 @SuppressWarnings("rawtypes")
439 public Object
getAdapter(Class adapter
) {
440 if (IGotoMarker
.class.equals(adapter
)) {
443 return super.getAdapter(adapter
);
447 public void resourceChanged(IResourceChangeEvent event
) {
448 for (IMarkerDelta delta
: event
.findMarkerDeltas(IMarker
.BOOKMARK
, false)) {
449 if (delta
.getResource().equals(fFile
)) {
450 if (delta
.getKind() == IResourceDelta
.REMOVED
) {
451 final IMarker bookmark
= delta
.getMarker();
452 Display
.getDefault().asyncExec(new Runnable() {
455 fEventsTable
.removeBookmark(bookmark
);
458 } else if (delta
.getKind() == IResourceDelta
.CHANGED
) {
459 Display
.getDefault().asyncExec(new Runnable() {
462 fEventsTable
.getTable().refresh();
470 // ------------------------------------------------------------------------
472 // ------------------------------------------------------------------------
474 public void addBookmark() {
475 fEventsTable
.addBookmark(fFile
);
479 // ------------------------------------------------------------------------
481 // ------------------------------------------------------------------------
483 @SuppressWarnings("unchecked")
485 public void traceParserUpdated(TmfTraceParserUpdatedSignal signal
) {
486 if (signal
.getTraceResource().equals(fFile
)) {
487 broadcast(new TmfTraceClosedSignal(this, fTrace
));
489 String name
= fTrace
.getName();
491 String traceTypeId
= fFile
.getPersistentProperty(TmfTraceElement
.TRACETYPE
);
492 if (traceTypeId
!= null) {
493 for (IConfigurationElement ce
: TmfTraceType
.getTypeElements()) {
494 if (traceTypeId
.equals(ce
.getAttribute(TmfTraceType
.ID_ATTR
))) {
495 fTrace
= (ITmfTrace
<?
>) ce
.createExecutableExtension(TmfTraceType
.TRACE_TYPE_ATTR
);
496 TmfEvent event
= (TmfEvent
) ce
.createExecutableExtension(TmfTraceType
.EVENT_TYPE_ATTR
);
497 String path
= fFile
.getLocationURI().getPath();
498 fTrace
.initTrace(name
, path
, event
.getClass(), true);
503 } catch (InvalidRegistryObjectException e
) {
505 } catch (FileNotFoundException e
) {
507 } catch (CoreException e
) {
510 fEventsTable
.dispose();
511 if (fTrace
!= null) {
512 fEventsTable
= createEventsTable(fParent
, fTrace
.getCacheSize());
513 fEventsTable
.setTrace(fTrace
, true);
514 broadcast(new TmfTraceOpenedSignal(this, fTrace
, fFile
, fEventsTable
));
516 fEventsTable
= new TmfEventsTable(fParent
, 0);
523 public void traceSelected(TmfTraceSelectedSignal signal
) {
524 if (signal
.getSource() != this && signal
.getTrace().equals(fTrace
)) {
525 getSite().getPage().bringToTop(this);