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
.internal
.tmf
.ui
.parsers
.custom
.CustomEventsTable
;
34 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomTxtTrace
;
35 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.parsers
.custom
.CustomXmlTrace
;
36 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.project
.handlers
.Messages
;
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
.experiment
.TmfExperiment
;
40 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignalHandler
;
41 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceSelectedSignal
;
42 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
43 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfTrace
;
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
.project
.model
.TmfTraceType
;
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
.eclipse
.ui
.part
.FileEditorInput
;
66 import org
.osgi
.framework
.Bundle
;
69 * <b><u>TmfEventsEditor</u></b>
71 public class TmfEventsEditor
extends TmfEditor
implements ITmfTraceEditor
, IReusableEditor
, IPropertyListener
, IResourceChangeListener
{
73 public static final String ID
= "org.eclipse.linuxtools.tmf.ui.editors.events"; //$NON-NLS-1$
75 private TmfEventsTable fEventsTable
;
77 @SuppressWarnings("rawtypes")
78 private ITmfTrace fTrace
;
79 private Composite fParent
;
82 public void doSave(IProgressMonitor monitor
) {
86 public void doSaveAs() {
89 @SuppressWarnings({ "unchecked", "rawtypes" })
91 public void init(IEditorSite site
, IEditorInput input
) throws PartInitException
{
92 if (input
instanceof TmfEditorInput
) {
93 fFile
= ((TmfEditorInput
) input
).getFile();
94 fTrace
= ((TmfEditorInput
) input
).getTrace();
95 input
= new FileEditorInput(fFile
);
96 } else if (input
instanceof IFileEditorInput
) {
97 fFile
= ((IFileEditorInput
) input
).getFile();
99 throw new PartInitException("Invalid IFileEditorInput: " + input
); //$NON-NLS-1$
102 String traceTypeId
= fFile
.getPersistentProperty(TmfTraceElement
.TRACETYPE
);
103 if (traceTypeId
== null) {
104 throw new PartInitException(Messages
.OpenTraceHandler_NoTraceType
);
106 if (traceTypeId
.equals(TmfExperiment
.class.getCanonicalName())) {
107 // Special case: experiment bookmark resource
108 TmfNavigatorContentProvider ncp
= new TmfNavigatorContentProvider();
109 ncp
.getChildren(fFile
.getProject()); // force the model to be populated
110 TmfProjectElement project
= TmfProjectRegistry
.getProject(fFile
.getProject());
111 if (project
== null) {
112 throw new PartInitException(Messages
.OpenExperimentHandler_NoTraceType
);
114 for (ITmfProjectModelElement projectElement
: project
.getExperimentsFolder().getChildren()) {
115 String traceName
= fFile
.getParent().getName();
116 if (projectElement
.getName().equals(traceName
)) {
117 TmfExperimentElement experimentElement
= (TmfExperimentElement
) projectElement
;
118 // Instantiate the experiment's traces
119 List
<TmfTraceElement
> traceEntries
= experimentElement
.getTraces();
120 int nbTraces
= traceEntries
.size();
121 int cacheSize
= Integer
.MAX_VALUE
;
122 ITmfTrace
<?
>[] traces
= new ITmfTrace
[nbTraces
];
123 for (int i
= 0; i
< nbTraces
; i
++) {
124 TmfTraceElement traceElement
= traceEntries
.get(i
);
125 ITmfTrace trace
= traceElement
.instantiateTrace();
126 ITmfEvent traceEvent
= traceElement
.instantiateEvent();
127 if ((trace
== null) || (traceEvent
== null)) {
128 for (int j
= 0; j
< i
; j
++) {
131 throw new PartInitException(Messages
.OpenExperimentHandler_NoTraceType
);
134 trace
.initTrace(traceElement
.getName(), traceElement
.getLocation().getPath(), traceEvent
.getClass());
135 } catch (FileNotFoundException e
) {
137 trace
.setResource(traceElement
.getResource());
138 cacheSize
= Math
.min(cacheSize
, trace
.getIndexPageSize());
141 TmfExperiment experiment
= new TmfExperiment(TmfEvent
.class, experimentElement
.getName(), traces
, cacheSize
);
142 experiment
.setBookmarksFile(fFile
);
144 experiment
.initTrace(null, null, null);
145 experiment
.indexTrace(true);
149 } else if (traceTypeId
.equals(TmfTrace
.class.getCanonicalName())) {
150 // Special case: trace bookmark resource
151 TmfNavigatorContentProvider ncp
= new TmfNavigatorContentProvider();
152 ncp
.getChildren(fFile
.getProject()); // force the model to be populated
153 TmfProjectElement project
= TmfProjectRegistry
.getProject(fFile
.getProject());
154 for (ITmfProjectModelElement projectElement
: project
.getTracesFolder().getChildren()) {
155 String traceName
= fFile
.getParent().getName();
156 if (projectElement
.getName().equals(traceName
)) {
157 TmfTraceElement traceElement
= (TmfTraceElement
) projectElement
;
158 // Instantiate the trace
159 ITmfTrace trace
= traceElement
.instantiateTrace();
160 ITmfEvent traceEvent
= traceElement
.instantiateEvent();
161 if ((trace
== null) || (traceEvent
== null)) {
162 throw new PartInitException(Messages
.OpenTraceHandler_NoTraceType
);
165 trace
.initTrace(traceElement
.getName(), traceElement
.getLocation().getPath(), traceEvent
.getClass());
166 trace
.indexTrace(false);
167 } catch (FileNotFoundException e
) {
169 trace
.setResource(traceElement
.getResource());
175 TmfNavigatorContentProvider ncp
= new TmfNavigatorContentProvider();
176 ncp
.getChildren(fFile
.getProject()); // force the model to be populated
177 TmfProjectElement project
= TmfProjectRegistry
.getProject(fFile
.getProject());
178 for (ITmfProjectModelElement projectElement
: project
.getTracesFolder().getChildren()) {
179 if (projectElement
.getResource().equals(fFile
)) {
180 TmfTraceElement traceElement
= (TmfTraceElement
) projectElement
;
181 // Instantiate the trace
182 ITmfTrace trace
= traceElement
.instantiateTrace();
183 ITmfEvent traceEvent
= traceElement
.instantiateEvent();
184 if ((trace
== null) || (traceEvent
== null)) {
185 throw new PartInitException(Messages
.OpenTraceHandler_NoTraceType
);
188 trace
.initTrace(traceElement
.getName(), traceElement
.getLocation().getPath(), traceEvent
.getClass());
189 trace
.indexTrace(false);
190 } catch (FileNotFoundException e
) {
192 if (trace
instanceof TmfTrace
) {
193 ((TmfTrace
) trace
).setResource(traceElement
.getResource());
200 } catch (InvalidRegistryObjectException e
) {
202 } catch (PartInitException e
) {
204 } catch (CoreException e
) {
208 throw new PartInitException("Invalid IEditorInput: " + input
.getClass()); //$NON-NLS-1$
210 if (fTrace
== null) {
211 throw new PartInitException("Invalid IEditorInput: " + fFile
.getName()); //$NON-NLS-1$
214 super.setInput(input
);
218 public boolean isDirty() {
223 public boolean isSaveAsAllowed() {
228 public void setInput(IEditorInput input
) {
229 super.setInput(input
);
230 firePropertyChange(IEditorPart
.PROP_INPUT
);
234 public void propertyChanged(Object source
, int propId
) {
235 if (propId
== IEditorPart
.PROP_INPUT
) {
236 broadcast(new TmfTraceClosedSignal(this, fTrace
));
237 fFile
= ((TmfEditorInput
) getEditorInput()).getFile();
238 fTrace
= ((TmfEditorInput
) getEditorInput()).getTrace();
239 super.setInput(new FileEditorInput(fFile
));
240 fEventsTable
.dispose();
241 if (fTrace
!= null) {
242 fEventsTable
= createEventsTable(fParent
, fTrace
.getIndexPageSize());
243 fEventsTable
.setTrace(fTrace
, true);
244 fEventsTable
.refreshBookmarks(fFile
);
245 broadcast(new TmfTraceOpenedSignal(this, fTrace
, fFile
, fEventsTable
));
247 fEventsTable
= new TmfEventsTable(fParent
, 0);
254 public void createPartControl(Composite parent
) {
256 if (fTrace
!= null) {
257 setPartName(fTrace
.getName());
258 fEventsTable
= createEventsTable(parent
, fTrace
.getIndexPageSize());
259 fEventsTable
.setTrace(fTrace
, true);
260 fEventsTable
.refreshBookmarks(fFile
);
261 broadcast(new TmfTraceOpenedSignal(this, fTrace
, fFile
, fEventsTable
));
263 setPartName(getEditorInput().getName());
264 fEventsTable
= new TmfEventsTable(parent
, 0);
266 addPropertyListener(this);
267 ResourcesPlugin
.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent
.POST_CHANGE
);
271 public void dispose() {
272 ResourcesPlugin
.getWorkspace().removeResourceChangeListener(this);
273 removePropertyListener(this);
274 if (fTrace
!= null) {
275 broadcast(new TmfTraceClosedSignal(this, fTrace
));
277 if (fEventsTable
!= null) {
278 fEventsTable
.dispose();
283 protected TmfEventsTable
createEventsTable(Composite parent
, int cacheSize
) {
284 TmfEventsTable eventsTable
= getEventsTable(parent
, cacheSize
);
285 if (eventsTable
== null) {
286 eventsTable
= new TmfEventsTable(parent
, cacheSize
);
291 private TmfEventsTable
getEventsTable(Composite parent
, int cacheSize
) {
292 if (fTrace
instanceof TmfExperiment
) {
293 return getExperimentEventsTable((TmfExperiment
<?
>) fTrace
, parent
, cacheSize
);
295 TmfEventsTable eventsTable
= null;
297 if (fTrace
.getResource() == null) {
300 String traceType
= fTrace
.getResource().getPersistentProperty(TmfTraceElement
.TRACETYPE
);
301 if (traceType
== null) {
304 if (traceType
.startsWith(CustomTxtTrace
.class.getCanonicalName())) {
305 return new CustomEventsTable(((CustomTxtTrace
) fTrace
).getDefinition(), parent
, cacheSize
);
307 if (traceType
.startsWith(CustomXmlTrace
.class.getCanonicalName())) {
308 return new CustomEventsTable(((CustomXmlTrace
) fTrace
).getDefinition(), parent
, cacheSize
);
310 for (IConfigurationElement ce
: TmfTraceType
.getTypeElements()) {
311 if (ce
.getAttribute(TmfTraceType
.ID_ATTR
).equals(traceType
)) {
312 IConfigurationElement
[] eventsTableTypeCE
= ce
.getChildren(TmfTraceType
.EVENTS_TABLE_TYPE_ELEM
);
313 if (eventsTableTypeCE
.length
!= 1) {
316 String eventsTableType
= eventsTableTypeCE
[0].getAttribute(TmfTraceType
.CLASS_ATTR
);
317 if ((eventsTableType
== null) || (eventsTableType
.length() == 0)) {
320 Bundle bundle
= Platform
.getBundle(ce
.getContributor().getName());
321 Class
<?
> c
= bundle
.loadClass(eventsTableType
);
322 Class
<?
>[] constructorArgs
= new Class
[] { Composite
.class, int.class };
323 Constructor
<?
> constructor
= c
.getConstructor(constructorArgs
);
324 Object
[] args
= new Object
[] { parent
, cacheSize
};
325 eventsTable
= (TmfEventsTable
) constructor
.newInstance(args
);
329 } catch (InvalidRegistryObjectException e
) {
331 } catch (CoreException e
) {
333 } catch (ClassNotFoundException e
) {
335 } catch (SecurityException e
) {
337 } catch (NoSuchMethodException e
) {
339 } catch (IllegalArgumentException e
) {
341 } catch (InstantiationException e
) {
343 } catch (IllegalAccessException e
) {
345 } catch (InvocationTargetException e
) {
352 * Get the events table for an experiment.
353 * If all traces in the experiment are of the same type,
354 * use the extension point specified event table
355 * @param experiment the experiment
356 * @param parent the parent Composite
357 * @param cacheSize the event table cache size
358 * @return an events table of the appropriate type
360 private TmfEventsTable
getExperimentEventsTable(TmfExperiment
<?
> experiment
, Composite parent
, int cacheSize
) {
361 TmfEventsTable eventsTable
= null;
362 String commonTraceType
= null;
364 for (ITmfTrace
<?
> trace
: experiment
.getTraces()) {
365 IResource resource
= trace
.getResource();
366 if (resource
== null) {
369 String traceType
= resource
.getPersistentProperty(TmfTraceElement
.TRACETYPE
);
370 if ((commonTraceType
!= null) && !commonTraceType
.equals(traceType
)) {
373 commonTraceType
= traceType
;
375 if (commonTraceType
== null) {
378 if (commonTraceType
.startsWith(CustomTxtTrace
.class.getCanonicalName())) {
379 return new CustomEventsTable(((CustomTxtTrace
) experiment
.getTraces()[0]).getDefinition(), parent
, cacheSize
);
381 if (commonTraceType
.startsWith(CustomXmlTrace
.class.getCanonicalName())) {
382 return new CustomEventsTable(((CustomXmlTrace
) experiment
.getTraces()[0]).getDefinition(), parent
, cacheSize
);
384 for (IConfigurationElement ce
: TmfTraceType
.getTypeElements()) {
385 if (ce
.getAttribute(TmfTraceType
.ID_ATTR
).equals(commonTraceType
)) {
386 IConfigurationElement
[] eventsTableTypeCE
= ce
.getChildren(TmfTraceType
.EVENTS_TABLE_TYPE_ELEM
);
387 if (eventsTableTypeCE
.length
!= 1) {
390 String eventsTableType
= eventsTableTypeCE
[0].getAttribute(TmfTraceType
.CLASS_ATTR
);
391 if ((eventsTableType
== null) || (eventsTableType
.length() == 0)) {
394 Bundle bundle
= Platform
.getBundle(ce
.getContributor().getName());
395 Class
<?
> c
= bundle
.loadClass(eventsTableType
);
396 Class
<?
>[] constructorArgs
= new Class
[] { Composite
.class, int.class };
397 Constructor
<?
> constructor
= c
.getConstructor(constructorArgs
);
398 Object
[] args
= new Object
[] { parent
, cacheSize
};
399 eventsTable
= (TmfEventsTable
) constructor
.newInstance(args
);
403 } catch (CoreException e
) {
405 } catch (InvalidRegistryObjectException e
) {
407 } catch (SecurityException e
) {
409 } catch (IllegalArgumentException e
) {
411 } catch (ClassNotFoundException e
) {
413 } catch (NoSuchMethodException e
) {
415 } catch (InstantiationException e
) {
417 } catch (IllegalAccessException e
) {
419 } catch (InvocationTargetException e
) {
426 public ITmfTrace
<?
> getTrace() {
431 public IFile
getBookmarksFile() {
436 public void setFocus() {
437 fEventsTable
.setFocus();
438 if (fTrace
!= null) {
439 broadcast(new TmfTraceSelectedSignal(this, fTrace
));
444 @SuppressWarnings("rawtypes")
445 public Object
getAdapter(Class adapter
) {
446 if (IGotoMarker
.class.equals(adapter
)) {
449 return super.getAdapter(adapter
);
453 public void resourceChanged(IResourceChangeEvent event
) {
454 for (IMarkerDelta delta
: event
.findMarkerDeltas(IMarker
.BOOKMARK
, false)) {
455 if (delta
.getResource().equals(fFile
)) {
456 if (delta
.getKind() == IResourceDelta
.REMOVED
) {
457 final IMarker bookmark
= delta
.getMarker();
458 Display
.getDefault().asyncExec(new Runnable() {
461 fEventsTable
.removeBookmark(bookmark
);
464 } else if (delta
.getKind() == IResourceDelta
.CHANGED
) {
465 Display
.getDefault().asyncExec(new Runnable() {
468 fEventsTable
.getTable().refresh();
476 // ------------------------------------------------------------------------
478 // ------------------------------------------------------------------------
480 public void addBookmark() {
481 fEventsTable
.addBookmark(fFile
);
485 // ------------------------------------------------------------------------
487 // ------------------------------------------------------------------------
489 @SuppressWarnings("unchecked")
491 public void traceParserUpdated(TmfTraceParserUpdatedSignal signal
) {
492 if (signal
.getTraceResource().equals(fFile
)) {
493 broadcast(new TmfTraceClosedSignal(this, fTrace
));
495 String name
= fTrace
.getName();
497 String traceTypeId
= fFile
.getPersistentProperty(TmfTraceElement
.TRACETYPE
);
498 if (traceTypeId
!= null) {
499 for (IConfigurationElement ce
: TmfTraceType
.getTypeElements()) {
500 if (traceTypeId
.equals(ce
.getAttribute(TmfTraceType
.ID_ATTR
))) {
501 fTrace
= (ITmfTrace
<?
>) ce
.createExecutableExtension(TmfTraceType
.TRACE_TYPE_ATTR
);
502 TmfEvent event
= (TmfEvent
) ce
.createExecutableExtension(TmfTraceType
.EVENT_TYPE_ATTR
);
503 String path
= fFile
.getLocationURI().getPath();
504 fTrace
.initTrace(name
, path
, event
.getClass());
505 fTrace
.indexTrace(false);
510 } catch (InvalidRegistryObjectException e
) {
512 } catch (FileNotFoundException e
) {
514 } catch (CoreException e
) {
517 fEventsTable
.dispose();
518 if (fTrace
!= null) {
519 fEventsTable
= createEventsTable(fParent
, fTrace
.getIndexPageSize());
520 fEventsTable
.setTrace(fTrace
, true);
521 broadcast(new TmfTraceOpenedSignal(this, fTrace
, fFile
, fEventsTable
));
523 fEventsTable
= new TmfEventsTable(fParent
, 0);
530 public void traceSelected(TmfTraceSelectedSignal signal
) {
531 if ((signal
.getSource() != this) && signal
.getTrace().equals(fTrace
)) {
532 getSite().getPage().bringToTop(this);