--- /dev/null
+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);
+ }
+}