JAL-3878 Add RNAalifold service discovery.
[jalview.git] / src / jalview / ws2 / slivka / SlivkaWSDiscoverer.java
index fe5c040..ee3ddf9 100644 (file)
@@ -9,6 +9,7 @@ import java.util.concurrent.*;
 import jalview.bin.Cache;
 import jalview.ws2.*;
 import jalview.ws2.operations.AlignmentOperation;
+import jalview.ws2.operations.AnnotationOperation;
 import jalview.ws2.operations.Operation;
 import uk.ac.dundee.compbio.slivkaclient.SlivkaClient;
 import uk.ac.dundee.compbio.slivkaclient.SlivkaService;
@@ -21,7 +22,7 @@ public class SlivkaWSDiscoverer implements WebServiceDiscoverer
 
   private static SlivkaWSDiscoverer instance = null;
 
-  private List<WebServiceI> services = List.of();
+  private List<Operation> operations = List.of();
 
   private SlivkaWSDiscoverer()
   {
@@ -37,7 +38,8 @@ public class SlivkaWSDiscoverer implements WebServiceDiscoverer
   }
 
   @Override
-  public List<String> getUrls() {
+  public List<String> getUrls()
+  {
     String surls = Cache.getDefault(SLIVKA_HOST_URLS, DEFAULT_URL);
     String urls[] = surls.split(",");
     ArrayList<String> valid = new ArrayList<>(urls.length);
@@ -47,13 +49,13 @@ public class SlivkaWSDiscoverer implements WebServiceDiscoverer
       {
         new URL(url);
         valid.add(url);
-      }
-      catch (MalformedURLException e)
+      } catch (MalformedURLException e)
       {
-        Cache.log.warn("Problem whilst trying to make a URL from '" +
-                Objects.toString(url, "<null>") + "'. " +
-                "This was probably due to malformed comma-separated-list " +
-                "in the " + SLIVKA_HOST_URLS + " entry of ${HOME}/.jalview_properties");
+        Cache.log.warn("Problem whilst trying to make a URL from '"
+                + Objects.toString(url, "<null>") + "'. "
+                + "This was probably due to malformed comma-separated-list "
+                + "in the " + SLIVKA_HOST_URLS
+                + " entry of ${HOME}/.jalview_properties");
         Cache.log.debug("Exception occurred while reading url list", e);
       }
     }
@@ -61,53 +63,65 @@ public class SlivkaWSDiscoverer implements WebServiceDiscoverer
   }
 
   @Override
-  public void setUrls(List<String> wsUrls) {
+  public void setUrls(List<String> wsUrls)
+  {
     if (wsUrls != null && !wsUrls.isEmpty())
     {
       Cache.setProperty(SLIVKA_HOST_URLS, String.join(",", wsUrls));
     }
-    else {
+    else
+    {
       Cache.removeProperty(SLIVKA_HOST_URLS);
     }
   }
 
   @Override
-  public boolean testUrl(URL url) {
+  public boolean testUrl(URL url)
+  {
     return getStatusForUrl(url.toString()) == STATUS_OK;
   }
 
   @Override
-  public int getStatusForUrl(String url) {
+  public int getStatusForUrl(String url)
+  {
     try
     {
       List<?> services = new SlivkaClient(url).getServices();
       return services.isEmpty() ? STATUS_NO_SERVICES : STATUS_OK;
-    }
-    catch (IOException e)
+    } catch (IOException e)
     {
-      Cache.log.error("Slivka could not retrieve services list from " + url, e);
+      Cache.log.error("Slivka could not retrieve services list from " + url,
+              e);
       return STATUS_INVALID;
     }
   }
 
-  public List<WebServiceI> getServices() {
-    return Collections.unmodifiableList(services);
+  @Override
+  public List<Operation> getOperations()
+  {
+    return Collections.unmodifiableList(operations);
   }
 
-  public boolean hasServices() {
-    return !isRunning() && services.size() > 0;
+  @Override
+  public boolean hasServices()
+  {
+    return !isRunning() && operations.size() > 0;
   }
 
-  public boolean isRunning() {
-    for (Future<?> task : discoveryTasks) {
-      if (!task.isDone()) {
-        return false;
+  public boolean isRunning()
+  {
+    for (Future<?> task : discoveryTasks)
+    {
+      if (!task.isDone())
+      {
+        return true;
       }
     }
-    return true;
+    return false;
   }
 
-  public boolean isDone() {
+  public boolean isDone()
+  {
     return !isRunning() && discoveryTasks.size() > 0;
   }
 
@@ -121,54 +135,83 @@ public class SlivkaWSDiscoverer implements WebServiceDiscoverer
               reloadServices();
               return SlivkaWSDiscoverer.this;
             });
+    task.thenRun(() -> fireOperationsChanged(getOperations()));
     discoveryTasks.add(task);
     return task;
   }
 
-  private List<WebServiceI> reloadServices()
+  private List<Operation> reloadServices()
   {
     Cache.log.info("Reloading Slivka services");
-    fireServicesChanged(Collections.emptyList());
-    ArrayList<WebServiceI> allServices = new ArrayList<>();
-    for (String url : getUrls()) {
+    fireOperationsChanged(Collections.emptyList());
+    ArrayList<Operation> allOperations= new ArrayList<>();
+    for (String url : getUrls())
+    {
       SlivkaClient client = new SlivkaClient(url);
       List<SlivkaService> services;
-      try {
+      try
+      {
         services = client.getServices();
-      } catch (IOException e) {
+      } catch (IOException e)
+      {
         Cache.log.error("Unable to fetch services from " + url, e);
         continue;
       }
-      for (SlivkaService service : services) {
-        SlivkaWebService instance = new SlivkaWebService(client, service, service.getName());
+      for (SlivkaService service : services)
+      {
+        SlivkaWebService instance = new SlivkaWebService(client, service);
+        Operation op = null;
         for (String classifier : service.classifiers)
         {
           String[] path = classifier.split("\\s*::\\s*");
           if (path.length >= 3 && path[0].toLowerCase().equals("operation")
                   && path[1].toLowerCase().equals("analysis"))
           {
-            Operation op = null;
-            switch (path[path.length - 1].toLowerCase()) {
+            switch (path[path.length - 1].toLowerCase())
+            {
+            case "rna secondary structure prediction":
+              AnnotationOperation anop;
+              op = anop = new AnnotationOperation(instance,
+                  instance::getAnnotations, instance::getFeaturesFile,
+                  "Secondary Structure Prediction");
+              anop.setInteractive(true);
+              anop.setAlignmentAnalysis(true);
+              anop.setProteinOperation(false);
+              break;
+            case "sequence alignment analysis (conservation)":
+              op = anop = new AnnotationOperation(instance,
+                  instance::getAnnotations, instance::getFeaturesFile,
+                  "Conservation");
+              anop.setAlignmentAnalysis(true);
+              anop.setInteractive(true);
+              break;
+            case "protein sequence analysis":
+              op = new AnnotationOperation(instance, instance::getAnnotations,
+                  instance::getFeaturesFile, "Protein Disorder");
+              break;
             case "multiple sequence alignment":
               op = new AlignmentOperation(instance, instance::getAlignment);
+              break;
             }
             if (op != null)
-              instance.addOperation(op);
+            {
+              break;
+            }
           }
         }
-        if (instance.operations.size() > 0) {
-          allServices.add(instance);
+        if (op != null) {
+          allOperations.add(op);
         }
       }
     }
-    this.services = allServices;
+    this.operations = allOperations;
     Cache.log.info("Reloading slivka services finished");
-    fireServicesChanged(getServices());
-    return allServices;
+    return allOperations;
   }
 
   @Override
-  public String getErrorMessages() {
+  public String getErrorMessages()
+  {
     return "";
   }