Add the remaining msa services to the Discoverer
[jalview.git] / src / jalview / ws / slivkaws / SlivkaWSInstance.java
1 package jalview.ws.slivkaws;
2
3 import jalview.datamodel.AlignmentI;
4 import jalview.datamodel.SequenceI;
5 import jalview.gui.WebserviceInfo;
6 import jalview.io.DataSourceType;
7 import jalview.io.FileFormat;
8 import jalview.io.FormatAdapter;
9 import jalview.ws.api.JalviewServiceEndpointProviderI;
10 import jalview.ws.api.JobId;
11 import jalview.ws.api.MultipleSequenceAlignmentI;
12 import jalview.ws.api.ServiceWithParameters;
13 import jalview.ws.gui.WsJob;
14 import jalview.ws.params.ArgumentI;
15 import jalview.ws.params.InvalidArgumentException;
16 import jalview.ws.params.ParamDatastoreI;
17 import jalview.ws.params.ParamManager;
18 import jalview.ws.params.WsParamSetI;
19
20 import java.io.ByteArrayInputStream;
21 import java.io.IOError;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.rmi.ServerError;
25 import java.util.EnumMap;
26 import java.util.HashMap;
27 import java.util.List;
28
29 import uk.ac.dundee.compbio.slivkaclient.FormField;
30 import uk.ac.dundee.compbio.slivkaclient.FormValidationException;
31 import uk.ac.dundee.compbio.slivkaclient.JobState;
32 import uk.ac.dundee.compbio.slivkaclient.RemoteFile;
33 import uk.ac.dundee.compbio.slivkaclient.SlivkaClient;
34 import uk.ac.dundee.compbio.slivkaclient.SlivkaForm;
35 import uk.ac.dundee.compbio.slivkaclient.SlivkaService;
36 import uk.ac.dundee.compbio.slivkaclient.ValidationException;
37
38 public class SlivkaWSInstance extends ServiceWithParameters
39     implements MultipleSequenceAlignmentI, JalviewServiceEndpointProviderI
40 {
41   private SlivkaClient client;
42   private SlivkaService service;
43   private SlivkaDatastore store = null;
44
45   private EnumMap<JobState, WsJob.JobState> stateMap = new EnumMap<>(JobState.class);
46   {
47     stateMap.put(JobState.PENDING, WsJob.JobState.QUEUED);
48     stateMap.put(JobState.QUEUED, WsJob.JobState.QUEUED);
49     stateMap.put(JobState.RUNNING, WsJob.JobState.RUNNING);
50     stateMap.put(JobState.COMPLETED, WsJob.JobState.FINISHED);
51     stateMap.put(JobState.FAILED, WsJob.JobState.FAILED);
52     stateMap.put(JobState.ERROR, WsJob.JobState.SERVERERROR);
53     stateMap.put(JobState.UNKNOWN, WsJob.JobState.UNKNOWN);
54   }
55
56   SlivkaWSInstance(SlivkaClient client, SlivkaService service) {
57     super(service.getName(), "Alignment", service.getName(), "Slivka", client.getUrl().toString());
58     this.client = client;
59     this.service = service;
60   }
61
62   @Override
63   public void updateStatus(WsJob job)
64   {
65     try
66     {
67       job.setState(stateMap.get(client.getJobState(job.getJobId())));
68     } catch (IOException e)
69     {
70       throw new RuntimeException(e);
71     }
72   }
73
74   SlivkaService getService()
75   {
76     return service;
77   }
78
79   @Override
80   public boolean updateJobProgress(WsJob job)
81   {
82     return false;
83   }
84
85   @Override
86   public boolean handleSubmitError(Throwable _lex, WsJob j, WebserviceInfo wsInfo)
87   {
88     if (_lex instanceof FormValidationException)
89     {
90       FormValidationException formError = (FormValidationException) _lex;
91       String[] messages = new String[formError.getErrors().size()];
92       int i = 0;
93       for (ValidationException e : formError.getErrors())
94       {
95         messages[i++] = String.format("%s: %s,", e.getField().getName(), e.getMessage());
96       }
97       j.setState(WsJob.JobState.INVALID);
98       j.setStatus(String.join(", ", messages));
99       return true;
100     }
101     return false;
102   }
103
104   @Override
105   public boolean handleCollectionException(Exception e, WsJob msjob, WebserviceInfo wsInfo)
106   {
107     return false;
108   }
109
110   @Override
111   public JobId align(List<SequenceI> toalign, WsParamSetI parameters, List<ArgumentI> list) throws Throwable
112   {
113     StringBuilder builder = new StringBuilder();
114     for (SequenceI seq : toalign)
115     {
116       builder.append(">").append(seq.getName()).append("\n");
117       builder.append(seq.getSequence()).append("\n");
118     }
119     InputStream stream = new ByteArrayInputStream(builder.toString().getBytes());
120     RemoteFile file = client.uploadFile(stream, "input.fasta", "application/fasta");
121     SlivkaForm form = service.getForm();
122     HashMap<String, String> values = new HashMap<>(list != null ? list.size() : 0);
123     if (list != null)
124     {
125       for (ArgumentI arg : list)
126       {
127         values.put(arg.getName(), arg.getValue());
128       }
129     }
130     for (FormField field : form.getFields())
131     {
132       switch (field.getType()) {
133       case FILE:
134         form.insert(field.getName(), file);
135         break;
136       case BOOLEAN:
137         String value = values.get(field.getName());
138         form.insert(field.getName(), (value != null && !value.isBlank()) ? true : false);
139         break;
140       default:
141         form.insert(field.getName(), field.valueOf(values.get(field.getName())));
142       }
143     }
144     return new JobId(service.getName(), service.getName(), form.submit());
145   }
146
147   @Override
148   public AlignmentI getAlignmentFor(JobId jobId) throws InvalidArgumentException, ServerError, IOError
149   {
150     List<RemoteFile> files;
151     try
152     {
153       files = client.getJobResults(jobId.getJobId());
154       for (RemoteFile f : files)
155       {
156         if (f.getMimeType().equals("application/clustal"))
157         {
158           return new FormatAdapter().readFile(f.getURL().toString(), DataSourceType.URL, FileFormat.Clustal);
159         }
160         else if (f.getMimeType().equals("application/fasta"))
161         {
162           return new FormatAdapter().readFile(f.getURL().toString(), DataSourceType.URL, FileFormat.Fasta);
163         }
164       }
165     } catch (IOException e)
166     {
167       throw new IOError(e);
168     }
169     return null;
170   }
171
172   @Override
173   public Object getEndpoint()
174   {
175     return this;
176   }
177
178   @Override
179   public void initParamStore(ParamManager userParameterStore)
180   {
181     if (store == null)
182     {
183       try
184       {
185         store = new SlivkaDatastore(service);
186       } catch (IOException e)
187       {
188         throw new IOError(e);
189       }
190     }
191   }
192
193   @Override
194   public boolean hasParameters()
195   {
196     return true;
197   }
198
199   @Override
200   public ParamDatastoreI getParamStore()
201   {
202     return store;
203   }
204 }