1 package jalview.ws.slivkaws;
3 import jalview.bin.Cache;
4 import jalview.ws.ServiceChangeListener;
5 import jalview.ws.WSDiscovererI;
6 import jalview.ws.api.ServiceWithParameters;
7 import java.beans.PropertyChangeListener;
8 import java.io.IOException;
9 import java.net.MalformedURLException;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.List;
15 import java.util.Vector;
16 import java.util.concurrent.CompletableFuture;
17 import java.util.concurrent.CopyOnWriteArraySet;
18 import java.util.concurrent.ExecutorService;
19 import java.util.concurrent.Executors;
20 import java.util.concurrent.Future;
21 import java.util.concurrent.FutureTask;
23 import uk.ac.dundee.compbio.slivkaclient.SlivkaClient;
24 import uk.ac.dundee.compbio.slivkaclient.SlivkaService;
26 public class SlivkaWSDiscoverer implements WSDiscovererI
28 private static final String SLIVKA_HOST_URLS = "SLIVKAHOSTURLS";
30 private static final String COMPBIO_SLIVKA = "https://www.compbio.dundee.ac.uk/slivka/";
32 private static SlivkaWSDiscoverer instance = null;
34 private List<ServiceWithParameters> services = List.of();
36 private SlivkaWSDiscoverer()
40 public static SlivkaWSDiscoverer getInstance()
44 instance = new SlivkaWSDiscoverer();
49 private Set<ServiceChangeListener> serviceListeners = new CopyOnWriteArraySet<>();
52 public void addServiceChangeListener(ServiceChangeListener l)
54 serviceListeners.add(l);
58 public void removeServiceChangeListener(ServiceChangeListener l)
60 serviceListeners.remove(l);
63 public void notifyServiceListeners(List<ServiceWithParameters> services)
65 for (var listener : serviceListeners)
67 listener.servicesChanged(this, services);
71 private final ExecutorService executor = Executors.newSingleThreadExecutor();
72 private Vector<Future<?>> discoveryTasks = new Vector<>();
74 public CompletableFuture<WSDiscovererI> startDiscoverer()
76 CompletableFuture<WSDiscovererI> task = CompletableFuture
79 return SlivkaWSDiscoverer.this;
81 discoveryTasks.add(task);
85 private List<ServiceWithParameters> reloadServices()
87 Cache.log.info("Reloading Slivka services");
88 notifyServiceListeners(Collections.emptyList());
89 ArrayList<ServiceWithParameters> instances = new ArrayList<>();
91 for (String url : getServiceUrls())
95 client = new SlivkaClient(url);
98 for (SlivkaService service : client.getServices())
100 SlivkaWSInstance newinstance = null;
101 for (String classifier : service.classifiers)
103 if (classifier.contains("Multiple sequence alignment"))
105 newinstance = new SlivkaMsaServiceInstance(client, service);
107 if (classifier.contains("Protein sequence analysis")
108 && newinstance == null)
110 newinstance = new SlivkaAnnotationServiceInstance(client,
114 .contains("Sequence alignment analysis (conservation)"))
116 newinstance = new SlivkaAnnotationServiceInstance(client,
120 if (newinstance != null)
122 instances.add(newinstance);
125 } catch (IOException e)
132 services = instances;
133 notifyServiceListeners(instances);
134 Cache.log.info("Slivka services reloading finished");
139 public List<ServiceWithParameters> getServices()
145 public boolean hasServices()
147 return !isRunning() && services.size() > 0;
151 public boolean isRunning()
153 return !discoveryTasks.stream().allMatch(Future::isDone);
157 public void setServiceUrls(List<String> wsUrls)
159 if (wsUrls != null && !wsUrls.isEmpty())
161 Cache.setProperty(SLIVKA_HOST_URLS, String.join(",", wsUrls));
165 Cache.removeProperty(SLIVKA_HOST_URLS);
170 public List<String> getServiceUrls()
172 String surls = Cache.getDefault(SLIVKA_HOST_URLS, COMPBIO_SLIVKA);
173 String[] urls = surls.split(",");
174 ArrayList<String> valid = new ArrayList<>(urls.length);
175 for (String url : urls)
181 } catch (MalformedURLException e)
183 Cache.log.warn("Problem whilst trying to make a URL from '"
184 + ((url != null) ? url : "<null>") + "'");
186 "This was probably due to a malformed comma separated list"
187 + " in the " + SLIVKA_HOST_URLS
188 + " entry of $(HOME)/.jalview_properties)");
189 Cache.log.debug("Exception was ", e);
196 public boolean testServiceUrl(URL url)
198 return getServerStatusFor(url.toString()) == STATUS_OK;
202 public int getServerStatusFor(String url)
206 List<?> services = new SlivkaClient(url).getServices();
207 return services.isEmpty() ? STATUS_NO_SERVICES : STATUS_OK;
208 } catch (IOException e)
210 Cache.log.error("Slivka could not retrieve services list", e);
211 return STATUS_INVALID;
216 public String getErrorMessages()
218 // TODO Auto-generated method stub