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