--- /dev/null
+package jalview.ws2.client.jpred4;
+
+import java.io.IOException;
+import java.util.List;
+
+import jalview.datamodel.SequenceI;
+import jalview.io.AlignFile;
+import jalview.io.DataSourceType;
+import jalview.io.FastaFile;
+import jalview.io.FileFormat;
+import jalview.io.FormatAdapter;
+import jalview.io.JPredFile;
+import jalview.ws.params.ArgumentI;
+import jalview.ws2.api.Credentials;
+import jalview.ws2.api.JobStatus;
+import jalview.ws2.api.WebServiceJobHandle;
+import jalview.ws2.client.api.SecStructPredWebServiceClientI;
+import uk.ac.dundee.compbio.jpred.JPredClient;
+import uk.ac.dundee.compbio.jpred.JPredRequest;
+import uk.ac.dundee.compbio.jpred.ResultTypes;
+
+public class JPred4WSClient implements SecStructPredWebServiceClientI
+{
+ final JPredClient client;
+
+ private final JPredRequest.Mode mode;
+
+ private final JPredRequest.Format format;
+
+ JPred4WSClient(JPredClient client, boolean msaMode)
+ {
+ this.mode = msaMode ? JPredRequest.Mode.MSA : JPredRequest.Mode.SINGLE;
+ this.format = msaMode ? JPredRequest.Format.FASTA : JPredRequest.Format.SEQ;
+ this.client = client;
+ }
+
+ @Override
+ public String getUrl()
+ {
+ return client.getURL().toString();
+ }
+
+ @Override
+ public String getClientName()
+ {
+ return "jpred4";
+ }
+
+ @Override
+ public WebServiceJobHandle submit(List<SequenceI> sequences,
+ List<ArgumentI> args, Credentials credentials) throws IOException
+ {
+ var input = mode == JPredRequest.Mode.MSA
+ ? FileFormat.Fasta
+ .getWriter(null)
+ .print(sequences.toArray(new SequenceI[sequences.size()]), false)
+ : sequences.get(0).getSequenceAsString();
+
+ JPredRequest request = JPredRequest
+ .newBuilder()
+ .mode(mode)
+ .format(format)
+ .input(input)
+ .build();
+ var jobId = client.submit(request);
+ return new WebServiceJobHandle(getClientName(), "jpred4", getUrl(), jobId);
+ }
+
+ @Override
+ public JobStatus getStatus(WebServiceJobHandle job) throws IOException
+ {
+ var status = client.getStatus(job.getJobId());
+ switch (status)
+ {
+ case PENDING:
+ return JobStatus.QUEUED;
+ case RUNNING:
+ return JobStatus.RUNNING;
+ case FINISHED:
+ return JobStatus.COMPLETED;
+ case NO_JOB:
+ return JobStatus.SERVER_ERROR;
+ case MALFORMED:
+ return JobStatus.INVALID;
+ case NOT_EXIST:
+ return JobStatus.SERVER_ERROR;
+ default:
+ return JobStatus.UNKNOWN;
+ }
+ }
+
+ @Override
+ public String getLog(WebServiceJobHandle job) throws IOException
+ {
+ var stream = client.getResultStream(job.getJobId(), ResultTypes.LOG);
+ // FIXME: potential OOM
+ return new String(stream.readAllBytes());
+ }
+
+ @Override
+ public String getErrorLog(WebServiceJobHandle job) throws IOException
+ {
+ return "";
+ }
+
+ @Override
+ public void cancel(WebServiceJobHandle job)
+ throws IOException, UnsupportedOperationException
+ {
+
+ }
+
+ @Override
+ public AlignFile getAlignmentFile(WebServiceJobHandle job) throws IOException
+ {
+ var url = client.getResultURL(job.getJobId(), ResultTypes.PSIBLAST_ALIGN);
+ return new FastaFile(url.toString(), DataSourceType.URL);
+ }
+
+ @Override
+ public JPredFile getPredictionFile(WebServiceJobHandle job) throws IOException
+ {
+ var url = client.getResultURL(job.getJobId(), ResultTypes.CONCISE);
+ return new JPredFile(url.toString(), DataSourceType.URL);
+ }
+}