tmf: Split the state system in a separate plugin
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / views / callstack / CallStackView.java
index 903aae72497c0d42b50fae2a826cce7ad74ba381..1c7cc98ee477dbd3a4c8f2c661d9c019c12b6fed 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2013 Ericsson
+ * Copyright (c) 2013, 2014 Ericsson
  *
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
@@ -25,6 +25,7 @@ import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.jface.action.Action;
 import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.action.IStatusLineManager;
@@ -43,28 +44,28 @@ import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.linuxtools.internal.tmf.ui.Activator;
 import org.eclipse.linuxtools.internal.tmf.ui.ITmfImageConstants;
 import org.eclipse.linuxtools.internal.tmf.ui.Messages;
+import org.eclipse.linuxtools.statesystem.core.ITmfStateSystem;
+import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException;
+import org.eclipse.linuxtools.statesystem.core.exceptions.StateSystemDisposedException;
+import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException;
+import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException;
+import org.eclipse.linuxtools.statesystem.core.interval.ITmfStateInterval;
+import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue;
+import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type;
 import org.eclipse.linuxtools.tmf.core.callstack.CallStackStateProvider;
-import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
-import org.eclipse.linuxtools.tmf.core.exceptions.StateSystemDisposedException;
-import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
-import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
-import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;
 import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;
 import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
 import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;
 import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal;
 import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
 import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal;
-import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
-import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
-import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue.Type;
 import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
 import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp;
 import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
 import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
 import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampDelta;
 import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
-import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment;
+import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager;
 import org.eclipse.linuxtools.tmf.ui.editors.ITmfTraceEditor;
 import org.eclipse.linuxtools.tmf.ui.views.TmfView;
 import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphRangeListener;
@@ -147,16 +148,16 @@ public class CallStackView extends TmfView {
     private ITmfTrace fTrace;
 
     // The selected thread map
-    private final Map<ITmfTrace, String> fSelectedThreadMap = new HashMap<ITmfTrace, String>();
+    private final Map<ITmfTrace, String> fSelectedThreadMap = new HashMap<>();
 
     // The time graph entry list
     private List<ThreadEntry> fEntryList;
 
     // The trace to entry list hash map
-    private final Map<ITmfTrace, ArrayList<ThreadEntry>> fEntryListMap = new HashMap<ITmfTrace, ArrayList<ThreadEntry>>();
+    private final Map<ITmfTrace, ArrayList<ThreadEntry>> fEntryListMap = new HashMap<>();
 
     // The trace to build thread hash map
-    private final Map<ITmfTrace, BuildThread> fBuildThreadMap = new HashMap<ITmfTrace, BuildThread>();
+    private final Map<ITmfTrace, BuildThread> fBuildThreadMap = new HashMap<>();
 
     /** The map to map function addresses to function names */
     private Map<String, String> fNameMapping;
@@ -205,8 +206,6 @@ public class CallStackView extends TmfView {
     // ------------------------------------------------------------------------
 
     private class ThreadEntry implements ITimeGraphEntry {
-        // The Trace
-        private final ITmfTrace fThreadTrace;
         // The start time
         private final long fTraceStartTime;
         // The end time
@@ -217,14 +216,17 @@ public class CallStackView extends TmfView {
         private final String fName;
         // The thread attribute quark
         private final int fThreadQuark;
+        // The state system from which this entry comes
+        private final ITmfStateSystem fSS;
 
         public ThreadEntry(ITmfTrace trace, String name, int threadQuark, long startTime, long endTime) {
-            fThreadTrace = trace;
-            fChildren = new ArrayList<CallStackEntry>();
+            fChildren = new ArrayList<>();
             fName = name;
             fTraceStartTime = startTime;
             fTraceEndTime = endTime;
             fThreadQuark = threadQuark;
+
+            fSS = getCallStackStateSystem(trace);
         }
 
         @Override
@@ -235,7 +237,10 @@ public class CallStackView extends TmfView {
         @Override
         public boolean hasChildren() {
             if (fChildren == null) {
-                ITmfStateSystem ss = fThreadTrace.getStateSystems().get(CallStackStateProvider.ID);
+                ITmfStateSystem ss = getStateSystem();
+                if (ss == null) {
+                    return false;
+                }
                 try {
                     int eventStackQuark = ss.getQuarkRelative(fThreadQuark, CallStackStateProvider.CALL_STACK);
                     ITmfStateInterval eventStackInterval = ss.querySingleState(ss.getStartTime(), eventStackQuark);
@@ -290,8 +295,9 @@ public class CallStackView extends TmfView {
             return fThreadQuark;
         }
 
-        public ITmfTrace getTrace() {
-            return fThreadTrace;
+        @Nullable
+        public ITmfStateSystem getStateSystem() {
+            return fSS;
         }
 
         public void addChild(CallStackEntry entry) {
@@ -442,8 +448,12 @@ public class CallStackView extends TmfView {
             }
             long resolution = Math.max(1, (fZoomEndTime - fZoomStartTime) / fDisplayWidth);
             for (ThreadEntry threadEntry : fZoomEntryList) {
-                ITmfStateSystem ss = threadEntry.fThreadTrace.getStateSystems().get(CallStackStateProvider.ID);
-                if (ss == null || !ss.waitUntilBuilt()) {
+                ITmfStateSystem ss = threadEntry.getStateSystem();
+                if (ss == null) {
+                    continue;
+                }
+                ss.waitUntilBuilt();
+                if (ss.isCancelled()) {
                     continue;
                 }
                 for (ITimeGraphEntry child : threadEntry.getChildren()) {
@@ -689,7 +699,7 @@ public class CallStackView extends TmfView {
                 }
                 TimeGraphViewer viewer = fTimeGraphCombo.getTimeGraphViewer();
                 for (ThreadEntry threadEntry : fEntryList) {
-                    ITmfStateSystem ss = threadEntry.getTrace().getStateSystems().get(CallStackStateProvider.ID);
+                    ITmfStateSystem ss = threadEntry.getStateSystem();
                     if (ss == null || beginTime < ss.getStartTime() || beginTime > ss.getCurrentEndTime()) {
                         continue;
                     }
@@ -777,23 +787,20 @@ public class CallStackView extends TmfView {
     private void buildThreadList(final ITmfTrace trace, IProgressMonitor monitor) {
         fStartTime = Long.MAX_VALUE;
         fEndTime = Long.MIN_VALUE;
-        ITmfTrace[] traces;
-        if (trace instanceof TmfExperiment) {
-            TmfExperiment experiment = (TmfExperiment) trace;
-            traces = experiment.getTraces();
-        } else {
-            traces = new ITmfTrace[] { trace };
-        }
-        ArrayList<ThreadEntry> entryList = new ArrayList<ThreadEntry>();
+        ITmfTrace[] traces = TmfTraceManager.getTraceSet(trace);
+        ArrayList<ThreadEntry> entryList = new ArrayList<>();
         for (ITmfTrace aTrace : traces) {
             if (monitor.isCanceled()) {
                 return;
             }
-            ITmfStateSystem ss = aTrace.getStateSystems().get(CallStackStateProvider.ID);
-            if (ss == null || !ss.waitUntilBuilt()) {
-                String threadName = Messages.CallStackView_StackInfoNotAvailable + ' ' + '(' + aTrace.getName() + ')';
-                ThreadEntry threadEntry = new ThreadEntry(aTrace, threadName, -1, 0, 0);
-                entryList.add(threadEntry);
+            ITmfStateSystem ss = getCallStackStateSystem(aTrace);
+            if (ss == null) {
+                addUnavailableEntry(aTrace, entryList);
+                continue;
+            }
+            ss.waitUntilBuilt();
+            if (ss.isCancelled()) {
+                addUnavailableEntry(aTrace, entryList);
                 continue;
             }
             long startTime = ss.getStartTime();
@@ -824,7 +831,7 @@ public class CallStackView extends TmfView {
             }
         }
         synchronized (fEntryListMap) {
-            fEntryListMap.put(trace, new ArrayList<ThreadEntry>(entryList));
+            fEntryListMap.put(trace, new ArrayList<>(entryList));
         }
         if (trace == fTrace) {
             refresh();
@@ -839,8 +846,17 @@ public class CallStackView extends TmfView {
         }
     }
 
+    private void addUnavailableEntry(ITmfTrace trace, List<ThreadEntry> list) {
+        String threadName = Messages.CallStackView_StackInfoNotAvailable + ' ' + '(' + trace.getName() + ')';
+        ThreadEntry threadEntry = new ThreadEntry(trace, threadName, -1, 0, 0);
+        list.add(threadEntry);
+    }
+
     private void buildStatusEvents(ITmfTrace trace, CallStackEntry entry, IProgressMonitor monitor) {
-        ITmfStateSystem ss = entry.getTrace().getStateSystems().get(CallStackStateProvider.ID);
+        ITmfStateSystem ss = getCallStackStateSystem(entry.getTrace());
+        if (ss == null) {
+            return;
+        }
         long start = ss.getStartTime();
         long end = ss.getCurrentEndTime() + 1;
         long resolution = Math.max(1, (end - start) / fDisplayWidth);
@@ -857,7 +873,10 @@ public class CallStackView extends TmfView {
     private static List<ITimeEvent> getEventList(CallStackEntry entry,
             long startTime, long endTime, long resolution,
             IProgressMonitor monitor) {
-        ITmfStateSystem ss = entry.getTrace().getStateSystems().get(CallStackStateProvider.ID);
+        ITmfStateSystem ss = getCallStackStateSystem(entry.getTrace());
+        if (ss == null) {
+            return null;
+        }
         long start = Math.max(startTime, ss.getStartTime());
         long end = Math.min(endTime, ss.getCurrentEndTime() + 1);
         if (end <= start) {
@@ -866,7 +885,7 @@ public class CallStackView extends TmfView {
         List<ITimeEvent> eventList = null;
         try {
             List<ITmfStateInterval> stackIntervals = ss.queryHistoryRange(entry.getQuark(), start, end - 1, resolution, monitor);
-            eventList = new ArrayList<ITimeEvent>(stackIntervals.size());
+            eventList = new ArrayList<>(stackIntervals.size());
             long lastEndTime = -1;
             boolean lastIsNull = true;
             for (ITmfStateInterval statusInterval : stackIntervals) {
@@ -913,8 +932,12 @@ public class CallStackView extends TmfView {
             return;
         }
         for (ThreadEntry threadEntry : fEntryList) {
-            ITmfStateSystem ss = threadEntry.fThreadTrace.getStateSystems().get(CallStackStateProvider.ID);
-            if (ss == null || !ss.waitUntilBuilt()) {
+            ITmfStateSystem ss = threadEntry.getStateSystem();
+            if (ss == null) {
+                continue;
+            }
+            ss.waitUntilBuilt();
+            if (ss.isCancelled()) {
                 continue;
             }
             long queryTime = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), time));
@@ -962,7 +985,7 @@ public class CallStackView extends TmfView {
                 synchronized (fEntryListMap) {
                     fEntryList = fEntryListMap.get(fTrace);
                     if (fEntryList == null) {
-                        fEntryList = new ArrayList<ThreadEntry>();
+                        fEntryList = new ArrayList<>();
                     }
                     entries = fEntryList.toArray(new ITimeGraphEntry[0]);
                 }
@@ -1081,7 +1104,10 @@ public class CallStackView extends TmfView {
                         try {
                             CallStackEntry callStackEntry = (CallStackEntry) entry;
                             ITmfTrace trace = callStackEntry.getTrace();
-                            ITmfStateSystem ss = trace.getStateSystems().get(CallStackStateProvider.ID);
+                            ITmfStateSystem ss = getCallStackStateSystem(trace);
+                            if (ss == null) {
+                                return;
+                            }
                             long time = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), viewer.getSelectionBegin()));
                             ThreadEntry threadEntry = (ThreadEntry) callStackEntry.getParent();
                             int quark = ss.getQuarkRelative(threadEntry.getThreadQuark(), CallStackStateProvider.CALL_STACK);
@@ -1094,6 +1120,7 @@ public class CallStackView extends TmfView {
                             fTimeGraphCombo.setSelection(selectedEntry);
                             viewer.getTimeGraphControl().fireSelectionChanged();
                             startZoomThread(viewer.getTime0(), viewer.getTime1());
+
                         } catch (AttributeNotFoundException e) {
                             Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
                         } catch (TimeRangeException e) {
@@ -1131,7 +1158,10 @@ public class CallStackView extends TmfView {
                         try {
                             CallStackEntry callStackEntry = (CallStackEntry) entry;
                             ITmfTrace trace = callStackEntry.getTrace();
-                            ITmfStateSystem ss = trace.getStateSystems().get(CallStackStateProvider.ID);
+                            ITmfStateSystem ss = getCallStackStateSystem(trace);
+                            if (ss == null) {
+                                return;
+                            }
                             long time = Math.max(ss.getStartTime(), Math.min(ss.getCurrentEndTime(), viewer.getSelectionBegin()));
                             ThreadEntry threadEntry = (ThreadEntry) callStackEntry.getParent();
                             int quark = ss.getQuarkRelative(threadEntry.getThreadQuark(), CallStackStateProvider.CALL_STACK);
@@ -1145,6 +1175,7 @@ public class CallStackView extends TmfView {
                             fTimeGraphCombo.setSelection(selectedEntry);
                             viewer.getTimeGraphControl().fireSelectionChanged();
                             startZoomThread(viewer.getTime0(), viewer.getTime1());
+
                         } catch (AttributeNotFoundException e) {
                             Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
                         } catch (TimeRangeException e) {
@@ -1166,6 +1197,38 @@ public class CallStackView extends TmfView {
         return fPrevEventAction;
     }
 
+    @Nullable
+    static ITmfStateSystem getCallStackStateSystem(ITmfTrace trace) {
+        /*
+         * Since we cannot know the exact analysis ID (in separate plugins), we
+         * will search using the analysis type.
+         */
+        Iterable<AbstractCallStackAnalysis> modules =
+                trace.getAnalysisModulesOfClass(AbstractCallStackAnalysis.class);
+        Iterator<AbstractCallStackAnalysis> it = modules.iterator();
+        if (!it.hasNext()) {
+            /* This trace does not provide a call-stack analysis */
+            return null;
+        }
+
+        /*
+         * We only look at the first module we find.
+         *
+         * TODO Handle the advanced case where one trace provides more than one
+         * call-stack analysis.
+         */
+        AbstractCallStackAnalysis module = it.next();
+        /* This analysis is not automatic, we need to schedule it on-demand */
+        module.schedule();
+        module.waitForInitialization();
+        ITmfStateSystem ss = module.getStateSystem();
+        if (ss == null) {
+            /* If we've waited for initialization, 'ss' should not be null */
+            throw new IllegalStateException();
+        }
+        return ss;
+    }
+
     // ------------------------------------------------------------------------
     // Methods related to function name mapping
     // ------------------------------------------------------------------------
This page took 0.044397 seconds and 5 git commands to generate.