analysis: Move plugins to their own sub-directory
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / analysis / TmfAbstractAnalysisModule.java
index 0b4f8593fd5b5c293ac0ced80fa488ff6a467835..84972090a1fa9466a9126e899d11a96c0996a84e 100644 (file)
@@ -12,6 +12,8 @@
 
 package org.eclipse.tracecompass.tmf.core.analysis;
 
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -23,11 +25,15 @@ import java.util.concurrent.TimeUnit;
 
 import org.eclipse.core.runtime.IProgressMonitor;
 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.NonNull;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.eclipse.osgi.util.NLS;
+import org.eclipse.tracecompass.common.core.NonNullUtils;
 import org.eclipse.tracecompass.internal.tmf.core.Activator;
+import org.eclipse.tracecompass.internal.tmf.core.TmfCoreTracer;
 import org.eclipse.tracecompass.tmf.core.analysis.TmfAnalysisRequirement.ValuePriorityLevel;
 import org.eclipse.tracecompass.tmf.core.component.TmfComponent;
 import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException;
@@ -43,18 +49,18 @@ import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
  * behavior to some methods of the analysis module
  *
  * @author Geneviève Bastien
- * @since 3.0
  */
+@NonNullByDefault
 public abstract class TmfAbstractAnalysisModule extends TmfComponent implements IAnalysisModule {
 
-    private String fName, fId;
+    private @Nullable String fId;
     private boolean fAutomatic = false, fStarted = false;
-    private volatile ITmfTrace fTrace;
+    private volatile @Nullable ITmfTrace fTrace;
     private final Map<String, Object> fParameters = new HashMap<>();
     private final List<String> fParameterNames = new ArrayList<>();
     private final List<IAnalysisOutput> fOutputs = new ArrayList<>();
     private List<IAnalysisParameterProvider> fParameterProviders = new ArrayList<>();
-    private Job fJob = null;
+    private @Nullable Job fJob = null;
 
     private final Object syncObj = new Object();
 
@@ -70,16 +76,12 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
 
     @Override
     public String getName() {
-        String name = fName;
-        if (name == null) {
-            return ""; //$NON-NLS-1$
-        }
-        return name;
+        return super.getName();
     }
 
     @Override
     public void setName(String name) {
-        fName = name;
+        super.setName(name);
     }
 
     @Override
@@ -88,11 +90,17 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
     }
 
     @Override
-    @NonNull
     public String getId() {
         String id = fId;
         if (id == null) {
-            id = new String(this.getClass().getCanonicalName());
+            id = this.getClass().getCanonicalName();
+            if (id == null) {
+                /*
+                 * Some types, like anonymous classes, don't have a canonical
+                 * name. Just use the default name instead.
+                 */
+                id = checkNotNull(this.getClass().getName());
+            }
             fId = id;
         }
         return id;
@@ -103,28 +111,32 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
         fAutomatic = auto;
     }
 
+    /**
+     * @since 1.0
+     */
     @Override
-    public void setTrace(ITmfTrace trace) throws TmfAnalysisException {
-        if (trace == null) {
-            throw new TmfAnalysisException(Messages.TmfAbstractAnalysisModule_NullTrace);
-        }
+    public boolean setTrace(ITmfTrace trace) throws TmfAnalysisException {
         if (fTrace != null) {
             throw new TmfAnalysisException(NLS.bind(Messages.TmfAbstractAnalysisModule_TraceSetMoreThanOnce, getName()));
         }
 
+        TmfCoreTracer.traceAnalysis(getId(), trace, "setting trace for analysis"); //$NON-NLS-1$
+
         /* Check that analysis can be executed */
         if (!canExecute(trace)) {
-            throw new TmfAnalysisException(NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisCannotExecute, getName()));
+            return false;
         }
 
         fTrace = trace;
         /* Get the parameter providers for this trace */
         fParameterProviders = TmfAnalysisManager.getParameterProviders(this, trace);
         for (IAnalysisParameterProvider provider : fParameterProviders) {
+            TmfCoreTracer.traceAnalysis(getId(), trace, "registered to parameter provider " + provider.getName()); //$NON-NLS-1$
             provider.registerModule(this);
         }
         resetAnalysis();
         fStarted = false;
+        return true;
     }
 
     /**
@@ -132,7 +144,7 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
      *
      * @return The trace
      */
-    protected ITmfTrace getTrace() {
+    protected @Nullable ITmfTrace getTrace() {
         return fTrace;
     }
 
@@ -142,7 +154,7 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
     }
 
     @Override
-    public synchronized void setParameter(String name, Object value) {
+    public synchronized void setParameter(String name, @Nullable Object value) {
         if (!fParameterNames.contains(name)) {
             throw new RuntimeException(NLS.bind(Messages.TmfAbstractAnalysisModule_InvalidParameter, name, getName()));
         }
@@ -176,7 +188,7 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
     }
 
     @Override
-    public Object getParameter(String name) {
+    public @Nullable Object getParameter(String name) {
         Object paramValue = fParameters.get(name);
         /* The parameter is not set, maybe it can be provided by someone else */
         if ((paramValue == null) && (fTrace != null)) {
@@ -191,7 +203,7 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
     }
 
     @Override
-    public boolean canExecute(@NonNull ITmfTrace trace) {
+    public boolean canExecute(ITmfTrace trace) {
         for (TmfAnalysisRequirement requirement : getAnalysisRequirements()) {
             if (!requirement.isFulfilled(trace)) {
                 return false;
@@ -204,6 +216,7 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
      * Set the countdown latch back to 1 so the analysis can be executed again
      */
     protected void resetAnalysis() {
+        TmfCoreTracer.traceAnalysis(getId(), getTrace(), "reset: ready for execution"); //$NON-NLS-1$
         fFinishedLatch.countDown();
         fFinishedLatch = new CountDownLatch(1);
     }
@@ -233,9 +246,11 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
      * It has to be called inside a synchronized block
      */
     private void setAnalysisCompleted() {
-        fStarted = false;
-        fJob = null;
-        fFinishedLatch.countDown();
+        synchronized (syncObj) {
+            fStarted = false;
+            fJob = null;
+            fFinishedLatch.countDown();
+        }
     }
 
     /**
@@ -244,11 +259,10 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
     @Override
     public final void cancel() {
         synchronized (syncObj) {
-            if (fJob != null) {
-                if (fJob.cancel()) {
-                    fAnalysisCancelled = true;
-                    setAnalysisCompleted();
-                }
+            TmfCoreTracer.traceAnalysis(getId(), getTrace(), "cancelled by application"); //$NON-NLS-1$
+            if (fJob != null && fJob.cancel()) {
+                fAnalysisCancelled = true;
+                setAnalysisCompleted();
             }
             fStarted = false;
         }
@@ -260,8 +274,19 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
         cancel();
     }
 
-    private void execute(@NonNull final ITmfTrace trace) {
+    /**
+     * Get an iterable list of all analyzes this analysis depends on. These
+     * analyzes will be scheduled before this analysis starts and the current
+     * analysis will not be considered completed until all the dependent
+     * analyzes are finished.
+     *
+     * @return An iterable list of analysis this analyzes depends on.
+     */
+    protected Iterable<IAnalysisModule> getDependentAnalyses() {
+        return checkNotNull(Collections.EMPTY_LIST);
+    }
 
+    private void execute(final ITmfTrace trace) {
         /*
          * TODO: The analysis in a job should be done at the analysis manager
          * level instead of depending on this abstract class implementation,
@@ -270,32 +295,50 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
 
         /* Do not execute if analysis has already run */
         if (fFinishedLatch.getCount() == 0) {
+            TmfCoreTracer.traceAnalysis(getId(), getTrace(), "already executed"); //$NON-NLS-1$
             return;
         }
 
         /* Do not execute if analysis already running */
         synchronized (syncObj) {
             if (fStarted) {
+                TmfCoreTracer.traceAnalysis(getId(), getTrace(), "already started, not starting again"); //$NON-NLS-1$
                 return;
             }
             fStarted = true;
         }
 
+        /* Execute dependent analyses before creating the job for this one */
+        final Iterable<IAnalysisModule> dependentAnalyses = getDependentAnalyses();
+        for (IAnalysisModule module : dependentAnalyses) {
+            module.schedule();
+        }
+
         /*
          * Actual analysis will be run on a separate thread
          */
-        fJob = new Job(NLS.bind(Messages.TmfAbstractAnalysisModule_RunningAnalysis, getName())) {
+        String jobName = checkNotNull(NLS.bind(Messages.TmfAbstractAnalysisModule_RunningAnalysis, getName()));
+        fJob = new Job(jobName) {
             @Override
-            protected IStatus run(final IProgressMonitor monitor) {
+            protected @Nullable IStatus run(final @Nullable IProgressMonitor monitor) {
+                IProgressMonitor mon = monitor;
+                if (mon == null) {
+                    mon = new NullProgressMonitor();
+                }
                 try {
-                    monitor.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$
+                    mon.beginTask("", IProgressMonitor.UNKNOWN); //$NON-NLS-1$
                     broadcast(new TmfStartAnalysisSignal(TmfAbstractAnalysisModule.this, TmfAbstractAnalysisModule.this));
-                    fAnalysisCancelled = !executeAnalysis(monitor);
+                    TmfCoreTracer.traceAnalysis(TmfAbstractAnalysisModule.this.getId(), TmfAbstractAnalysisModule.this.getTrace(), "started"); //$NON-NLS-1$
+                    fAnalysisCancelled = !executeAnalysis(mon);
+                    for (IAnalysisModule module : dependentAnalyses) {
+                        module.waitForCompletion(mon);
+                    }
+                    TmfCoreTracer.traceAnalysis(TmfAbstractAnalysisModule.this.getId(), TmfAbstractAnalysisModule.this.getTrace(), "finished"); //$NON-NLS-1$
                 } catch (TmfAnalysisException e) {
                     Activator.logError("Error executing analysis with trace " + trace.getName(), e); //$NON-NLS-1$
                 } finally {
                     synchronized (syncObj) {
-                        monitor.done();
+                        mon.done();
                         setAnalysisCompleted();
                     }
                     TmfTraceManager.refreshSupplementaryFiles(trace);
@@ -310,6 +353,7 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
 
             @Override
             protected void canceling() {
+                TmfCoreTracer.traceAnalysis(getId(), getTrace(), "job cancelled"); //$NON-NLS-1$
                 TmfAbstractAnalysisModule.this.canceling();
             }
 
@@ -324,10 +368,11 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
             if (trace == null) {
                 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, String.format("No trace specified for analysis %s", getName())); //$NON-NLS-1$
             }
+            TmfCoreTracer.traceAnalysis(getId(), getTrace(), "scheduled"); //$NON-NLS-1$
             execute(trace);
         }
 
-        return Status.OK_STATUS;
+        return checkNotNull(Status.OK_STATUS);
     }
 
     @Override
@@ -389,7 +434,6 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
      *
      * @param signal
      *            Trace selected signal
-     * @since 3.1
      */
     @TmfSignalHandler
     public void traceSelected(TmfTraceSelectedSignal signal) {
@@ -410,7 +454,9 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
      * @return Full help text for the module
      */
     protected String getFullHelpText() {
-        return NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisModule, getName());
+        return NonNullUtils.nullToEmptyString(NLS.bind(
+                Messages.TmfAbstractAnalysisModule_AnalysisModule,
+                getName()));
     }
 
     /**
@@ -422,7 +468,9 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
      * @return Short help text describing the module
      */
     protected String getShortHelpText(ITmfTrace trace) {
-        return NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisForTrace, getName(), trace.getName());
+        return NonNullUtils.nullToEmptyString(NLS.bind(
+                Messages.TmfAbstractAnalysisModule_AnalysisForTrace,
+                getName(), trace.getName()));
     }
 
     /**
@@ -434,7 +482,7 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
      *            The trace to apply the analysis to
      * @return Help text
      */
-    protected String getTraceCannotExecuteHelpText(@NonNull ITmfTrace trace) {
+    protected String getTraceCannotExecuteHelpText(ITmfTrace trace) {
         StringBuilder builder = new StringBuilder();
         builder.append(NLS.bind(Messages.TmfAbstractAnalysisModule_AnalysisCannotExecute, getName()));
         for (TmfAnalysisRequirement requirement : getAnalysisRequirements()) {
@@ -450,7 +498,7 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
                 }
             }
         }
-        return builder.toString();
+        return checkNotNull(builder.toString());
     }
 
     @Override
@@ -460,9 +508,6 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
 
     @Override
     public String getHelpText(ITmfTrace trace) {
-        if (trace == null) {
-            return getHelpText();
-        }
         String text = getShortHelpText(trace);
         if (!canExecute(trace)) {
             text = text + "\n\n" + getTraceCannotExecuteHelpText(trace); //$NON-NLS-1$
@@ -472,6 +517,6 @@ public abstract class TmfAbstractAnalysisModule extends TmfComponent implements
 
     @Override
     public Iterable<TmfAnalysisRequirement> getAnalysisRequirements() {
-        return Collections.EMPTY_SET;
+        return checkNotNull(Collections.EMPTY_SET);
     }
 }
This page took 0.030427 seconds and 5 git commands to generate.