Merge branch 'feature/JAL-3954-ebi-phmmer' into mmw/JAL-4199-task-execution-update
[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 // TODO: make class non-abstract by removing isInputValid()
29 public abstract class BaseJob implements JobI
30 {
31   protected final long internalId = MathUtils.getUID();
32
33   protected final List<SequenceI> inputSeqs;
34
35   protected JobStatus status = JobStatus.CREATED;
36
37   protected String log = "";
38
39   protected String errorLog = "";
40
41   /* FIXME: server job is not specific to the BaseJob and should preferably
42    * be managed by classes using clients (tasks). */
43   protected WebServiceJobHandle serverJob;
44
45   public BaseJob(List<SequenceI> inputSeqs)
46   {
47     this.inputSeqs = inputSeqs;
48   }
49
50   /**
51    * {@inheritDoc}
52    */
53   @Override
54   public final long getInternalId()
55   {
56     return internalId;
57   }
58
59   /**
60    * Return the list of input sequences associated with this job.
61    * 
62    * @return input sequences
63    */
64   public List<SequenceI> getInputSequences()
65   {
66     return inputSeqs;
67   }
68
69   /**
70    * Check if inputs make a valid job.
71    * 
72    * @return {@code true} if the input is valid.
73    */
74   // FIXME: method not necessary, may incorporate into task#prepare()
75   public abstract boolean isInputValid();
76
77   /**
78    * Check if the job is completed, This includes jobs with invalid input,
79    * successful and unsuccessful termination.
80    * 
81    * @return {@code true} if job is completed successfully or not
82    */
83   public boolean isCompleted()
84   {
85     return !isInputValid() || getStatus().isDone();
86   }
87
88   @Override
89   public final JobStatus getStatus()
90   {
91     return status;
92   }
93
94   /**
95    * Set new status of the job and notify listeners of the change. Job status is
96    * managed internally by tasks and should not be modified outside the task
97    * which created this job.
98    * 
99    * @param status
100    *          new job status
101    */
102   public final void setStatus(JobStatus status)
103   {
104     JobStatus oldStatus = this.status;
105     this.status = status;
106     pcs.firePropertyChange("status", oldStatus, status);
107   }
108
109   @Override
110   public final String getLog()
111   {
112     return log;
113   }
114
115   /**
116    * Set log text and notify listeners of the change. Log is managed by tasks
117    * which created the job and should not be modified by other classes.
118    * 
119    * @param log
120    *          new log
121    */
122   public final void setLog(String log)
123   {
124     String oldLog = this.log;
125     this.log = log;
126     pcs.firePropertyChange("log", oldLog, log);
127   }
128
129   @Override
130   public final String getErrorLog()
131   {
132     return errorLog;
133   }
134
135   /**
136    * Set error log text and notify listeners of the change. Error log is managed
137    * by tasks which created the job and should not be modified by other classes.
138    * 
139    * @param errorLog
140    */
141   public final void setErrorLog(String errorLog)
142   {
143     String oldLog = this.errorLog;
144     this.errorLog = errorLog;
145     pcs.firePropertyChange("errorLog", oldLog, errorLog);
146   }
147
148   /**
149    * Return the job handle that identifies this job running on the server or
150    * {@code null} if the job was not submitted.
151    * 
152    * @return server job handle
153    */
154   public final WebServiceJobHandle getServerJob()
155   {
156     return serverJob;
157   }
158
159   /**
160    * Set the server job handle once the job was submitted to the server. The
161    * handler is managed by the task which created this job and should not be
162    * modified by other classes.
163    * 
164    * @param job
165    */
166   public final void setServerJob(WebServiceJobHandle job)
167   {
168     this.serverJob = job;
169   }
170
171   private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
172
173   /**
174    * Register an observer that will be notified of changes to status, log and
175    * error log.
176    * 
177    * @param listener
178    *          property change listener
179    */
180   public final void addPropertyChangeListener(PropertyChangeListener listener)
181   {
182     pcs.addPropertyChangeListener(listener);
183   }
184
185   /**
186    * Remove the property listener from this object.
187    * 
188    * @param listener
189    *          listener to remove
190    */
191   public final void removePropertyChangeListener(PropertyChangeListener listener)
192   {
193     pcs.removePropertyChangeListener(listener);
194   }
195 }