Allow for frame insets
[jalview.git] / src / jalview / ws / MsaWSClient.java
index 9626132..c159a94 100755 (executable)
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
 package jalview.ws;
 
-import org.apache.axis.client.*;
-import javax.xml.namespace.QName;
-import java.util.*;
-import jalview.datamodel.*;
-import jalview.gui.*;
-import javax.swing.*;
-import java.util.*;
-import java.awt.*;
-import jalview.analysis.AlignSeq;
 import ext.vamsas.*;
-import vamsas.objects.*;
 
+import jalview.datamodel.*;
 
+import jalview.gui.*;
 
+import javax.swing.*;
 
+/**
+ * DOCUMENT ME!
+ *
+ * @author $author$
+ * @version $Revision$
+ */
 public class MsaWSClient
     extends WSClient
 {
-    /**
-     * server is a WSDL2Java generated stub for an archetypal MsaWSI service.
-     */
-    ext.vamsas.MuscleWS server;
-
-  private boolean setWebService(String MsaWSName) {
-    if (MsaWServices.info.containsKey(MsaWSName)) {
-      WebServiceName = MsaWSName;
-      String[] wsinfo = (String[]) MsaWServices.info.get(MsaWSName);
-      WsURL = wsinfo[0];
-      WebServiceJobTitle = wsinfo[1];
-      WebServiceReference = wsinfo[2];
-      return true;
-    } else {
-      return false;
-    }
-  }
-
-
-  public MsaWSClient(String MsaWSName, String altitle, SequenceI[] msa, boolean submitGaps, boolean preserveOrder)
+  /**
+   * server is a WSDL2Java generated stub for an archetypal MsaWSI service.
+   */
+  ext.vamsas.MuscleWS server;
+  AlignFrame alignFrame;
+
+
+  /**
+   * Creates a new MsaWSClient object that uses a service
+   * given by an externally retrieved ServiceHandle
+   *
+   * @param sh service handle of type AbstractName(MsaWS)
+   * @param altitle DOCUMENT ME!
+   * @param msa DOCUMENT ME!
+   * @param submitGaps DOCUMENT ME!
+   * @param preserveOrder DOCUMENT ME!
+   */
+
+  public MsaWSClient(ext.vamsas.ServiceHandle sh, String altitle,
+                     jalview.datamodel.AlignmentView msa,
+                     boolean submitGaps, boolean preserveOrder,
+                     Alignment seqdataset,
+                     AlignFrame _alignFrame)
   {
-    if (setWebService(MsaWSName)==false) {
-      JOptionPane.showMessageDialog(Desktop.desktop, "The Multiple Sequence Alignment Service named "+MsaWSName+" is unknown",
-                                    "Internal Jalview Error", JOptionPane.WARNING_MESSAGE);
+    super();
+    alignFrame = _alignFrame;
+    if (!sh.getAbstractName().equals("MsaWS"))
+    {
+      JOptionPane.showMessageDialog(Desktop.desktop,
+                                    "The Service called \n" + sh.getName() +
+          "\nis not a \nMultiple Sequence Alignment Service !",
+                                    "Internal Jalview Error",
+                                    JOptionPane.WARNING_MESSAGE);
+
       return;
     }
 
-    wsInfo = new jalview.gui.WebserviceInfo(WebServiceJobTitle, WebServiceReference);
-
-    wsInfo.setProgressText(((submitGaps) ? "Re-alignment" : "Alignment")+" of "+altitle+"\nJob details\n");
+    if ((wsInfo = setWebService(sh))==null)
+     {
+       JOptionPane.showMessageDialog(Desktop.desktop,
+                                     "The Multiple Sequence Alignment Service named " +
+                                     sh.getName() +
+                                     " is unknown", "Internal Jalview Error",
+                                     JOptionPane.WARNING_MESSAGE);
 
-    // TODO: MuscleWS transmuted to generic MsaWS client
-    MuscleWSServiceLocator loc = new MuscleWSServiceLocator(); // Default
-    try {
-      this.server = (MuscleWS) loc.getMuscleWS(new java.net.URL(WsURL));
-    }
-    catch (Exception ex) {
-      wsInfo.setProgressText("Serious! "+WebServiceName+" Service location failed\nfor URL :"
-                     +WsURL+"\n"+ex.getMessage());
-      wsInfo.setStatus(wsInfo.ERROR);
-      ex.printStackTrace();
-    }
+       return;
+     }
+    startMsaWSClient(altitle, msa, submitGaps, preserveOrder, seqdataset);
 
-    MsaWSThread musclethread = new MsaWSThread(WebServiceName+" alignment of "+altitle, msa, submitGaps, preserveOrder);
-    wsInfo.setthisService(musclethread);
-    musclethread.start();
   }
 
 
-  protected class MsaWSThread extends Thread implements WSClientI
+  private void startMsaWSClient(String altitle, AlignmentView msa,
+                     boolean submitGaps, boolean preserveOrder, Alignment seqdataset)
   {
-    String ServiceName = WebServiceName;
-
-    public boolean isCancellable()
-    {
-      return true;
-    }
-
-    String OutputHeader;
-    vamsas.objects.simple.MsaResult result = null;
-
-    vamsas.objects.simple.SequenceSet seqs = new vamsas.objects.simple.
-        SequenceSet();
-
-    Hashtable SeqNames = null;
-    boolean submitGaps = false,// default is to strip gaps from sequences
-        preserveOrder = true; // and always store and recover sequence order
-
-    String jobId;
-    String alTitle; // name which will be used to form new alignment window.
-    int allowedServerExceptions = 3; // thread dies if too many exceptions.
-    MsaWSThread(String title, SequenceI[] msa, boolean subgaps, boolean presorder)
+    if (!locateWebService())
     {
-      alTitle = title;
-      submitGaps = subgaps;
-      preserveOrder = presorder;
-
-      OutputHeader = wsInfo.getProgressText();
-      SeqNames = new Hashtable();
-      vamsas.objects.simple.Sequence[] seqarray = new vamsas.objects.simple.
-          Sequence[msa.length];
-
-      for (int i = 0; i < msa.length; i++)
-      {
-        String newname = jalview.analysis.SeqsetUtils.unique_name(i);
-        // uniquify as we go
-        // TODO: JBPNote: this is a ubiquitous transformation - set of jalview seq objects to vamsas sequences with name preservation
-        SeqNames.put(newname, jalview.analysis.SeqsetUtils.SeqCharacterHash(msa[i]));
-        seqarray[i] = new vamsas.objects.simple.Sequence();
-        seqarray[i].setId(newname);
-        seqarray[i].setSeq((submitGaps) ? msa[i].getSequence()
-                           : AlignSeq.extractGaps(jalview.util.Comparison.GapChars, msa[i].getSequence()));
-      }
-
-      this.seqs = new vamsas.objects.simple.SequenceSet();
-      this.seqs.setSeqs(seqarray);
+      return;
     }
 
-    boolean jobComplete = false;
-
-    public void cancelJob() {
-      if (!jobComplete) {
-        String cancelledMessage="";
-        try {
-          vamsas.objects.simple.WsJobId cancelledJob = server.cancel(jobId);
-          if (cancelledJob.getStatus() == 2)
-          {
-            // CANCELLED_JOB
-            cancelledMessage = "Job cancelled.";
-            wsInfo.setStatus(WebserviceInfo.STATE_CANCELLED_OK);
-            jobComplete = true;
-            jobsRunning--;
-            result = null;
-          }
-          else
-          if (cancelledJob.getStatus() == 3)
-          {
-            // VALID UNSTOPPABLE JOB
-            cancelledMessage +=
-                "Server cannot cancel this job. just close the window.\n";
-          }
-          if (cancelledJob.getJobId() != null)
-            cancelledMessage += "[" + cancelledJob.getJobId() + "]";
-          cancelledMessage +="\n";
-        } catch (Exception exc) {
-          cancelledMessage +="\nProblems cancelling the job : Exception received...\n"+exc+"\n";
-          exc.printStackTrace();
+    wsInfo.setProgressText( ( (submitGaps) ? "Re-alignment" : "Alignment") +
+                           " of " + altitle + "\nJob details\n");
+    String jobtitle = WebServiceName.toLowerCase();
+    if (jobtitle.endsWith("alignment")) {
+        if (submitGaps
+                && (!jobtitle.endsWith("realignment")
+                ||   jobtitle.indexOf("profile")==-1)) {
+            int pos=jobtitle.indexOf("alignment");
+            jobtitle = WebServiceName.substring(0, pos) + "re-alignment of "+altitle;
+        } else {
+            jobtitle = WebServiceName+" of "+altitle;
         }
-        wsInfo.setProgressText(OutputHeader + cancelledMessage+"\n");
-      }
+    } else {
+        jobtitle = WebServiceName+(submitGaps? " re" : " ") +"alignment of "+altitle;
     }
 
-    public void run()
-    {
-
-      StartJob();
-
-      while (!jobComplete && (allowedServerExceptions > 0))
-      {
-        try
-        {
-          result = server.getResult(jobId);
+    MsaWSThread msathread = new MsaWSThread(server, WsURL, wsInfo, alignFrame,
+                                               WebServiceName,
+                                               jobtitle,
+                                               msa,
+                                               submitGaps, preserveOrder, seqdataset);
+    wsInfo.setthisService(msathread);
+    msathread.start();
+  }
 
-          if (result.isRunning())
-            wsInfo.setStatus(WebserviceInfo.STATE_RUNNING);
-          else if (result.isQueued())
-            wsInfo.setStatus(WebserviceInfo.STATE_QUEUING);
+  /**
+   * Initializes the server field with a valid service implementation.
+   *
+   * @return true if service was located.
+   */
+  private boolean locateWebService()
+  {
+    // TODO: MuscleWS transmuted to generic MsaWS client
+    MuscleWSServiceLocator loc = new MuscleWSServiceLocator(); // Default
 
-          if (result.isFinished())
-          {
-            parseResult();
-            jobComplete = true;
-            jobsRunning--;
-          }
-          else
-          {
-            if (result.getStatus() != null)
-              wsInfo.setProgressText(OutputHeader + "\n" + result.getStatus());
-            if (! (result.isJobFailed() || result.isServerError()))
-            {
-              Thread.sleep(5000);
-              //  System.out.println("I'm alive "+seqid+" "+jobid);
-            }
-            else
-            {
-              break;
-            }
-          }
-        }
-        catch (Exception ex)
-        {
-          allowedServerExceptions--;
-          wsInfo.appendProgressText("\n" + ServiceName + " Server exception!\n" +
-                                    ex.getMessage());
-          ex.printStackTrace();
-        }
-      }
-      if (allowedServerExceptions == 0)
-      {
-        wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);
-      }
-      else
-      {
-        if (! (result != null && (result.isJobFailed() || result.isServerError())))
-          wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_OK);
-        else
-        {
-          if (result.isFailed())
-            wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_ERROR);
-          if (result.isServerError())
-            wsInfo.setStatus(WebserviceInfo.STATE_STOPPED_SERVERERROR);
-        }
-      }
-    }
-    void StartJob()
+    try
     {
-      try
-      {
-        vamsas.objects.simple.WsJobId jobsubmit = server.align(seqs);
-        if (jobsubmit.getStatus()==1) {
-          jobId=jobsubmit.getJobId();
-          System.out.println(WsURL+" Job Id '"+jobId+"'");
-        } else {
-          throw new Exception(jobsubmit.getJobId());
-        }
-      }
-      catch (Exception e)
-      {
-        System.err.println(ServiceName + " Client: Failed to submit the prediction\n" +
-                           e.toString() + "\n");
-        e.printStackTrace();
-      }
-    }
-
-    private void addFloatAnnotations(Alignment al, int[] gapmap, Vector values, String Symname, String Visname, float min, float max, int winLength) {
-
-      Annotation[] annotations = new Annotation[al.getWidth()];
-      for (int j = 0; j < values.size(); j++)
-      {
-        float value = Float.parseFloat(values.get(j).toString());
-        annotations[gapmap[j]] = new Annotation("", value+"",' ',value);
-      }
-      al.addAnnotation(new AlignmentAnnotation(Symname, Visname, annotations, min, max, winLength));
-    }
-    private jalview.datamodel.Sequence[] getVamsasAlignment(vamsas.objects.simple.Alignment valign) {
-      vamsas.objects.simple.Sequence[] seqs = valign.getSeqs().getSeqs();
-      jalview.datamodel.Sequence[] msa = new jalview.datamodel.Sequence[seqs.length];
-      for (int i=0, j=seqs.length; i<j;i++)
-        msa[i] = new jalview.datamodel.Sequence(seqs[i].getId(), seqs[i].getSeq());
-      return msa;
+      this.server = (MuscleWS) loc.getMuscleWS(new java.net.URL(WsURL));
+      ( (MuscleWSSoapBindingStub)this.server).setTimeout(60000); // One minute timeout
     }
-    void parseResult()
+    catch (Exception ex)
     {
-      SequenceI[] seqs=null;
-      try {
-        // OutputHeader = output.getText();
-        if (result.isFailed()) {
-          OutputHeader +="Job failed.\n";
-        }
-        if (result.getStatus()!=null) {
-          OutputHeader += "\n"+result.getStatus();
-        }
-        if (result.getMsa()!=null) {
-          OutputHeader += "\nAlignment Object Method Notes\n";
-          String lines[] = result.getMsa().getMethod();
-          for (int line=0;line<lines.length; line++)
-            OutputHeader+=lines[line]+"\n";
-
-          // JBPNote The returned files from a webservice could be hidden behind icons in the monitor window that, when clicked, pop up their corresponding data
-          seqs = getVamsasAlignment(result.getMsa());
-        }
-
-        wsInfo.setProgressText(OutputHeader);
-        if (seqs!=null) {
-          AlignmentOrder msaorder = new AlignmentOrder(seqs);
-
-          if (preserveOrder) {
-            jalview.analysis.AlignmentSorter.recoverOrder(seqs);
-          }
-
-          jalview.analysis.SeqsetUtils.deuniquify(SeqNames, seqs);
+      wsInfo.setProgressText("Serious! " + WebServiceName +
+                             " Service location failed\nfor URL :" + WsURL +
+                             "\n" +
+                             ex.getMessage());
+      wsInfo.setStatus(WebserviceInfo.ERROR);
+      ex.printStackTrace();
 
-          Alignment al = new Alignment(seqs);
+      return false;
+    }
 
-          // TODO: JBPNote Should also rename the query sequence sometime...
-          AlignFrame af = new AlignFrame(al);
-          af.addSortByOrderMenuItem(ServiceName+" Ordering", msaorder);
+    loc.getEngine().setOption("axis", "1");
 
-          Desktop.addInternalFrame(af,
-                                   alTitle,
-                                   AlignFrame.NEW_WINDOW_WIDTH,
-                                   AlignFrame.NEW_WINDOW_HEIGHT);
-        }
-      }catch(Exception ex){ex.printStackTrace();}
+    return true;
+  }
 
-    }
+  protected String getServiceActionKey()
+  {
+    return "MsaWS";
+  }
 
+  protected String getServiceActionDescription()
+  {
+    return "Multiple Sequence Alignment";
   }
 }
-
-