1 package jalview.ws2.client.slivka;
3 import java.io.IOException;
4 import java.net.MalformedURLException;
5 import java.net.URISyntaxException;
7 import java.util.ArrayList;
10 import jalview.bin.Cache;
11 import jalview.ws.params.ParamManager;
12 import jalview.ws2.actions.alignment.AlignmentAction;
13 import jalview.ws2.actions.annotation.AnnotationAction;
14 import jalview.ws2.api.WebService;
15 import jalview.ws2.client.api.AbstractWebServiceDiscoverer;
16 import uk.ac.dundee.compbio.slivkaclient.SlivkaClient;
17 import uk.ac.dundee.compbio.slivkaclient.SlivkaService;
19 public class SlivkaWSDiscoverer extends AbstractWebServiceDiscoverer
21 private static final String SLIVKA_HOST_URLS = "SLIVKAHOSTURLS";
23 private static final URL DEFAULT_URL;
28 DEFAULT_URL = new URL("https://www.compbio.dundee.ac.uk/slivka/");
29 } catch (MalformedURLException e)
31 throw new AssertionError(e);
35 private static SlivkaWSDiscoverer instance = null;
37 private static ParamManager paramManager = null;
39 private SlivkaWSDiscoverer()
43 public static SlivkaWSDiscoverer getInstance()
46 instance = new SlivkaWSDiscoverer();
50 public static void setParamManager(ParamManager manager)
52 paramManager = manager;
56 public int getStatusForUrl(URL url)
60 List<?> services = new SlivkaClient(url.toString()).getServices();
61 return services.isEmpty() ? STATUS_NO_SERVICES : STATUS_OK;
62 } catch (IOException e)
64 Cache.log.error("slivka could not retrieve services from " + url, e);
65 return STATUS_INVALID;
70 protected String getUrlsPropertyKey()
72 return SLIVKA_HOST_URLS;
76 protected URL getDefaultUrl()
82 protected List<WebService<?>> fetchServices(URL url) throws IOException
84 ArrayList<WebService<?>> allServices = new ArrayList<>();
85 SlivkaClient slivkaClient;
88 slivkaClient = new SlivkaClient(url.toURI());
89 } catch (URISyntaxException e)
91 throw new MalformedURLException(e.getMessage());
93 for (var slivkaService : slivkaClient.getServices())
95 int serviceClass = getServiceClass(slivkaService);
96 if (serviceClass == SERVICE_CLASS_MSA)
98 var wsb = WebService.<AlignmentAction> newBuilder();
99 initServiceBuilder(slivkaService, wsb);
100 wsb.category("Alignment");
101 wsb.interactive(false);
102 wsb.actionClass(AlignmentAction.class);
103 var msaService = wsb.build();
105 boolean canRealign = msaService.getName().contains("lustal");
106 var client = new SlivkaAlignmentWSClient(slivkaService);
107 var actionBuilder = AlignmentAction.newBuilder(client);
108 actionBuilder.name("Alignment");
109 actionBuilder.webService(msaService);
111 actionBuilder.subcategory("Align");
112 actionBuilder.minSequences(2);
113 msaService.addAction(actionBuilder.build());
116 actionBuilder.name("Re-alignment");
117 actionBuilder.subcategory("Realign");
118 actionBuilder.submitGaps(true);
119 msaService.addAction(actionBuilder.build());
121 allServices.add(msaService);
123 else if (serviceClass == SERVICE_CLASS_PROT_SEQ_ANALYSIS)
125 var wsb = WebService.<AnnotationAction> newBuilder();
126 initServiceBuilder(slivkaService, wsb);
127 wsb.category("Protein Disorder");
128 wsb.interactive(false);
129 wsb.actionClass(AnnotationAction.class);
130 var psaService = wsb.build();
131 var client = new SlivkaAnnotationWSClient(slivkaService);
132 var actionBuilder = AnnotationAction.newBuilder(client);
133 actionBuilder.webService(psaService);
134 actionBuilder.name("Analysis");
135 psaService.addAction(actionBuilder.build());
136 allServices.add(psaService);
146 private void initServiceBuilder(SlivkaService service, WebService.Builder<?> wsBuilder)
150 wsBuilder.url(service.getUrl().toURL());
151 } catch (MalformedURLException e)
155 wsBuilder.clientName("slivka");
156 wsBuilder.name(service.getName());
157 wsBuilder.description(service.getDescription());
158 var storeBuilder = new SlivkaParamStoreFactory(service, paramManager);
159 wsBuilder.paramDatastore(storeBuilder.createParamDatastore());
162 static final int SERVICE_CLASS_UNSUPPORTED = -1;
164 static final int SERVICE_CLASS_MSA = 1;
166 static final int SERVICE_CLASS_RNA_SEC_STR_PRED = 2;
168 static final int SERVICE_CLASS_CONSERVATION = 3;
170 static final int SERVICE_CLASS_PROT_SEQ_ANALYSIS = 4;
172 static final int SERVICE_CLASS_PROT_SEC_STR_PRED = 5;
175 * Scan service classifiers starting with operation :: analysis to decide the
178 * @return service class flag
180 private static int getServiceClass(SlivkaService service)
182 for (String classifier : service.getClassifiers())
184 String[] path = classifier.split("\\s*::\\s*");
185 if (path.length < 3 || !path[0].equalsIgnoreCase("operation") ||
186 !path[1].equalsIgnoreCase("analysis"))
188 // classifier is operation :: analysis :: *
189 var tail = path[path.length - 1].toLowerCase();
192 case "multiple sequence alignment":
193 return SERVICE_CLASS_MSA;
194 case "rna secondary structure prediction":
195 return SERVICE_CLASS_RNA_SEC_STR_PRED;
196 case "sequence alignment analysis (conservation)":
197 return SERVICE_CLASS_CONSERVATION;
198 case "protein sequence analysis":
199 return SERVICE_CLASS_PROT_SEQ_ANALYSIS;
200 case "protein secondary structure prediction":
201 return SERVICE_CLASS_PROT_SEC_STR_PRED;
204 return SERVICE_CLASS_UNSUPPORTED;