--- /dev/null
+package jalview.ws2.api;
+
+public enum JobStatus
+{
+ /** Job has invalid inputs and cannot be started. */
+ INVALID,
+ /** Job is created and ready for submission. */
+ READY,
+ /** Job has been submitted and awaits processing. */
+ SUBMITTED,
+ /** Job has been queued for execution */
+ QUEUED,
+ /** Job is running */
+ RUNNING,
+ /** Job has completed successfully. */
+ COMPLETED,
+ /** Job has finished with errors. */
+ FAILED,
+ /** Job has been cancelled by the user. */
+ CANCELLED,
+ /** Job cannot be processed due to server error. */
+ SERVER_ERROR,
+ /** Job status cannot be determined. */
+ UNKNOWN;
+
+ /**
+ * Returns true if the status corresponds to the job completed due to normal
+ * termination, error or cancellation.
+ *
+ * @return {@value true} if status corresponds to a finished job.
+ */
+ public boolean isDone()
+ {
+ switch (this)
+ {
+ case COMPLETED:
+ case FAILED:
+ case CANCELLED:
+ case SERVER_ERROR:
+ return true;
+ case INVALID:
+ case READY:
+ case SUBMITTED:
+ case QUEUED:
+ case RUNNING:
+ case UNKNOWN:
+ return false;
+ default:
+ throw new AssertionError("non-exhaustive switch statement");
+ }
+ }
+
+ public boolean isCompleted()
+ {
+ return this == COMPLETED;
+ }
+
+ public boolean isCancelled()
+ {
+ return this == CANCELLED;
+ }
+}
--- /dev/null
+package jalview.ws2.client.api;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.Date;
+
+import jalview.util.MathUtils;
+import jalview.ws2.api.JobStatus;
+
+/**
+ * {@code WebServiceJob} represents a job running on a remote server. The object
+ * contains all the information needed to associate the job with an originating
+ * client and url, service being run and to poll the job and retrieve the
+ * results from the server. The {@code WebServiceJob} object is provided by the
+ * {@link WebServiceClientI#submit} method when the job is created.
+ *
+ * @see WebServiceClientI
+ *
+ * @author mmwarowny
+ */
+public class WebServiceJob
+{
+ /** Unique id used internally by Jalview */
+ private final long internalId = MathUtils.getUID();
+
+ /** Name of the related client */
+ private final String serviceClient;
+
+ /** Name of the related service */
+ private final String serviceName;
+
+ /** URL the job is valid for */
+ private final String url;
+
+ /** External job id as given by the server */
+ private final String jobId;
+
+ /** Current status of the job */
+ private JobStatus status = JobStatus.READY;
+
+ private String log = "";
+
+ private String errorLog = "";
+
+ private Date creationTime = new Date();
+
+ public WebServiceJob(String serviceClient, String serviceName,
+ String url, String jobId)
+ {
+ this.serviceClient = serviceClient;
+ this.serviceName = serviceName;
+ this.url = url;
+ this.jobId = jobId;
+ }
+
+ /**
+ * Get a unique job id used internally by Jalview.
+ *
+ * @return unique job id
+ */
+ public long getInternalId()
+ {
+ return internalId;
+ }
+
+ /**
+ * Get a URL this job originates from.
+ *
+ * @return job URL
+ */
+ public String getUrl()
+ {
+ return url;
+ }
+
+ /**
+ * Get an id assigned to the job by the server.
+ *
+ * @return job id handle
+ */
+ public String getJobId()
+ {
+ return jobId;
+ }
+
+ /**
+ * @return job status
+ */
+ public JobStatus getStatus()
+ {
+ return status;
+ }
+
+ /**
+ * Update status of the job and notify the listeners. This method should only
+ * be used by {@link WebServiceClientI} implementations when polling the job.
+ *
+ * @param status
+ * new job status
+ */
+ public void setStatus(JobStatus status)
+ {
+ JobStatus oldStatus = this.status;
+ this.status = status;
+ pcs.firePropertyChange("status", oldStatus, status);
+ }
+
+ /**
+ * @return standard progress log
+ */
+ public String getLog()
+ {
+ return log;
+ }
+
+ /**
+ * Update log string with data received from the server and notify the
+ * listeners. This method should only be used by {@link WebServiceClientI}
+ * implementations when polling the job.
+ *
+ * @param log
+ * new log string
+ */
+ public void setLog(String log)
+ {
+ String oldLog = this.log;
+ this.log = log;
+ pcs.firePropertyChange("log", oldLog, log);
+ }
+
+ /**
+ * @return error log
+ */
+ public String getErrorLog()
+ {
+ return errorLog;
+ }
+
+ /**
+ * Update error log string with data received from the server and notify the
+ * listeners. This method should only be used by {@link WebServiceClientI}
+ * implementations when polling the job
+ *
+ * @param errorLog
+ * new error log string
+ */
+ public void setErrorLog(String errorLog)
+ {
+ String oldLog = this.errorLog;
+ this.errorLog = errorLog;
+ pcs.firePropertyChange("errorLog", oldLog, errorLog);
+ }
+
+ /**
+ * @return Job creation time
+ */
+ public Date getCreationTime()
+ {
+ return creationTime;
+ }
+
+ public String toString()
+ {
+ return String.format("%s:%s [%s] Created %s", serviceClient, serviceName,
+ jobId, creationTime);
+ }
+
+ /* Methods related to bean listeners */
+ private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
+
+ public void addPropertyChangeListener(PropertyChangeListener listener)
+ {
+ pcs.addPropertyChangeListener(listener);
+ }
+
+ public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener)
+ {
+ pcs.addPropertyChangeListener(propertyName, listener);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener)
+ {
+ pcs.removePropertyChangeListener(listener);
+ }
+
+ public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener)
+ {
+ pcs.removePropertyChangeListener(propertyName, listener);
+ }
+}