1 package jalview.ws2.slivka;
3 import java.io.IOException;
4 import java.net.MalformedURLException;
7 import java.util.concurrent.*;
9 import jalview.bin.Cache;
11 import jalview.ws2.operations.AlignmentOperation;
12 import jalview.ws2.operations.Operation;
13 import uk.ac.dundee.compbio.slivkaclient.SlivkaClient;
14 import uk.ac.dundee.compbio.slivkaclient.SlivkaService;
16 public class SlivkaWSDiscoverer implements WebServiceDiscoverer
18 private static final String SLIVKA_HOST_URLS = "SLIVKSHOSTURLS";
20 private static final String DEFAULT_URL = "https://www.compbio.dundee.ac.uk/slivka/";
22 private static SlivkaWSDiscoverer instance = null;
24 private List<WebServiceI> services = List.of();
26 private SlivkaWSDiscoverer()
30 public static SlivkaWSDiscoverer getInstance()
34 instance = new SlivkaWSDiscoverer();
40 public List<String> getUrls() {
41 String surls = Cache.getDefault(SLIVKA_HOST_URLS, DEFAULT_URL);
42 String urls[] = surls.split(",");
43 ArrayList<String> valid = new ArrayList<>(urls.length);
44 for (String url : urls)
51 catch (MalformedURLException e)
53 Cache.log.warn("Problem whilst trying to make a URL from '" +
54 Objects.toString(url, "<null>") + "'. " +
55 "This was probably due to malformed comma-separated-list " +
56 "in the " + SLIVKA_HOST_URLS + " entry of ${HOME}/.jalview_properties");
57 Cache.log.debug("Exception occurred while reading url list", e);
64 public void setUrls(List<String> wsUrls) {
65 if (wsUrls != null && !wsUrls.isEmpty())
67 Cache.setProperty(SLIVKA_HOST_URLS, String.join(",", wsUrls));
70 Cache.removeProperty(SLIVKA_HOST_URLS);
75 public boolean testUrl(URL url) {
76 return getStatusForUrl(url.toString()) == STATUS_OK;
80 public int getStatusForUrl(String url) {
83 List<?> services = new SlivkaClient(url).getServices();
84 return services.isEmpty() ? STATUS_NO_SERVICES : STATUS_OK;
88 Cache.log.error("Slivka could not retrieve services list from " + url, e);
89 return STATUS_INVALID;
93 public List<WebServiceI> getServices() {
94 return Collections.unmodifiableList(services);
97 public boolean hasServices() {
98 return !isRunning() && services.size() > 0;
101 public boolean isRunning() {
102 for (Future<?> task : discoveryTasks) {
103 if (!task.isDone()) {
110 public boolean isDone() {
111 return !isRunning() && discoveryTasks.size() > 0;
114 private Vector<Future<?>> discoveryTasks = new Vector<>();
117 public CompletableFuture<WebServiceDiscoverer> startDiscoverer()
119 CompletableFuture<WebServiceDiscoverer> task = CompletableFuture
122 return SlivkaWSDiscoverer.this;
124 discoveryTasks.add(task);
128 private List<WebServiceI> reloadServices()
130 Cache.log.info("Reloading Slivka services");
131 fireServicesChanged(Collections.emptyList());
132 ArrayList<WebServiceI> allServices = new ArrayList<>();
133 for (String url : getUrls()) {
134 SlivkaClient client = new SlivkaClient(url);
135 List<SlivkaService> services;
137 services = client.getServices();
138 } catch (IOException e) {
139 Cache.log.error("Unable to fetch services from " + url, e);
142 for (SlivkaService service : services) {
143 SlivkaWebService instance = new SlivkaWebService(client, service, service.getName());
144 for (String classifier : service.classifiers)
146 String[] path = classifier.split("\\s*::\\s*");
147 if (path.length >= 3 && path[0].toLowerCase().equals("operation")
148 && path[1].toLowerCase().equals("analysis"))
151 switch (path[path.length - 1].toLowerCase()) {
152 case "multiple sequence alignment":
153 op = new AlignmentOperation(instance, instance::getAlignment);
156 instance.addOperation(op);
159 if (instance.operations.size() > 0) {
160 allServices.add(instance);
164 this.services = allServices;
165 Cache.log.info("Reloading slivka services finished");
166 fireServicesChanged(getServices());
171 public String getErrorMessages() {