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
.IMarker
;
21 import org
.eclipse
.core
.resources
.IMarkerDelta
;
22 import org
.eclipse
.core
.resources
.IResource
;
23 import org
.eclipse
.core
.resources
.IResourceChangeEvent
;
24 import org
.eclipse
.core
.resources
.IResourceChangeListener
;
25 import org
.eclipse
.core
.resources
.IResourceDelta
;
26 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
27 import org
.eclipse
.core
.runtime
.CoreException
;
28 import org
.eclipse
.core
.runtime
.IConfigurationElement
;
29 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
30 import org
.eclipse
.core
.runtime
.InvalidRegistryObjectException
;
31 import org
.eclipse
.core
.runtime
.Platform
;
32 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfEvent
;
33 import org
.eclipse
.linuxtools
.tmf
.core
.experiment
.TmfExperiment
;
34 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfExperimentSelectedSignal
;
35 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignalHandler
;
36 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignalManager
;
37 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceSelectedSignal
;
38 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
39 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfTrace
;
40 import org
.eclipse
.linuxtools
.tmf
.core
.util
.TmfTraceType
;
41 import org
.eclipse
.linuxtools
.tmf
.ui
.parsers
.custom
.CustomEventsTable
;
42 import org
.eclipse
.linuxtools
.tmf
.ui
.parsers
.custom
.CustomTxtTrace
;
43 import org
.eclipse
.linuxtools
.tmf
.ui
.parsers
.custom
.CustomXmlTrace
;
44 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.handlers
.Messages
;
45 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.ITmfProjectModelElement
;
46 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfExperimentElement
;
47 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfNavigatorContentProvider
;
48 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfProjectElement
;
49 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfProjectRegistry
;
50 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceElement
;
51 import org
.eclipse
.linuxtools
.tmf
.ui
.signal
.TmfTraceClosedSignal
;
52 import org
.eclipse
.linuxtools
.tmf
.ui
.signal
.TmfTraceOpenedSignal
;
53 import org
.eclipse
.linuxtools
.tmf
.ui
.signal
.TmfTraceParserUpdatedSignal
;
54 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.events
.TmfEventsTable
;
55 import org
.eclipse
.swt
.widgets
.Composite
;
56 import org
.eclipse
.swt
.widgets
.Display
;
57 import org
.eclipse
.ui
.IEditorInput
;
58 import org
.eclipse
.ui
.IEditorPart
;
59 import org
.eclipse
.ui
.IEditorSite
;
60 import org
.eclipse
.ui
.IFileEditorInput
;
61 import org
.eclipse
.ui
.IPropertyListener
;
62 import org
.eclipse
.ui
.IReusableEditor
;
63 import org
.eclipse
.ui
.PartInitException
;
64 import org
.eclipse
.ui
.ide
.IGotoMarker
;
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
;
75 private IResource fResource
;
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 fResource
= ((TmfEditorInput
) input
).getResource();
93 fTrace
= ((TmfEditorInput
) input
).getTrace();
94 } else if (input
instanceof IFileEditorInput
) {
95 fResource
= ((IFileEditorInput
) input
).getFile();
96 if (fResource
== null) {
97 throw new PartInitException("Invalid IFileEditorInput: " + input
); //$NON-NLS-1$
100 String traceTypeId
= fResource
.getPersistentProperty(TmfTraceElement
.TRACETYPE
);
101 if (traceTypeId
.equals(TmfExperiment
.class.getCanonicalName())) {
102 // Special case: experiment bookmark resource
103 TmfNavigatorContentProvider ncp
= new TmfNavigatorContentProvider();
104 ncp
.getChildren(fResource
.getProject()); // force the model to be populated
105 TmfProjectElement project
= TmfProjectRegistry
.getProject(fResource
.getProject());
106 if (project
== null) {
107 throw new PartInitException(Messages
.OpenExperimentHandler_NoTraceType
);
109 for (ITmfProjectModelElement projectElement
: project
.getExperimentsFolder().getChildren()) {
110 String traceName
= fResource
.getParent().getName();
111 if (projectElement
.getName().equals(traceName
)) {
112 TmfExperimentElement experimentElement
= (TmfExperimentElement
) projectElement
;
113 // Instantiate the experiment's traces
114 List
<TmfTraceElement
> traceEntries
= experimentElement
.getTraces();
115 int nbTraces
= traceEntries
.size();
116 int cacheSize
= Integer
.MAX_VALUE
;
117 ITmfTrace
<?
>[] traces
= new ITmfTrace
[nbTraces
];
118 for (int i
= 0; i
< nbTraces
; i
++) {
119 TmfTraceElement traceElement
= traceEntries
.get(i
);
120 ITmfTrace trace
= traceElement
.instantiateTrace();
121 TmfEvent traceEvent
= traceElement
.instantiateEvent();
122 if (trace
== null || traceEvent
== null) {
123 for (int j
= 0; j
< i
; j
++) {
126 throw new PartInitException(Messages
.OpenExperimentHandler_NoTraceType
);
129 trace
.initTrace(traceElement
.getLocation().getPath(), traceEvent
.getClass(), false);
130 } catch (FileNotFoundException e
) {
132 if (trace
instanceof TmfTrace
) {
133 ((TmfTrace
) trace
).setResource(traceElement
.getResource());
135 cacheSize
= Math
.min(cacheSize
, trace
.getCacheSize());
138 TmfExperiment experiment
= new TmfExperiment(TmfEvent
.class, experimentElement
.getName(), traces
, cacheSize
);
139 experiment
.setResource(fResource
);
141 TmfExperiment
.setCurrentExperiment(experiment
);
142 TmfSignalManager
.dispatchSignal(new TmfExperimentSelectedSignal(this, experiment
));
146 } else if (traceTypeId
.equals(TmfTrace
.class.getCanonicalName())) {
147 // Special case: trace bookmark resource
148 TmfNavigatorContentProvider ncp
= new TmfNavigatorContentProvider();
149 ncp
.getChildren(fResource
.getProject()); // force the model to be populated
150 TmfProjectElement project
= TmfProjectRegistry
.getProject(fResource
.getProject());
151 for (ITmfProjectModelElement projectElement
: project
.getTracesFolder().getChildren()) {
152 String experimentName
= fResource
.getParent().getName();
153 if (projectElement
.getName().equals(experimentName
)) {
154 TmfTraceElement traceElement
= (TmfTraceElement
) projectElement
;
155 // Instantiate the experiment trace
156 ITmfTrace trace
= traceElement
.instantiateTrace();
157 TmfEvent traceEvent
= traceElement
.instantiateEvent();
158 if (trace
== null || traceEvent
== null) {
159 throw new PartInitException(Messages
.OpenTraceHandler_NoTraceType
);
162 trace
.initTrace(traceElement
.getLocation().getPath(), traceEvent
.getClass(), false);
163 } catch (FileNotFoundException e
) {
165 if (trace
instanceof TmfTrace
) {
166 ((TmfTrace
) trace
).setResource(traceElement
.getResource());
168 ITmfTrace
[] traces
= new ITmfTrace
[] { trace
};
169 TmfExperiment experiment
= new TmfExperiment(traceEvent
.getClass(), traceElement
.getName(), traces
, trace
.getCacheSize());
170 experiment
.setResource(fResource
);
172 TmfExperiment
.setCurrentExperiment(experiment
);
173 TmfSignalManager
.dispatchSignal(new TmfExperimentSelectedSignal(this, experiment
));
177 } else if (traceTypeId
!= null) {
178 for (IConfigurationElement ce
: TmfTraceType
.getTypeElements()) {
179 if (traceTypeId
.equals(ce
.getAttribute(TmfTraceType
.ID_ATTR
))) {
180 fTrace
= (ITmfTrace
<?
>) ce
.createExecutableExtension(TmfTraceType
.TRACE_TYPE_ATTR
);
181 TmfEvent event
= (TmfEvent
) ce
.createExecutableExtension(TmfTraceType
.EVENT_TYPE_ATTR
);
182 String path
= fResource
.getLocationURI().getPath();
183 fTrace
.initTrace(path
, event
.getClass(), true);
188 } catch (InvalidRegistryObjectException e
) {
190 } catch (FileNotFoundException e
) {
192 } catch (PartInitException e
) {
194 } catch (CoreException e
) {
197 input
= new TmfEditorInput(fResource
, fTrace
);
199 throw new PartInitException("Invalid IEditorInput: " + input
.getClass()); //$NON-NLS-1$
201 if (fTrace
== null) {
202 throw new PartInitException("Invalid IEditorInput: " + fResource
.getName()); //$NON-NLS-1$
205 super.setInput(input
);
209 public boolean isDirty() {
214 public boolean isSaveAsAllowed() {
219 public void setInput(IEditorInput input
) {
220 super.setInput(input
);
221 firePropertyChange(IEditorPart
.PROP_INPUT
);
225 public void propertyChanged(Object source
, int propId
) {
226 if (propId
== IEditorPart
.PROP_INPUT
) {
227 broadcast(new TmfTraceClosedSignal(this, fTrace
));
228 fResource
= ((TmfEditorInput
) getEditorInput()).getResource();
229 fTrace
= ((TmfEditorInput
) getEditorInput()).getTrace();
230 fEventsTable
.dispose();
231 if (fTrace
!= null) {
232 fEventsTable
= createEventsTable(fParent
, fTrace
.getCacheSize());
233 fEventsTable
.setTrace(fTrace
, true);
234 fEventsTable
.refreshBookmarks(fResource
);
235 broadcast(new TmfTraceOpenedSignal(this, fTrace
, fResource
, fEventsTable
));
237 fEventsTable
= new TmfEventsTable(fParent
, 0);
244 public void createPartControl(Composite parent
) {
246 setPartName(getEditorInput().getName());
247 if (fTrace
!= null) {
248 fEventsTable
= createEventsTable(parent
, fTrace
.getCacheSize());
249 fEventsTable
.setTrace(fTrace
, true);
250 fEventsTable
.refreshBookmarks(fResource
);
251 broadcast(new TmfTraceOpenedSignal(this, fTrace
, fResource
, fEventsTable
));
253 fEventsTable
= new TmfEventsTable(parent
, 0);
255 addPropertyListener(this);
256 ResourcesPlugin
.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent
.POST_CHANGE
);
260 public void dispose() {
261 ResourcesPlugin
.getWorkspace().removeResourceChangeListener(this);
262 removePropertyListener(this);
263 if (fTrace
!= null) {
264 broadcast(new TmfTraceClosedSignal(this, fTrace
));
266 if (fEventsTable
!= null) {
267 fEventsTable
.dispose();
272 protected TmfEventsTable
createEventsTable(Composite parent
, int cacheSize
) {
273 TmfEventsTable eventsTable
= getEventsTable(parent
, cacheSize
);
274 if (eventsTable
== null) {
275 eventsTable
= new TmfEventsTable(parent
, cacheSize
);
280 private TmfEventsTable
getEventsTable(Composite parent
, int cacheSize
) {
281 if (fTrace
instanceof TmfExperiment
) {
282 return getExperimentEventsTable((TmfExperiment
<?
>) fTrace
, parent
, cacheSize
);
284 TmfEventsTable eventsTable
= null;
286 String traceType
= fResource
.getPersistentProperty(TmfTraceElement
.TRACETYPE
);
287 if (traceType
.startsWith(CustomTxtTrace
.class.getCanonicalName())) {
288 return new CustomEventsTable(((CustomTxtTrace
) fTrace
).getDefinition(), parent
, cacheSize
);
290 if (traceType
.startsWith(CustomXmlTrace
.class.getCanonicalName())) {
291 return new CustomEventsTable(((CustomXmlTrace
) fTrace
).getDefinition(), parent
, cacheSize
);
293 for (IConfigurationElement ce
: TmfTraceType
.getTypeElements()) {
294 if (ce
.getAttribute(TmfTraceType
.ID_ATTR
).equals(traceType
)) {
295 IConfigurationElement
[] eventsTableTypeCE
= ce
.getChildren(TmfTraceType
.EVENTS_TABLE_TYPE_ELEM
);
296 if (eventsTableTypeCE
.length
!= 1) {
299 String eventsTableType
= eventsTableTypeCE
[0].getAttribute(TmfTraceType
.CLASS_ATTR
);
300 if (eventsTableType
== null || eventsTableType
.length() == 0) {
303 Bundle bundle
= Platform
.getBundle(ce
.getContributor().getName());
304 Class
<?
> c
= bundle
.loadClass(eventsTableType
);
305 Class
<?
>[] constructorArgs
= new Class
[] { Composite
.class, int.class };
306 Constructor
<?
> constructor
= c
.getConstructor(constructorArgs
);
307 Object
[] args
= new Object
[] { parent
, cacheSize
};
308 eventsTable
= (TmfEventsTable
) constructor
.newInstance(args
);
312 } catch (InvalidRegistryObjectException e
) {
314 } catch (CoreException e
) {
316 } catch (ClassNotFoundException e
) {
318 } catch (SecurityException e
) {
320 } catch (NoSuchMethodException e
) {
322 } catch (IllegalArgumentException e
) {
324 } catch (InstantiationException e
) {
326 } catch (IllegalAccessException e
) {
328 } catch (InvocationTargetException e
) {
335 * Get the events table for an experiment.
336 * If all traces in the experiment are of the same type,
337 * use the extension point specified event table
338 * @param experiment the experiment
339 * @param parent the parent Composite
340 * @param cacheSize the event table cache size
341 * @return an events table of the appropriate type
343 private TmfEventsTable
getExperimentEventsTable(TmfExperiment
<?
> experiment
, Composite parent
, int cacheSize
) {
344 TmfEventsTable eventsTable
= null;
345 String commonTraceType
= null;
347 for (ITmfTrace
<?
> trace
: experiment
.getTraces()) {
348 IResource resource
= null;
349 if (trace
instanceof TmfTrace
) {
350 resource
= ((TmfTrace
<?
>) trace
).getResource();
352 if (resource
== null) {
355 String traceType
= resource
.getPersistentProperty(TmfTraceElement
.TRACETYPE
);
356 if (commonTraceType
!= null && !commonTraceType
.equals(traceType
)) {
359 commonTraceType
= traceType
;
361 if (commonTraceType
== null) {
364 if (commonTraceType
.startsWith(CustomTxtTrace
.class.getCanonicalName())) {
365 return new CustomEventsTable(((CustomTxtTrace
) experiment
.getTraces()[0]).getDefinition(), parent
, cacheSize
);
367 if (commonTraceType
.startsWith(CustomXmlTrace
.class.getCanonicalName())) {
368 return new CustomEventsTable(((CustomXmlTrace
) experiment
.getTraces()[0]).getDefinition(), parent
, cacheSize
);
370 for (IConfigurationElement ce
: TmfTraceType
.getTypeElements()) {
371 if (ce
.getAttribute(TmfTraceType
.ID_ATTR
).equals(commonTraceType
)) {
372 IConfigurationElement
[] eventsTableTypeCE
= ce
.getChildren(TmfTraceType
.EVENTS_TABLE_TYPE_ELEM
);
373 if (eventsTableTypeCE
.length
!= 1) {
376 String eventsTableType
= eventsTableTypeCE
[0].getAttribute(TmfTraceType
.CLASS_ATTR
);
377 if (eventsTableType
== null || eventsTableType
.length() == 0) {
380 Bundle bundle
= Platform
.getBundle(ce
.getContributor().getName());
381 Class
<?
> c
= bundle
.loadClass(eventsTableType
);
382 Class
<?
>[] constructorArgs
= new Class
[] { Composite
.class, int.class };
383 Constructor
<?
> constructor
= c
.getConstructor(constructorArgs
);
384 Object
[] args
= new Object
[] { parent
, cacheSize
};
385 eventsTable
= (TmfEventsTable
) constructor
.newInstance(args
);
389 } catch (CoreException e
) {
391 } catch (InvalidRegistryObjectException e
) {
393 } catch (SecurityException e
) {
395 } catch (IllegalArgumentException e
) {
397 } catch (ClassNotFoundException e
) {
399 } catch (NoSuchMethodException e
) {
401 } catch (InstantiationException e
) {
403 } catch (IllegalAccessException e
) {
405 } catch (InvocationTargetException e
) {
412 public ITmfTrace
<?
> getTrace() {
417 public IResource
getResource() {
421 @SuppressWarnings({ "rawtypes", "unchecked" })
423 public void setFocus() {
424 fEventsTable
.setFocus();
425 if (fTrace
!= null) {
426 broadcast(new TmfTraceSelectedSignal(this, fTrace
));
427 if (fTrace
instanceof TmfExperiment
&& !fTrace
.equals(TmfExperiment
.getCurrentExperiment())) {
428 TmfExperiment experiment
= (TmfExperiment
) fTrace
;
429 TmfExperiment
.setCurrentExperiment(experiment
);
430 broadcast(new TmfExperimentSelectedSignal(this, experiment
));
436 @SuppressWarnings("rawtypes")
437 public Object
getAdapter(Class adapter
) {
438 if (IGotoMarker
.class.equals(adapter
)) {
441 return super.getAdapter(adapter
);
445 public void resourceChanged(IResourceChangeEvent event
) {
446 for (IMarkerDelta delta
: event
.findMarkerDeltas(IMarker
.BOOKMARK
, false)) {
447 if (delta
.getResource().equals(fResource
)) {
448 if (delta
.getKind() == IResourceDelta
.REMOVED
) {
449 final IMarker bookmark
= delta
.getMarker();
450 Display
.getDefault().asyncExec(new Runnable() {
453 fEventsTable
.removeBookmark(bookmark
);
456 } else if (delta
.getKind() == IResourceDelta
.CHANGED
) {
457 Display
.getDefault().asyncExec(new Runnable() {
460 fEventsTable
.getTable().refresh();
468 // ------------------------------------------------------------------------
470 // ------------------------------------------------------------------------
472 public void addBookmark() {
473 fEventsTable
.addBookmark(fResource
);
477 // ------------------------------------------------------------------------
479 // ------------------------------------------------------------------------
481 @SuppressWarnings("unchecked")
483 public void traceParserUpdated(TmfTraceParserUpdatedSignal signal
) {
484 if (signal
.getTraceResource().equals(fResource
)) {
485 broadcast(new TmfTraceClosedSignal(this, fTrace
));
488 String traceTypeId
= fResource
.getPersistentProperty(TmfTraceElement
.TRACETYPE
);
489 if (traceTypeId
!= null) {
490 for (IConfigurationElement ce
: TmfTraceType
.getTypeElements()) {
491 if (traceTypeId
.equals(ce
.getAttribute(TmfTraceType
.ID_ATTR
))) {
492 fTrace
= (ITmfTrace
<?
>) ce
.createExecutableExtension(TmfTraceType
.TRACE_TYPE_ATTR
);
493 TmfEvent event
= (TmfEvent
) ce
.createExecutableExtension(TmfTraceType
.EVENT_TYPE_ATTR
);
494 String path
= fResource
.getLocationURI().getPath();
495 fTrace
.initTrace(path
, event
.getClass(), true);
500 } catch (InvalidRegistryObjectException e
) {
502 } catch (FileNotFoundException e
) {
504 } catch (CoreException e
) {
507 fEventsTable
.dispose();
508 if (fTrace
!= null) {
509 fEventsTable
= createEventsTable(fParent
, fTrace
.getCacheSize());
510 fEventsTable
.setTrace(fTrace
, true);
511 broadcast(new TmfTraceOpenedSignal(this, fTrace
, fResource
, fEventsTable
));
513 fEventsTable
= new TmfEventsTable(fParent
, 0);
520 public void traceSelected(TmfTraceSelectedSignal signal
) {
521 if (signal
.getSource() != this && signal
.getTrace().equals(fTrace
)) {
522 getSite().getPage().bringToTop(this);