package jalview.ws.slivkaws;
-import jalview.datamodel.AlignmentView;
+import jalview.bin.Cache;
import jalview.gui.AlignFrame;
-import jalview.ws.WSMenuEntryProviderI;
-import jalview.ws.jws2.MsaWSClient;
+import jalview.ws.WSDiscovererI;
+import jalview.ws.api.ServiceWithParameters;
+import jalview.ws.jws2.PreferredServiceRegistry;
-import java.awt.event.ActionEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
import java.io.IOException;
-import java.net.URISyntaxException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
import javax.swing.JMenu;
-import javax.swing.JMenuItem;
import uk.ac.dundee.compbio.slivkaclient.SlivkaClient;
+import uk.ac.dundee.compbio.slivkaclient.SlivkaService;
-public class SlivkaWSDiscoverer
- implements Runnable, WSMenuEntryProviderI
+public class SlivkaWSDiscoverer implements WSDiscovererI
{
+ private static final String SLIVKA_HOST_URLS = "SLIVKAHOSTURLS";
+
+ private static final String COMPBIO_SLIVKA = "https://www.compbio.dundee.ac.uk/slivka/";
+
private static SlivkaWSDiscoverer instance = null;
- private SlivkaClient client;
- private ClustaloWS clustalo;
- private SlivkaWSDiscoverer() {
- try
- {
- client = new SlivkaClient("gjb-www-1.cluster.lifesci.dundee.ac.uk", 3203);
- } catch (URISyntaxException e)
- {
- throw new RuntimeException(e);
- }
- clustalo = new ClustaloWS(client);
+ private List<ServiceWithParameters> services = List.of();
+
+ private SlivkaWSDiscoverer()
+ {
}
public static SlivkaWSDiscoverer getInstance()
{
- if (instance == null) {
- instance = new SlivkaWSDiscoverer();
- }
+ if (instance == null)
+ {
+ instance = new SlivkaWSDiscoverer();
+ }
return instance;
}
+ private PropertyChangeSupport changeSupport = new PropertyChangeSupport(
+ this);
+
@Override
public void attachWSMenuEntry(JMenu wsmenu, final AlignFrame alignFrame)
{
- JMenu submenu = new JMenu("Slivka");
+ JMenu slivkaMenu = new JMenu("Slivka");
+ wsmenu.add(slivkaMenu);
- JMenuItem noParamMenuItem = new JMenuItem("ClustalO with defaults");
- noParamMenuItem.addActionListener((ActionEvent e) -> {
- AlignmentView msa = alignFrame.gatherSequencesForAlignment();
- if (msa != null)
- {
- new MsaWSClient(
- clustalo, alignFrame.getTitle(), msa, false, true,
- alignFrame.getViewport().getAlignment().getDataset(),
- alignFrame);
- }
- });
- submenu.add(noParamMenuItem);
+ JMenu alignmentMenu = new JMenu("Sequence Alignment");
+ slivkaMenu.add(alignmentMenu);
+ JMenu disorderMenu = new JMenu("Protein sequence analysis");
+ slivkaMenu.add(disorderMenu);
+ JMenu conservationMenu = new JMenu("Conservation");
+ slivkaMenu.add(conservationMenu);
+ PreferredServiceRegistry.getRegistry().populateWSMenuEntry(services,
+ changeSupport, slivkaMenu, alignFrame, null);
+
+ }
+
+ volatile boolean ready = false;
- JMenuItem parametrisedMenuItem = new JMenuItem("ClustalO with custom parameters");
- parametrisedMenuItem.addActionListener((ActionEvent evt) -> {
- AlignmentView msa = alignFrame.gatherSequencesForAlignment();
- if (msa != null)
+ volatile Thread discovererThread = null;
+
+ private class DiscovererThread extends Thread
+ {
+ private Thread oldThread;
+
+ DiscovererThread(Thread oldThread)
+ {
+ super();
+ this.oldThread = oldThread;
+ }
+
+ @Override
+ public void run()
+ {
+ if (oldThread != null)
{
+ oldThread.interrupt();
try
{
- SlivkaParamSet paramSet = new SlivkaParamSet(clustalo.getService());
- new MsaWSClient(
- clustalo, paramSet, null, true, alignFrame.getTitle(), msa, false, true,
- alignFrame.getViewport().getAlignment().getDataset(), alignFrame
- );
- } catch (IOException e)
+ oldThread.join();
+ } catch (InterruptedException e)
+ {
+ return;
+ } finally
+ {
+ oldThread = null;
+ }
+ }
+ ready = false;
+ reloadServices();
+ ready = !isInterrupted();
+ }
+ }
+
+ Thread discoverer = null;
+
+ @Override
+ public Thread startDiscoverer(PropertyChangeListener changeListener)
+ {
+ changeSupport.addPropertyChangeListener(changeListener);
+ ready = false;
+ (discovererThread = new DiscovererThread(discovererThread)).start();
+ return discovererThread;
+ }
+
+ private void reloadServices()
+ {
+ Cache.log.info("Reloading Slivka services");
+ changeSupport.firePropertyChange("services", services, List.of());
+ ArrayList<ServiceWithParameters> instances = new ArrayList<>();
+
+ for (String url : getServiceUrls())
+ {
+ Cache.log.info(url);
+ SlivkaClient client;
+ client = new SlivkaClient(url);
+ try
+ {
+ for (SlivkaService service : client.getServices())
{
- e.printStackTrace();
+ SlivkaWSInstance newinstance = null;
+ for (String classifier : service.classifiers)
+ {
+ if (classifier.contains("Multiple sequence alignment"))
+ {
+ newinstance = new SlivkaMsaServiceInstance(client, service);
+ }
+ if (classifier.contains("Protein sequence analysis")
+ && newinstance == null)
+ {
+ newinstance = new SlivkaAnnotationServiceInstance(client,
+ service, false);
+ }
+ if (classifier
+ .contains("Sequence alignment analysis (conservation)"))
+ {
+ newinstance = new SlivkaAnnotationServiceInstance(client,
+ service, true);
+ }
+ }
+ if (newinstance != null)
+ {
+ instances.add(newinstance);
+ }
}
+ } catch (IOException e)
+ {
+ continue;
+ }
+ }
+
+ services = instances;
+ changeSupport.firePropertyChange("services", List.of(), services);
+
+ Cache.log.info("Slivka services reloading finished");
+ }
+
+ @Override
+ public List<ServiceWithParameters> getServices()
+ {
+ return services;
+ }
+
+ @Override
+ public boolean hasServices()
+ {
+ return ready == true && services.size() > 0;
+ }
+
+ @Override
+ public boolean isRunning()
+ {
+ return discovererThread == null || discovererThread.isAlive()
+ || discovererThread.getState() == Thread.State.NEW;
+ }
+
+ @Override
+ public void setServiceUrls(List<String> wsUrls)
+ {
+ if (wsUrls != null && !wsUrls.isEmpty())
+ {
+ Cache.setProperty(SLIVKA_HOST_URLS, String.join(",", wsUrls));
+ }
+ else
+ {
+ Cache.removeProperty(SLIVKA_HOST_URLS);
+ }
+ }
+
+ @Override
+ public List<String> getServiceUrls()
+ {
+ String surls = Cache.getDefault(SLIVKA_HOST_URLS, COMPBIO_SLIVKA);
+ String[] urls = surls.split(",");
+ ArrayList<String> valid = new ArrayList<>(urls.length);
+ for (String url : urls)
+ {
+ try
+ {
+ new URL(url);
+ valid.add(url);
+ } catch (MalformedURLException e)
+ {
+ Cache.log.warn("Problem whilst trying to make a URL from '"
+ + ((url != null) ? url : "<null>") + "'");
+ Cache.log.warn(
+ "This was probably due to a malformed comma separated list"
+ + " in the " + SLIVKA_HOST_URLS
+ + " entry of $(HOME)/.jalview_properties)");
+ Cache.log.debug("Exception was ", e);
}
- });
- submenu.add(parametrisedMenuItem);
+ }
+ return valid;
+ }
- wsmenu.add(submenu);
+ @Override
+ public boolean testServiceUrl(URL url)
+ {
+ return getServerStatusFor(url.toString()) == STATUS_OK;
}
@Override
- public void run()
+ public int getServerStatusFor(String url)
{
+ try
+ {
+ List<?> services = new SlivkaClient(url).getServices();
+ return services.isEmpty() ? STATUS_NO_SERVICES : STATUS_OK;
+ } catch (IOException e)
+ {
+ Cache.log.error("Slivka could not retrieve services list", e);
+ return STATUS_INVALID;
+ }
+ }
+ @Override
+ public String getErrorMessages()
+ {
+ // TODO Auto-generated method stub
+ return "";
}
}