906b6257bb448625bfe9a3136e3fe07f58f961a1
[jalview.git] / src / jalview / ws2 / actions / BaseJob.java
1 package jalview.ws2.actions;
2
3 import java.beans.PropertyChangeListener;
4 import java.beans.PropertyChangeSupport;
5 import java.util.List;
6
7 import jalview.datamodel.SequenceI;
8 import jalview.util.MathUtils;
9 import jalview.ws2.actions.api.JobI;
10 import jalview.ws2.actions.api.TaskEventListener;
11 import jalview.ws2.api.JobStatus;
12 import jalview.ws2.api.WebServiceJobHandle;
13
14 /**
15  * Basic implementation of the {@link JobI} interface which stores internal job
16  * id, status, log and error log and provides getters to those fields.
17  * Additionally, it stores sequences that will be submitted as job input and the
18  * handle to the job on the server. Extending classes can add extra fields in
19  * order to associate additional data with the job.
20  * 
21  * Observers can be registered with this bean-like object to listen to changes
22  * to {@code status}, {@code log}, and {@code errorLog} properties. Typically,
23  * the events are delegated to the {@link TaskEventListener} objects observing
24  * the task that created this job.
25  * 
26  * @author mmwarowny
27  */
28 public abstract class BaseJob implements JobI
29 {
30   protected final long internalId = MathUtils.getUID();
31
32   protected final List<SequenceI> inputSeqs;
33
34   protected JobStatus status = null;
35
36   protected String log = "";
37
38   protected String errorLog = "";
39
40   /* FIXME: server job is not specific to the BaseJob and should preferably
41    * be managed by classes using clients (tasks). */
42   protected WebServiceJobHandle serverJob;
43
44   public BaseJob(List<SequenceI> inputSeqs)
45   {
46     this.inputSeqs = inputSeqs;
47   }
48
49   /**
50    * {@inheritDoc}
51    */
52   @Override
53   public final long getInternalId()
54   {
55     return internalId;
56   }
57
58   /**
59    * Return the list of input sequences associated with this job.
60    * 
61    * @return input sequences
62    */
63   public List<SequenceI> getInputSequences()
64   {
65     return inputSeqs;
66   }
67
68   /**
69    * Check if inputs make a valid job.
70    * 
71    * @return {@code true} if the input is valid.
72    */
73   public abstract boolean isInputValid();
74
75   /**
76    * Check if the job is completed, This includes jobs with invalid input,
77    * successful and unsuccessful termination.
78    * 
79    * @return {@code true} if job is completed successfully or not
80    */
81   public boolean isCompleted()
82   {
83     return !isInputValid() || getStatus().isDone();
84   }
85
86   @Override
87   public final JobStatus getStatus()
88   {
89     return status;
90   }
91
92   /**
93    * Set new status of the job and notify listeners of the change. Job status is
94    * managed internally by tasks and should not be modified outside the task
95    * which created this job.
96    * 
97    * @param status
98    *          new job status
99    */
100   public final void setStatus(JobStatus status)
101   {
102     JobStatus oldStatus = this.status;
103     this.status = status;
104     pcs.firePropertyChange("status", oldStatus, status);
105   }
106
107   @Override
108   public final String getLog()
109   {
110     return log;
111   }
112
113   /**
114    * Set log text and notify listeners of the change. Log is managed by tasks
115    * which created the job and should not be modified by other classes.
116    * 
117    * @param log
118    *          new log
119    */
120   final void setLog(String log)
121   {
122     String oldLog = this.log;
123     this.log = log;
124     pcs.firePropertyChange("log", oldLog, log);
125   }
126
127   @Override
128   public final String getErrorLog()
129   {
130     return errorLog;
131   }
132
133   /**
134    * Set error log text and notify listeners of the change. Error log is managed
135    * by tasks which created the job and should not be modified by other classes.
136    * 
137    * @param errorLog
138    */
139   final void setErrorLog(String errorLog)
140   {
141     String oldLog = this.errorLog;
142     this.errorLog = errorLog;
143     pcs.firePropertyChange("errorLog", oldLog, errorLog);
144   }
145
146   /**
147    * Return the job handle that identifies this job running on the server or
148    * {@code null} if the job was not submitted.
149    * 
150    * @return server job handle
151    */
152   public final WebServiceJobHandle getServerJob()
153   {
154     return serverJob;
155   }
156
157   /**
158    * Set the server job handle once the job was submitted to the server. The
159    * handler is managed by the task which created this job and should not be
160    * modified by other classes.
161    * 
162    * @param job
163    */
164   final void setServerJob(WebServiceJobHandle job)
165   {
166     this.serverJob = job;
167   }
168
169   private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
170
171   /**
172    * Register an observer that will be notified of changes to status, log and
173    * error log.
174    * 
175    * @param listener
176    *          property change listener
177    */
178   public final void addPropertyChagneListener(PropertyChangeListener listener)
179   {
180     pcs.addPropertyChangeListener(listener);
181   }
182
183   /**
184    * Remove the property listener from this object.
185    * 
186    * @param listener
187    *          listener to remove
188    */
189   public final void removePropertyChangeListener(PropertyChangeListener listener)
190   {
191     pcs.removePropertyChangeListener(listener);
192   }
193 }