1 package jalview.ws.rest;
3 import java.io.IOException;
4 import java.util.ArrayList;
5 import java.util.Collection;
6 import java.util.Hashtable;
9 import java.util.Map.Entry;
11 import java.util.Vector;
13 import jalview.datamodel.AlignmentI;
14 import jalview.datamodel.AlignmentOrder;
15 import jalview.datamodel.AlignmentView;
16 import jalview.datamodel.SequenceGroup;
17 import jalview.datamodel.SequenceI;
18 import jalview.io.packed.DataProvider;
19 import jalview.io.packed.JalviewDataset;
20 import jalview.io.packed.ParsePackedSet;
21 import jalview.io.packed.SimpleDataProvider;
22 import jalview.io.packed.DataProvider.JvDataType;
23 import jalview.ws.AWsJob;
24 import jalview.ws.rest.params.Alignment;
25 import jalview.ws.rest.params.SeqGroupIndexVector;
27 public class RestJob extends AWsJob
30 // TODO: input alignmentview and other data for this job
31 RestServiceDescription rsd;
45 * dataset associated with this input data.
49 AlignmentOrder inputOrder;
52 * context of input data with respect to an AlignmentView's visible contigs.
56 private AlignmentI contextAl=null;
59 * create a rest job using data bounded by the given start/end column.
62 * @param restJobThread
65 * visible contigs of an alignment view from which _input was derived
67 public RestJob(int jobNum, RestJobThread restJobThread,
68 AlignmentI _input, int[] viscontigs)
70 rsd = restJobThread.restClient.service;
72 if (viscontigs != null)
74 origviscontig = new int[viscontigs.length];
75 System.arraycopy(viscontigs, 0, origviscontig, 0, viscontigs.length);
77 // get sequences for the alignmentI
78 // get groups trimmed to alignment columns
79 // get any annotation trimmed to start/end columns, too.
82 // form alignment+groups+annotation,preprocess and then record references
84 ArrayList<InputType> alinp = new ArrayList<InputType>();
85 int paramsWithData = 0;
86 // we cheat for moment - since we know a-priori what data is available and
87 // what inputs we have implemented so far
88 for (Map.Entry<String, InputType> prm : rsd.inputParams.entrySet())
90 if (!prm.getValue().isConstant())
92 if (prm.getValue() instanceof Alignment)
94 alinp.add(prm.getValue());
98 if ((prm.getValue() instanceof SeqGroupIndexVector)
99 && (_input.getGroups() != null && _input.getGroups()
102 alinp.add(prm.getValue());
111 if ((paramsWithData + alinp.size()) == rsd.inputParams.size())
113 inputOrder = new AlignmentOrder(_input);
114 if ((dsForIO = _input.getDataset()) == null)
116 _input.setDataset(null);
118 dsForIO = _input.getDataset();
123 setAlignmentForInputs(alinp, _input);
128 // not enough data, so we bail.
133 boolean validInput = false;
136 public boolean hasResults()
142 public boolean hasValidInput()
148 public boolean isRunning()
150 return running; // TODO: can we check the response body for status messages
155 public boolean isQueued()
161 public boolean isFinished()
163 return resSet != null;
167 public boolean isFailed()
169 // TODO logic for error
174 public boolean isBroken()
176 // TODO logic for error
181 public boolean isServerError()
183 // TODO logic for error
188 public boolean hasStatus()
190 return statMessage != null;
193 protected String statMessage = null;
195 public HttpResultSet resSet;
198 public String getStatus()
204 public boolean hasResponse()
206 return statMessage != null || resSet != null;
210 public void clearResponse()
212 // only clear the transient server response
219 * @see jalview.ws.AWsJob#getState()
222 public String getState()
224 // TODO generate state string - prolly should have a default abstract method
226 return "Job is clueless";
229 public String getPostUrl()
232 // TODO Auto-generated method stub
236 public Set<Map.Entry<String, InputType>> getInputParams()
238 return rsd.inputParams.entrySet();
241 // return the URL that should be polled for this job
242 public String getPollUrl()
244 return rsd.getDecoratedResultUrl(jobId);
249 * @return the context for parsing results from service
251 public JalviewDataset newJalviewDataset()
255 context = new JalviewDataset(dsForIO, null, squniq, null);
258 context.addAlignment(contextAl);
266 * Extract list of sequence IDs for input parameter 'token' with given
273 public SequenceI[] getSequencesForInput(String token,
274 InputType.molType type) throws NoValidInputDataException
276 Object sgdat = inputData.get(token);
277 // can we form an alignment from this data ?
280 throw new NoValidInputDataException(
281 "No Sequence vector data bound to input '" + token
282 + "' for service at " + rsd.postUrl);
284 if (sgdat instanceof AlignmentI)
286 return ((AlignmentI) sgdat).getSequencesArray();
288 if (sgdat instanceof SequenceGroup)
290 return ((SequenceGroup) sgdat).getSequencesAsArray(null);
292 if (sgdat instanceof Vector)
294 if (((Vector) sgdat).size() > 0
295 && ((Vector) sgdat).get(0) instanceof SequenceI)
297 SequenceI[] sq = new SequenceI[((Vector) sgdat).size()];
298 ((Vector) sgdat).copyInto(sq);
302 throw new NoValidInputDataException(
303 "No Sequence vector data bound to input '" + token
304 + "' for service at " + rsd.postUrl);
308 * binding between input data (AlignmentI, SequenceGroup, NJTree) and input
311 private Hashtable<String, Object> inputData = new Hashtable<String, Object>();
314 * is the job fully submitted to server and apparently in progress ?
316 public boolean running = false;
322 * - reference to object to be stored as input. Note - input data may
323 * be modifed by formatter
325 public void setAlignmentForInputs(Collection<InputType> itypes,
328 for (InputType itype : itypes)
330 if (!rsd.inputParams.values().contains(itype))
332 throw new IllegalArgumentException("InputType " + itype.getClass()
333 + " is not valid for service at " + rsd.postUrl);
335 if (itype instanceof AlignmentProcessor)
337 ((AlignmentProcessor) itype).prepareAlignment(al);
339 // stash a reference for recall when the alignment data is formatted
340 inputData.put(itype.token, al);
349 * @return alignment object bound to the given token
350 * @throws NoValidInputDataException
352 public AlignmentI getAlignmentForInput(String token,
353 InputType.molType type) throws NoValidInputDataException
355 Object al = inputData.get(token);
356 // can we form an alignment from this data ?
357 if (al == null || !(al instanceof AlignmentI))
359 throw new NoValidInputDataException(
360 "No alignment data bound to input '" + token
361 + "' for service at " + rsd.postUrl);
363 return (AlignmentI) al;
367 * test to see if the job has data of type cl that's needed for the job to run
370 * @return true or false
372 public boolean hasDataOfType(Class cl)
374 if (AlignmentI.class.isAssignableFrom(cl))
378 // TODO: add more source data types
384 * context used to parse results from service
386 JalviewDataset context = null;
388 Object[] jvresultobj = null;
391 * process the results obtained from the server into jalview datamodel objects
392 * ready to be merged/added to the users' view.
394 public void parseResultSet() throws Exception, Error
396 jvresultobj = resSet.parseResultSet();