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
.lang
.reflect
.Constructor
;
16 import java
.lang
.reflect
.InvocationTargetException
;
17 import java
.util
.List
;
19 import org
.eclipse
.core
.resources
.IFile
;
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
.internal
.tmf
.ui
.parsers
.custom
.CustomEventsTable
;
33 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomTxtTrace
;
34 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomXmlTrace
;
35 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.project
.handlers
.Messages
;
36 import org
.eclipse
.linuxtools
.tmf
.core
.TmfCommonConstants
;
37 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
38 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfEvent
;
39 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.TmfTraceException
;
40 import org
.eclipse
.linuxtools
.tmf
.core
.experiment
.TmfExperiment
;
41 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignalHandler
;
42 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceSelectedSignal
;
43 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
44 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfTrace
;
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
.project
.model
.TmfTraceType
;
52 import org
.eclipse
.linuxtools
.tmf
.ui
.signal
.TmfTraceClosedSignal
;
53 import org
.eclipse
.linuxtools
.tmf
.ui
.signal
.TmfTraceOpenedSignal
;
54 import org
.eclipse
.linuxtools
.tmf
.ui
.signal
.TmfTraceParserUpdatedSignal
;
55 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.events
.TmfEventsTable
;
56 import org
.eclipse
.swt
.widgets
.Composite
;
57 import org
.eclipse
.swt
.widgets
.Display
;
58 import org
.eclipse
.ui
.IEditorInput
;
59 import org
.eclipse
.ui
.IEditorPart
;
60 import org
.eclipse
.ui
.IEditorSite
;
61 import org
.eclipse
.ui
.IFileEditorInput
;
62 import org
.eclipse
.ui
.IPropertyListener
;
63 import org
.eclipse
.ui
.IReusableEditor
;
64 import org
.eclipse
.ui
.PartInitException
;
65 import org
.eclipse
.ui
.ide
.IGotoMarker
;
66 import org
.eclipse
.ui
.part
.FileEditorInput
;
67 import org
.osgi
.framework
.Bundle
;
70 * <b><u>TmfEventsEditor</u></b>
72 public class TmfEventsEditor
extends TmfEditor
implements ITmfTraceEditor
, IReusableEditor
, IPropertyListener
, IResourceChangeListener
{
74 public static final String ID
= "org.eclipse.linuxtools.tmf.ui.editors.events"; //$NON-NLS-1$
76 private TmfEventsTable fEventsTable
;
78 @SuppressWarnings("rawtypes")
79 private ITmfTrace fTrace
;
80 private Composite fParent
;
83 public void doSave(final IProgressMonitor monitor
) {
87 public void doSaveAs() {
90 @SuppressWarnings({ "unchecked", "rawtypes" })
92 public void init(final IEditorSite site
, IEditorInput input
) throws PartInitException
{
93 if (input
instanceof TmfEditorInput
) {
94 fFile
= ((TmfEditorInput
) input
).getFile();
95 fTrace
= ((TmfEditorInput
) input
).getTrace();
96 input
= new FileEditorInput(fFile
);
97 } else if (input
instanceof IFileEditorInput
) {
98 fFile
= ((IFileEditorInput
) input
).getFile();
100 throw new PartInitException("Invalid IFileEditorInput: " + input
); //$NON-NLS-1$
102 final String traceTypeId
= fFile
.getPersistentProperty(TmfCommonConstants
.TRACETYPE
);
103 if (traceTypeId
== null)
104 throw new PartInitException(Messages
.OpenTraceHandler_NoTraceType
);
105 if (traceTypeId
.equals(TmfExperiment
.class.getCanonicalName())) {
106 // Special case: experiment bookmark resource
107 final TmfNavigatorContentProvider ncp
= new TmfNavigatorContentProvider();
108 ncp
.getChildren(fFile
.getProject()); // force the model to be populated
109 final TmfProjectElement project
= TmfProjectRegistry
.getProject(fFile
.getProject());
111 throw new PartInitException(Messages
.OpenExperimentHandler_NoTraceType
);
112 for (final ITmfProjectModelElement projectElement
: project
.getExperimentsFolder().getChildren()) {
113 final String traceName
= fFile
.getParent().getName();
114 if (projectElement
.getName().equals(traceName
)) {
115 final TmfExperimentElement experimentElement
= (TmfExperimentElement
) projectElement
;
116 // Instantiate the experiment's traces
117 final List
<TmfTraceElement
> traceEntries
= experimentElement
.getTraces();
118 final int nbTraces
= traceEntries
.size();
119 int cacheSize
= Integer
.MAX_VALUE
;
120 final ITmfTrace
<?
>[] traces
= new ITmfTrace
[nbTraces
];
121 for (int i
= 0; i
< nbTraces
; i
++) {
122 final TmfTraceElement traceElement
= traceEntries
.get(i
);
123 final ITmfTrace trace
= traceElement
.instantiateTrace();
124 final ITmfEvent traceEvent
= traceElement
.instantiateEvent();
125 if ((trace
== null) || (traceEvent
== null)) {
126 for (int j
= 0; j
< i
; j
++)
128 throw new PartInitException(Messages
.OpenExperimentHandler_NoTraceType
);
131 trace
.initTrace(traceElement
.getResource(), traceElement
.getLocation().getPath(), traceEvent
.getClass());
132 } catch (final TmfTraceException e
) {
134 cacheSize
= Math
.min(cacheSize
, trace
.getCacheSize());
137 final TmfExperiment experiment
= new TmfExperiment(ITmfEvent
.class, experimentElement
.getName(), traces
, cacheSize
);
138 experiment
.setBookmarksFile(fFile
);
140 experiment
.initTrace(null, null, null);
144 } else if (traceTypeId
.equals(TmfTrace
.class.getCanonicalName())) {
145 // Special case: trace bookmark resource
146 final TmfNavigatorContentProvider ncp
= new TmfNavigatorContentProvider();
147 ncp
.getChildren(fFile
.getProject()); // force the model to be populated
148 final TmfProjectElement project
= TmfProjectRegistry
.getProject(fFile
.getProject());
149 for (final ITmfProjectModelElement projectElement
: project
.getTracesFolder().getChildren()) {
150 final String traceName
= fFile
.getParent().getName();
151 if (projectElement
.getName().equals(traceName
)) {
152 final TmfTraceElement traceElement
= (TmfTraceElement
) projectElement
;
153 // Instantiate the trace
154 final ITmfTrace trace
= traceElement
.instantiateTrace();
155 final ITmfEvent traceEvent
= traceElement
.instantiateEvent();
156 if ((trace
== null) || (traceEvent
== null))
157 throw new PartInitException(Messages
.OpenTraceHandler_NoTraceType
);
159 trace
.initTrace(traceElement
.getResource(), traceElement
.getLocation().getPath(), traceEvent
.getClass());
160 } catch (final TmfTraceException e
) {
167 final TmfNavigatorContentProvider ncp
= new TmfNavigatorContentProvider();
168 ncp
.getChildren(fFile
.getProject()); // force the model to be populated
169 final TmfProjectElement project
= TmfProjectRegistry
.getProject(fFile
.getProject());
170 for (final ITmfProjectModelElement projectElement
: project
.getTracesFolder().getChildren())
171 if (projectElement
.getResource().equals(fFile
)) {
172 final TmfTraceElement traceElement
= (TmfTraceElement
) projectElement
;
173 // Instantiate the trace
174 final ITmfTrace trace
= traceElement
.instantiateTrace();
175 final ITmfEvent traceEvent
= traceElement
.instantiateEvent();
176 if ((trace
== null) || (traceEvent
== null))
177 throw new PartInitException(Messages
.OpenTraceHandler_NoTraceType
);
179 trace
.initTrace(traceElement
.getResource(), traceElement
.getLocation().getPath(), traceEvent
.getClass());
180 } catch (final TmfTraceException e
) {
186 } catch (final InvalidRegistryObjectException e
) {
188 } catch (final PartInitException e
) {
190 } catch (final CoreException e
) {
194 throw new PartInitException("Invalid IEditorInput: " + input
.getClass()); //$NON-NLS-1$
196 throw new PartInitException("Invalid IEditorInput: " + fFile
.getName()); //$NON-NLS-1$
198 super.setInput(input
);
202 public boolean isDirty() {
207 public boolean isSaveAsAllowed() {
212 public void setInput(final IEditorInput input
) {
213 super.setInput(input
);
214 firePropertyChange(IEditorPart
.PROP_INPUT
);
218 public void propertyChanged(final Object source
, final int propId
) {
219 if (propId
== IEditorPart
.PROP_INPUT
) {
220 broadcast(new TmfTraceClosedSignal(this, fTrace
));
221 fFile
= ((TmfEditorInput
) getEditorInput()).getFile();
222 fTrace
= ((TmfEditorInput
) getEditorInput()).getTrace();
223 super.setInput(new FileEditorInput(fFile
));
224 fEventsTable
.dispose();
225 if (fTrace
!= null) {
226 fEventsTable
= createEventsTable(fParent
, fTrace
.getCacheSize());
227 fEventsTable
.setTrace(fTrace
, true);
228 fEventsTable
.refreshBookmarks(fFile
);
229 broadcast(new TmfTraceOpenedSignal(this, fTrace
, fFile
, fEventsTable
));
231 fEventsTable
= new TmfEventsTable(fParent
, 0);
237 public void createPartControl(final Composite parent
) {
239 if (fTrace
!= null) {
240 setPartName(fTrace
.getName());
241 fEventsTable
= createEventsTable(parent
, fTrace
.getCacheSize());
242 fEventsTable
.setTrace(fTrace
, true);
243 fEventsTable
.refreshBookmarks(fFile
);
244 broadcast(new TmfTraceOpenedSignal(this, fTrace
, fFile
, fEventsTable
));
246 setPartName(getEditorInput().getName());
247 fEventsTable
= new TmfEventsTable(parent
, 0);
249 addPropertyListener(this);
250 ResourcesPlugin
.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent
.POST_CHANGE
);
254 public void dispose() {
255 ResourcesPlugin
.getWorkspace().removeResourceChangeListener(this);
256 removePropertyListener(this);
258 broadcast(new TmfTraceClosedSignal(this, fTrace
));
259 if (fEventsTable
!= null)
260 fEventsTable
.dispose();
264 protected TmfEventsTable
createEventsTable(final Composite parent
, final int cacheSize
) {
265 TmfEventsTable eventsTable
= getEventsTable(parent
, cacheSize
);
266 if (eventsTable
== null)
267 eventsTable
= new TmfEventsTable(parent
, cacheSize
);
271 private TmfEventsTable
getEventsTable(final Composite parent
, final int cacheSize
) {
272 if (fTrace
instanceof TmfExperiment
)
273 return getExperimentEventsTable((TmfExperiment
<?
>) fTrace
, parent
, cacheSize
);
274 TmfEventsTable eventsTable
= null;
276 if (fTrace
.getResource() == null)
278 final String traceType
= fTrace
.getResource().getPersistentProperty(TmfCommonConstants
.TRACETYPE
);
279 if (traceType
== null)
281 if (traceType
.startsWith(CustomTxtTrace
.class.getCanonicalName()))
282 return new CustomEventsTable(((CustomTxtTrace
) fTrace
).getDefinition(), parent
, cacheSize
);
283 if (traceType
.startsWith(CustomXmlTrace
.class.getCanonicalName()))
284 return new CustomEventsTable(((CustomXmlTrace
) fTrace
).getDefinition(), parent
, cacheSize
);
285 for (final IConfigurationElement ce
: TmfTraceType
.getTypeElements())
286 if (ce
.getAttribute(TmfTraceType
.ID_ATTR
).equals(traceType
)) {
287 final IConfigurationElement
[] eventsTableTypeCE
= ce
.getChildren(TmfTraceType
.EVENTS_TABLE_TYPE_ELEM
);
288 if (eventsTableTypeCE
.length
!= 1)
290 final String eventsTableType
= eventsTableTypeCE
[0].getAttribute(TmfTraceType
.CLASS_ATTR
);
291 if ((eventsTableType
== null) || (eventsTableType
.length() == 0))
293 final Bundle bundle
= Platform
.getBundle(ce
.getContributor().getName());
294 final Class
<?
> c
= bundle
.loadClass(eventsTableType
);
295 final Class
<?
>[] constructorArgs
= new Class
[] { Composite
.class, int.class };
296 final Constructor
<?
> constructor
= c
.getConstructor(constructorArgs
);
297 final Object
[] args
= new Object
[] { parent
, cacheSize
};
298 eventsTable
= (TmfEventsTable
) constructor
.newInstance(args
);
301 } catch (final InvalidRegistryObjectException e
) {
303 } catch (final CoreException e
) {
305 } catch (final ClassNotFoundException e
) {
307 } catch (final SecurityException e
) {
309 } catch (final NoSuchMethodException e
) {
311 } catch (final IllegalArgumentException e
) {
313 } catch (final InstantiationException e
) {
315 } catch (final IllegalAccessException e
) {
317 } catch (final InvocationTargetException e
) {
324 * Get the events table for an experiment.
325 * If all traces in the experiment are of the same type,
326 * use the extension point specified event table
327 * @param experiment the experiment
328 * @param parent the parent Composite
329 * @param cacheSize the event table cache size
330 * @return an events table of the appropriate type
332 private TmfEventsTable
getExperimentEventsTable(final TmfExperiment
<?
> experiment
, final Composite parent
, final int cacheSize
) {
333 TmfEventsTable eventsTable
= null;
334 String commonTraceType
= null;
336 for (final ITmfTrace
<?
> trace
: experiment
.getTraces()) {
337 final IResource resource
= trace
.getResource();
338 if (resource
== null)
340 final String traceType
= resource
.getPersistentProperty(TmfCommonConstants
.TRACETYPE
);
341 if ((commonTraceType
!= null) && !commonTraceType
.equals(traceType
))
343 commonTraceType
= traceType
;
345 if (commonTraceType
== null)
347 if (commonTraceType
.startsWith(CustomTxtTrace
.class.getCanonicalName()))
348 return new CustomEventsTable(((CustomTxtTrace
) experiment
.getTraces()[0]).getDefinition(), parent
, cacheSize
);
349 if (commonTraceType
.startsWith(CustomXmlTrace
.class.getCanonicalName()))
350 return new CustomEventsTable(((CustomXmlTrace
) experiment
.getTraces()[0]).getDefinition(), parent
, cacheSize
);
351 for (final IConfigurationElement ce
: TmfTraceType
.getTypeElements())
352 if (ce
.getAttribute(TmfTraceType
.ID_ATTR
).equals(commonTraceType
)) {
353 final IConfigurationElement
[] eventsTableTypeCE
= ce
.getChildren(TmfTraceType
.EVENTS_TABLE_TYPE_ELEM
);
354 if (eventsTableTypeCE
.length
!= 1)
356 final String eventsTableType
= eventsTableTypeCE
[0].getAttribute(TmfTraceType
.CLASS_ATTR
);
357 if ((eventsTableType
== null) || (eventsTableType
.length() == 0))
359 final Bundle bundle
= Platform
.getBundle(ce
.getContributor().getName());
360 final Class
<?
> c
= bundle
.loadClass(eventsTableType
);
361 final Class
<?
>[] constructorArgs
= new Class
[] { Composite
.class, int.class };
362 final Constructor
<?
> constructor
= c
.getConstructor(constructorArgs
);
363 final Object
[] args
= new Object
[] { parent
, cacheSize
};
364 eventsTable
= (TmfEventsTable
) constructor
.newInstance(args
);
367 } catch (final CoreException e
) {
369 } catch (final InvalidRegistryObjectException e
) {
371 } catch (final SecurityException e
) {
373 } catch (final IllegalArgumentException e
) {
375 } catch (final ClassNotFoundException e
) {
377 } catch (final NoSuchMethodException e
) {
379 } catch (final InstantiationException e
) {
381 } catch (final IllegalAccessException e
) {
383 } catch (final InvocationTargetException e
) {
390 public ITmfTrace
<?
> getTrace() {
395 public IFile
getBookmarksFile() {
400 public void setFocus() {
401 fEventsTable
.setFocus();
403 broadcast(new TmfTraceSelectedSignal(this, fTrace
));
407 @SuppressWarnings("rawtypes")
408 public Object
getAdapter(final Class adapter
) {
409 if (IGotoMarker
.class.equals(adapter
))
411 return super.getAdapter(adapter
);
415 public void resourceChanged(final IResourceChangeEvent event
) {
416 for (final IMarkerDelta delta
: event
.findMarkerDeltas(IMarker
.BOOKMARK
, false))
417 if (delta
.getResource().equals(fFile
))
418 if (delta
.getKind() == IResourceDelta
.REMOVED
) {
419 final IMarker bookmark
= delta
.getMarker();
420 Display
.getDefault().asyncExec(new Runnable() {
423 fEventsTable
.removeBookmark(bookmark
);
426 } else if (delta
.getKind() == IResourceDelta
.CHANGED
)
427 Display
.getDefault().asyncExec(new Runnable() {
430 fEventsTable
.getTable().refresh();
435 // ------------------------------------------------------------------------
437 // ------------------------------------------------------------------------
439 public void addBookmark() {
440 fEventsTable
.addBookmark(fFile
);
444 // ------------------------------------------------------------------------
446 // ------------------------------------------------------------------------
448 @SuppressWarnings("unchecked")
450 public void traceParserUpdated(final TmfTraceParserUpdatedSignal signal
) {
451 if (signal
.getTraceResource().equals(fFile
)) {
452 broadcast(new TmfTraceClosedSignal(this, fTrace
));
456 final String traceTypeId
= fFile
.getPersistentProperty(TmfCommonConstants
.TRACETYPE
);
457 if (traceTypeId
!= null)
458 for (final IConfigurationElement ce
: TmfTraceType
.getTypeElements())
459 if (traceTypeId
.equals(ce
.getAttribute(TmfTraceType
.ID_ATTR
))) {
460 fTrace
= (ITmfTrace
<?
>) ce
.createExecutableExtension(TmfTraceType
.TRACE_TYPE_ATTR
);
461 final ITmfEvent event
= (TmfEvent
) ce
.createExecutableExtension(TmfTraceType
.EVENT_TYPE_ATTR
);
462 final String path
= fFile
.getLocationURI().getPath();
463 fTrace
.initTrace(null, path
, event
.getClass());
466 } catch (final InvalidRegistryObjectException e
) {
468 } catch (final TmfTraceException e
) {
470 } catch (final CoreException e
) {
473 fEventsTable
.dispose();
474 if (fTrace
!= null) {
475 fEventsTable
= createEventsTable(fParent
, fTrace
.getCacheSize());
476 fEventsTable
.setTrace(fTrace
, true);
477 broadcast(new TmfTraceOpenedSignal(this, fTrace
, fFile
, fEventsTable
));
479 fEventsTable
= new TmfEventsTable(fParent
, 0);
485 public void traceSelected(final TmfTraceSelectedSignal signal
) {
486 if ((signal
.getSource() != this) && signal
.getTrace().equals(fTrace
))
487 getSite().getPage().bringToTop(this);