1 package jalview.ws.rest;
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Hashtable;
7 import java.util.Map.Entry;
9 import java.util.Vector;
11 import jalview.datamodel.AlignmentI;
12 import jalview.datamodel.AlignmentView;
13 import jalview.datamodel.SequenceGroup;
14 import jalview.datamodel.SequenceI;
15 import jalview.io.packed.JalviewDataset;
16 import jalview.ws.AWsJob;
17 import jalview.ws.rest.params.Alignment;
18 import jalview.ws.rest.params.SeqGroupIndexVector;
20 public class RestJob extends AWsJob
23 // TODO: input alignmentview and other data for this job
24 RestServiceDescription rsd;
33 * create a rest job using data bounded by the given start/end column.
35 * @param restJobThread
38 public RestJob(int jobNum, RestJobThread restJobThread,
41 rsd = restJobThread.restClient.service;
43 // get sequences for the alignmentI
44 // get groups trimmed to alignment columns
45 // get any annotation trimmed to start/end columns, too.
48 // form alignment+groups+annotation,preprocess and then record references for formatters
49 ArrayList<InputType> alinp = new ArrayList<InputType>();
51 // we cheat for moment - since we know a-priori what data is available and what inputs we have implemented so far
52 for (Map.Entry<String,InputType>prm: rsd.inputParams.entrySet())
54 if (!prm.getValue().isConstant())
56 if (prm.getValue() instanceof Alignment)
58 alinp.add(prm.getValue());
61 if ((prm.getValue() instanceof SeqGroupIndexVector)
62 &&(_input.getGroups()!=null && _input.getGroups().size()>0))
64 alinp.add(prm.getValue());
71 if ((paramsWithData+alinp.size())==rsd.inputParams.size())
73 setAlignmentForInputs(alinp, _input);
76 // not enough data, so we bail.
80 boolean validInput=false;
82 public boolean hasResults()
88 public boolean hasValidInput()
94 public boolean isRunning()
96 return running; // TODO: can we check the response body for status messages ?
100 public boolean isQueued()
106 public boolean isFinished()
112 public boolean isFailed()
114 // TODO logic for error
119 public boolean isBroken()
121 // TODO logic for error
126 public boolean isServerError()
128 // TODO logic for error
133 public boolean hasStatus()
135 return statMessage != null;
138 protected String statMessage = null;
139 public HttpResultSet resSet;
142 public String getStatus()
148 public boolean hasResponse()
150 return statMessage!=null || resSet!=null;
154 public void clearResponse()
156 // only clear the transient server response
161 * @see jalview.ws.AWsJob#getState()
164 public String getState()
166 // TODO generate state string - prolly should have a default abstract method for this
167 return "Job is clueless";
170 public String getPostUrl()
173 // TODO Auto-generated method stub
177 public Set<Map.Entry<String,InputType>> getInputParams()
179 return rsd.inputParams.entrySet();
182 // return the URL that should be polled for this job
183 public String getPollUrl()
185 return rsd.getDecoratedResultUrl(jobId);
190 * @return new context for parsing results from service
192 public JalviewDataset newJalviewDataset()
195 * TODO: initialise dataset with correct input context
197 JalviewDataset njd = new JalviewDataset();
202 * Extract list of sequence IDs for input parameter 'token' with given molecule type
207 public SequenceI[] getSequencesForInput(String token, InputType.molType type) throws NoValidInputDataException
209 Object sgdat = inputData.get(token);
210 // can we form an alignment from this data ?
213 throw new NoValidInputDataException("No Sequence vector data bound to input '"+token+"' for service at "+rsd.postUrl);
215 if (sgdat instanceof AlignmentI)
217 return ((AlignmentI) sgdat).getSequencesArray();
219 if (sgdat instanceof SequenceGroup)
221 return ((SequenceGroup)sgdat).getSequencesAsArray(null);
223 if (sgdat instanceof Vector)
225 if (((Vector)sgdat).size()>0 && ((Vector)sgdat).get(0) instanceof SequenceI)
227 SequenceI[] sq = new SequenceI[((Vector)sgdat).size()];
228 ((Vector)sgdat).copyInto(sq);
232 throw new NoValidInputDataException("No Sequence vector data bound to input '"+token+"' for service at "+rsd.postUrl);
235 * binding between input data (AlignmentI, SequenceGroup, NJTree) and input param names.
237 private Hashtable<String,Object> inputData=new Hashtable<String,Object>();
239 * is the job fully submitted to server and apparently in progress ?
241 public boolean running=false;
245 * @param al - reference to object to be stored as input. Note - input data may be modifed by formatter
247 public void setAlignmentForInputs(Collection<InputType> itypes, AlignmentI al)
249 for (InputType itype: itypes) {
250 if (!rsd.inputParams.values().contains(itype))
252 throw new IllegalArgumentException("InputType "+itype.getClass()+
253 " is not valid for service at "+rsd.postUrl);
255 if (itype instanceof AlignmentProcessor)
257 ((AlignmentProcessor)itype).prepareAlignment(al);
259 // stash a reference for recall when the alignment data is formatted
260 inputData.put(itype.token, al);
268 * @return alignment object bound to the given token
269 * @throws NoValidInputDataException
271 public AlignmentI getAlignmentForInput(String token, InputType.molType type) throws NoValidInputDataException
273 Object al = inputData.get(token);
274 // can we form an alignment from this data ?
275 if (al==null || !(al instanceof AlignmentI))
277 throw new NoValidInputDataException("No alignment data bound to input '"+token+"' for service at "+rsd.postUrl);
279 return (AlignmentI) al;
283 * test to see if the job has data of type cl that's needed for the job to run
285 * @return true or false
287 public boolean hasDataOfType(Class cl)
289 if (AlignmentI.class.isAssignableFrom(cl)) {
292 // TODO: add more source data types