JAL-3070 refactored Client specific code from jalview.ws.jws2.MSA* as implementors...
[jalview.git] / src / jalview / ws / jws2 / jabaws2 / JabawsMsaInstance.java
1 package jalview.ws.jws2.jabaws2;
2
3 import jalview.bin.Cache;
4 import jalview.datamodel.AlignmentI;
5 import jalview.datamodel.Sequence;
6 import jalview.datamodel.SequenceI;
7 import jalview.gui.WebserviceInfo;
8 import jalview.util.MessageManager;
9 import jalview.ws.api.CancellableI;
10 import jalview.ws.api.JobId;
11 import jalview.ws.api.MultipleSequenceAlignmentI;
12 import jalview.ws.gui.WsJob;
13 import jalview.ws.gui.WsJob.JobState;
14 import jalview.ws.jws2.JabaParamStore;
15 import jalview.ws.jws2.JabaPreset;
16 import jalview.ws.jws2.dm.JabaWsParamSet;
17 import jalview.ws.params.ArgumentI;
18 import jalview.ws.params.InvalidArgumentException;
19 import jalview.ws.params.WsParamSetI;
20
21 import java.io.IOError;
22 import java.rmi.ServerError;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27
28 import compbio.data.msa.MsaWS;
29 import compbio.data.sequence.Alignment;
30 import compbio.data.sequence.FastaSequence;
31 import compbio.metadata.Argument;
32 import compbio.metadata.ChunkHolder;
33 import compbio.metadata.JobStatus;
34 import compbio.metadata.Preset;
35 import compbio.metadata.ResultNotAvailableException;
36
37 public class JabawsMsaInstance
38         implements MultipleSequenceAlignmentI, CancellableI
39 {
40   /**
41    * our service instance handler generated by the discoverer
42    */
43   Jws2Instance our;
44
45   MsaWS<?> service;
46
47   @Override
48   public JobId align(List<SequenceI> toalign, WsParamSetI parameters,
49           List<ArgumentI> arguments) throws Throwable
50   {
51     List<compbio.data.sequence.FastaSequence> seqs = new ArrayList<>();
52     for (SequenceI seq : toalign)
53     {
54       seqs.add(new FastaSequence(seq.getName(), seq.getSequenceAsString()));
55     }
56     String jobid = null;
57     if (parameters != null)
58     {
59       if (parameters instanceof JabaPreset)
60       {
61         jobid = service.presetAlign(seqs,
62                 ((JabaPreset) parameters).getJabaPreset());
63       }
64       else
65       {
66         jobid = service.customAlign(seqs, JabaParamStore
67                 .getJabafromJwsArgs(parameters.getArguments()));
68       }
69     }
70     else if (arguments != null && arguments.size() > 0)
71     {
72       jobid = service.customAlign(seqs,
73               JabaParamStore.getJabafromJwsArgs(arguments));
74     }
75     else
76     {
77       jobid = service.align(seqs);
78     }
79
80     if (jobid == null)
81     {
82       return null;
83     }
84     return new JobId(our.getServiceType(), our.getName(), jobid);
85   }
86
87   @Override
88   public AlignmentI getAlignmentFor(JobId jobId)
89           throws InvalidArgumentException, ServerError, IOError
90   {
91     Alignment alignment = null;
92     try
93     {
94       alignment = service.getResult(jobId.getJobId());
95     } catch (ResultNotAvailableException rnotav)
96     {
97
98       // TODO - migrate JABA exception
99       // throw new ServerError("Couldn't get result for job",rnotav);
100     }
101     SequenceI[] alseqs;
102     int alseq_l = 0;
103     if (alignment.getSequences().size() == 0)
104     {
105       return null;
106     }
107
108     alseqs = new SequenceI[alignment.getSequences().size()];
109     for (compbio.data.sequence.FastaSequence seq : alignment.getSequences())
110     {
111       alseqs[alseq_l++] = new Sequence(seq.getId(), seq.getSequence());
112     }
113     AlignmentI jv_al = new jalview.datamodel.Alignment(alseqs);
114     jv_al.setGapCharacter(alignment.getMetadata().getGapchar());
115     return jv_al;
116
117   }
118
119   public JabawsMsaInstance(Jws2Instance handle)
120   {
121     our = handle;
122     service = (MsaWS<?>) our.service;
123   }
124
125   @Override
126   public boolean cancel(WsJob job)
127   {
128     service.cancelJob(job.getJobId());
129     // if the Jaba server indicates the job can't be cancelled, its
130     // because its running on the server's local execution engine
131     // so we just close the window anyway.
132
133     return true;
134   }
135
136   Map<JobStatus, JobState> jwsState = new HashMap<>();
137   {
138     jwsState.put(JobStatus.CANCELLED, JobState.CANCELLED);
139     jwsState.put(JobStatus.COLLECTED, JobState.FINISHED);
140     jwsState.put(JobStatus.FAILED, JobState.FAILED);
141     jwsState.put(JobStatus.FINISHED, JobState.FINISHED);
142     jwsState.put(JobStatus.PENDING, JobState.QUEUED);
143     jwsState.put(JobStatus.RUNNING, JobState.RUNNING);
144     jwsState.put(JobStatus.STARTED, JobState.RUNNING);
145     jwsState.put(JobStatus.SUBMITTED, JobState.SUBMITTED);
146     jwsState.put(JobStatus.UNDEFINED, JobState.UNKNOWN);
147   }
148   @Override
149   public void updateStatus(WsJob job)
150   {
151     JobStatus jwsstatus = service.getJobStatus(job.getJobId());
152     job.setState(jwsState.get(jwsstatus));
153   }
154
155   @Override
156   public boolean updateJobProgress(WsJob job) throws Exception
157   {
158     StringBuilder response = new StringBuilder(job.getStatus());
159     long lastchunk = job.getNextChunk();
160     boolean changed = false;
161     do
162     {
163       ChunkHolder chunk = service.pullExecStatistics(job.getJobId(),
164               lastchunk);
165       if (chunk != null)
166       {
167         changed |= chunk.getChunk().length() > 0;
168         response.append(chunk.getChunk());
169         lastchunk = chunk.getNextPosition();
170         try
171         {
172           Thread.sleep(50);
173         } catch (InterruptedException x)
174         {
175         }
176         ;
177       }
178       ;
179       job.setnextChunk(lastchunk);
180     } while (lastchunk >= 0 && job.getNextChunk() != lastchunk);
181     if (job instanceof WsJob)
182     {
183       // TODO decide if WsJob will be the bean for all ng-webservices
184       job.setStatus(response.toString());
185     }
186     return changed;
187   }
188
189   public boolean isPresetJob(WsJob job)
190   {
191     return job.getPreset() != null && job.getPreset() instanceof JabaPreset;
192   }
193
194   public Preset getServerPreset(WsJob job)
195   {
196     return (isPresetJob(job))
197             ? ((JabaPreset) job.getPreset()).getJabaPreset()
198             : null;
199   }
200
201   public List<Argument> getJabaArguments(WsParamSetI preset)
202   {
203     List<Argument> newargs = new ArrayList<>();
204     if (preset != null)
205     {
206       if (preset instanceof JabaWsParamSet)
207       {
208         newargs.addAll(((JabaWsParamSet) preset).getjabaArguments());
209       }
210       else
211       {
212         newargs.addAll(
213                 JabaParamStore.getJabafromJwsArgs(preset.getArguments()));
214       }
215     }
216     return newargs;
217   }
218
219   @Override
220   public boolean handleSubmitError(Throwable _lex, WsJob j,
221           WebserviceInfo wsInfo) throws Exception, Error
222   {
223     if (_lex instanceof compbio.metadata.UnsupportedRuntimeException)
224     {
225       wsInfo.appendProgressText(MessageManager.formatMessage(
226               "info.job_couldnt_be_run_server_doesnt_support_program",
227               new String[]
228               { _lex.getMessage() }));
229       wsInfo.warnUser(_lex.getMessage(),
230               MessageManager.getString("warn.service_not_supported"));
231       wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);
232       wsInfo.setStatus(j.getJobnum(),
233               WebserviceInfo.STATE_STOPPED_SERVERERROR);
234       return true;
235     }
236     if (_lex instanceof compbio.metadata.LimitExceededException)
237     {
238       wsInfo.appendProgressText(MessageManager.formatMessage(
239               "info.job_couldnt_be_run_exceeded_hard_limit", new String[]
240               { _lex.getMessage() }));
241       wsInfo.warnUser(_lex.getMessage(),
242               MessageManager.getString("warn.input_is_too_big"));
243       wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
244       wsInfo.setStatus(j.getJobnum(), WebserviceInfo.STATE_STOPPED_ERROR);
245       return true;
246     }
247     if (_lex instanceof compbio.metadata.WrongParameterException)
248     {
249       wsInfo.warnUser(_lex.getMessage(),
250               MessageManager.getString("warn.invalid_job_param_set"));
251       wsInfo.appendProgressText(MessageManager.formatMessage(
252               "info.job_couldnt_be_run_incorrect_param_setting",
253               new String[]
254               { _lex.getMessage() }));
255       wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
256       wsInfo.setStatus(j.getJobnum(), WebserviceInfo.STATE_STOPPED_ERROR);
257       return true;
258     }
259     // pass on to generic error handler
260     return false;
261   }
262
263   @Override
264   public boolean handleCollectionException(Exception ex, WsJob msjob,
265           WebserviceInfo wsInfo)
266   {
267     if (ex instanceof compbio.metadata.ResultNotAvailableException)
268     {
269       // job has failed for some reason - probably due to invalid
270       // parameters
271       Cache.log.debug(
272               "Results not available for finished job - marking as broken job.",
273               ex);
274       String status = msjob.getStatus();
275
276       msjob.setStatus(status
277               +
278               "\nResult not available. Probably due to invalid input or parameter settings. Server error message below:\n\n"
279                       + ex.getLocalizedMessage());
280       msjob.setState(WsJob.JobState.BROKEN);
281       return true;
282     }
283     return false;
284   }
285 }