Merge branch 'JAL-3878_ws-overhaul-3' into mmw/Release_2_12_ws_merge
[jalview.git] / src / jalview / ws2 / actions / BaseJob.java
diff --git a/src/jalview/ws2/actions/BaseJob.java b/src/jalview/ws2/actions/BaseJob.java
new file mode 100644 (file)
index 0000000..945c7b0
--- /dev/null
@@ -0,0 +1,193 @@
+package jalview.ws2.actions;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.List;
+
+import jalview.datamodel.SequenceI;
+import jalview.util.MathUtils;
+import jalview.ws2.actions.api.JobI;
+import jalview.ws2.actions.api.TaskEventListener;
+import jalview.ws2.api.JobStatus;
+import jalview.ws2.api.WebServiceJobHandle;
+
+/**
+ * Basic implementation of the {@link JobI} interface which stores internal job
+ * id, status, log and error log and provides getters to those fields.
+ * Additionally, it stores sequences that will be submitted as job input and the
+ * handle to the job on the server. Extending classes can add extra fields in
+ * order to associate additional data with the job.
+ * 
+ * Observers can be registered with this bean-like object to listen to changes
+ * to {@code status}, {@code log}, and {@code errorLog} properties. Typically,
+ * the events are delegated to the {@link TaskEventListener} objects observing
+ * the task that created this job.
+ * 
+ * @author mmwarowny
+ */
+public abstract class BaseJob implements JobI
+{
+  protected final long internalId = MathUtils.getUID();
+
+  protected final List<SequenceI> inputSeqs;
+
+  protected JobStatus status = null;
+
+  protected String log = "";
+
+  protected String errorLog = "";
+
+  /* FIXME: server job is not specific to the BaseJob and should preferably
+   * be managed by classes using clients (tasks). */
+  protected WebServiceJobHandle serverJob;
+
+  public BaseJob(List<SequenceI> inputSeqs)
+  {
+    this.inputSeqs = inputSeqs;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public final long getInternalId()
+  {
+    return internalId;
+  }
+
+  /**
+   * Return the list of input sequences associated with this job.
+   * 
+   * @return input sequences
+   */
+  public List<SequenceI> getInputSequences()
+  {
+    return inputSeqs;
+  }
+
+  /**
+   * Check if inputs make a valid job.
+   * 
+   * @return {@code true} if the input is valid.
+   */
+  public abstract boolean isInputValid();
+
+  /**
+   * Check if the job is completed, This includes jobs with invalid input,
+   * successful and unsuccessful termination.
+   * 
+   * @return {@code true} if job is completed successfully or not
+   */
+  public boolean isCompleted()
+  {
+    return !isInputValid() || getStatus().isDone();
+  }
+
+  @Override
+  public final JobStatus getStatus()
+  {
+    return status;
+  }
+
+  /**
+   * Set new status of the job and notify listeners of the change. Job status is
+   * managed internally by tasks and should not be modified outside the task
+   * which created this job.
+   * 
+   * @param status
+   *          new job status
+   */
+  public final void setStatus(JobStatus status)
+  {
+    JobStatus oldStatus = this.status;
+    this.status = status;
+    pcs.firePropertyChange("status", oldStatus, status);
+  }
+
+  @Override
+  public final String getLog()
+  {
+    return log;
+  }
+
+  /**
+   * Set log text and notify listeners of the change. Log is managed by tasks
+   * which created the job and should not be modified by other classes.
+   * 
+   * @param log
+   *          new log
+   */
+  public final void setLog(String log)
+  {
+    String oldLog = this.log;
+    this.log = log;
+    pcs.firePropertyChange("log", oldLog, log);
+  }
+
+  @Override
+  public final String getErrorLog()
+  {
+    return errorLog;
+  }
+
+  /**
+   * Set error log text and notify listeners of the change. Error log is managed
+   * by tasks which created the job and should not be modified by other classes.
+   * 
+   * @param errorLog
+   */
+  public final void setErrorLog(String errorLog)
+  {
+    String oldLog = this.errorLog;
+    this.errorLog = errorLog;
+    pcs.firePropertyChange("errorLog", oldLog, errorLog);
+  }
+
+  /**
+   * Return the job handle that identifies this job running on the server or
+   * {@code null} if the job was not submitted.
+   * 
+   * @return server job handle
+   */
+  public final WebServiceJobHandle getServerJob()
+  {
+    return serverJob;
+  }
+
+  /**
+   * Set the server job handle once the job was submitted to the server. The
+   * handler is managed by the task which created this job and should not be
+   * modified by other classes.
+   * 
+   * @param job
+   */
+  public final void setServerJob(WebServiceJobHandle job)
+  {
+    this.serverJob = job;
+  }
+
+  private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
+
+  /**
+   * Register an observer that will be notified of changes to status, log and
+   * error log.
+   * 
+   * @param listener
+   *          property change listener
+   */
+  public final void addPropertyChagneListener(PropertyChangeListener listener)
+  {
+    pcs.addPropertyChangeListener(listener);
+  }
+
+  /**
+   * Remove the property listener from this object.
+   * 
+   * @param listener
+   *          listener to remove
+   */
+  public final void removePropertyChangeListener(PropertyChangeListener listener)
+  {
+    pcs.removePropertyChangeListener(listener);
+  }
+}