scripting.core: allow an analysis to complete without a state system.

Change-Id: I828597467f31656562dc22c668e53092c61279e9
Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net>
Reviewed-on: https://git.eclipse.org/r/153658
Tested-by: CI Bot
diff --git a/analyses/org.eclipse.tracecompass.incubator.scripting.core/src/org/eclipse/tracecompass/incubator/internal/scripting/core/data/provider/ScriptedTimeGraphDataProvider.java b/analyses/org.eclipse.tracecompass.incubator.scripting.core/src/org/eclipse/tracecompass/incubator/internal/scripting/core/data/provider/ScriptedTimeGraphDataProvider.java
index 544005b..307e378 100644
--- a/analyses/org.eclipse.tracecompass.incubator.scripting.core/src/org/eclipse/tracecompass/incubator/internal/scripting/core/data/provider/ScriptedTimeGraphDataProvider.java
+++ b/analyses/org.eclipse.tracecompass.incubator.scripting.core/src/org/eclipse/tracecompass/incubator/internal/scripting/core/data/provider/ScriptedTimeGraphDataProvider.java
@@ -73,6 +73,7 @@
     private final Function<Map<String, Object>, @Nullable List<ITimeGraphEntryModel>> fEntryMethod;
     private final @Nullable Function<Map<String, Object>, @Nullable List<ITimeGraphArrow>> fArrowMethod;
     private final @Nullable Function<Map<String, Object>, @Nullable List<ITimeGraphRowModel>> fRowModelMethod;
+    private final ScriptedAnalysis fAnalysis;
 
     /**
      * Constructor
@@ -91,6 +92,7 @@
             @Nullable Function<Map<String, Object>, @Nullable List<ITimeGraphRowModel>> rowModelMethod,
             @Nullable Function<Map<String, Object>, @Nullable List<ITimeGraphArrow>> arrowMethod) {
         super(analysis.getTrace());
+        fAnalysis = analysis;
         fSs = Objects.requireNonNull(analysis.getStateSystem(true));
         fEntryMethod = entryMethod;
         fRowModelMethod = rowModelMethod;
@@ -100,7 +102,7 @@
 
     @Override
     public TmfModelResponse<TmfTreeModel<ITimeGraphEntryModel>> fetchTree(Map<String, Object> fetchParameters, @Nullable IProgressMonitor monitor) {
-        boolean isComplete = fSs.waitUntilBuilt(0);
+        boolean isComplete = fAnalysis.isComplete();
 
         List<ITimeGraphEntryModel> entryList = fEntryMethod.apply(fetchParameters);
         if (entryList == null) {
diff --git a/analyses/org.eclipse.tracecompass.incubator.scripting.core/src/org/eclipse/tracecompass/incubator/scripting/core/analysis/ScriptedAnalysis.java b/analyses/org.eclipse.tracecompass.incubator.scripting.core/src/org/eclipse/tracecompass/incubator/scripting/core/analysis/ScriptedAnalysis.java
index 1f1b07b..b07be39 100644
--- a/analyses/org.eclipse.tracecompass.incubator.scripting.core/src/org/eclipse/tracecompass/incubator/scripting/core/analysis/ScriptedAnalysis.java
+++ b/analyses/org.eclipse.tracecompass.incubator.scripting.core/src/org/eclipse/tracecompass/incubator/scripting/core/analysis/ScriptedAnalysis.java
@@ -32,6 +32,7 @@
 
     private final ITmfTrace fTrace;
     private final String fName;
+    private @Nullable ITmfStateSystemBuilder fStateSystem;
 
     /**
      * Constructor
@@ -62,12 +63,17 @@
     @WrapToScript
     public @Nullable ITmfStateSystemBuilder getStateSystem(@ScriptParameter(defaultValue = "false") boolean useExisting) {
 
+        ITmfStateSystemBuilder stateSystem = fStateSystem;
+        if (stateSystem != null) {
+            return stateSystem;
+        }
         TmfScriptAnalysis analysisModule = TmfTraceUtils.getAnalysisModuleOfClass(fTrace, TmfScriptAnalysis.class, TmfScriptAnalysis.ID);
         if (analysisModule == null) {
             return null;
         }
-
-        return (ITmfStateSystemBuilder) analysisModule.getStateSystem(fName, useExisting);
+        stateSystem = (ITmfStateSystemBuilder) analysisModule.getStateSystem(fName, useExisting);
+        fStateSystem = stateSystem;
+        return stateSystem;
 
     }
 
@@ -116,4 +122,35 @@
     public String getName() {
         return fName;
     }
+
+    /**
+     * Make sure the analysis is complete and the state system, if any, is
+     * closed. It will close the state system at the end time of the trace if is
+     * has not been closed previously. If no state system was requested through
+     * the {@link #getStateSystem(boolean)} before hand, nothing will happen.
+     */
+    public void complete() {
+        ITmfStateSystemBuilder stateSystem = fStateSystem;
+        if (stateSystem == null) {
+            return;
+        }
+        if (!stateSystem.waitUntilBuilt(0)) {
+            stateSystem.closeHistory(getTrace().getEndTime().toNanos());
+        }
+    }
+
+    /**
+     * Get whether this analysis is complete, ie, if a state systemw as
+     * requested by the {@link #getStateSystem(boolean)} method, then the state
+     * system has been closed.
+     *
+     * @return Whether the analysis is complete and the state system was closed
+     */
+    public boolean isComplete() {
+        ITmfStateSystemBuilder stateSystem = fStateSystem;
+        if (stateSystem == null) {
+            return true;
+        }
+        return stateSystem.waitUntilBuilt(0);
+    }
 }