Set job title correctly and pass reason why
authorjprocter <jprocter@compbio.dundee.ac.uk>
Thu, 7 Jul 2011 10:15:13 +0000 (11:15 +0100)
committerjprocter <jprocter@compbio.dundee.ac.uk>
Thu, 7 Jul 2011 10:15:13 +0000 (11:15 +0100)
input is invalid back to user (JAL-724, JAL-715)

src/jalview/ws/rest/RestClient.java
src/jalview/ws/rest/RestJob.java
src/jalview/ws/rest/RestJobThread.java
src/jalview/ws/rest/params/SeqGroupIndexVector.java

index 37add58..606d927 100644 (file)
@@ -196,10 +196,14 @@ public class RestClient extends WSClient implements WSClientI,
    */
   jalview.io.packed.JalviewDataset jds;
 
+  /**
+   * informative name for results
+   */
+  public String viewTitle;
+
   protected void constructJob()
   {
     service.setInvolvesFlags();
-    
     // record all aspects of alignment view so we can merge back or recreate
     // later
     undoredo = av.getUndoRedoHash();
@@ -210,7 +214,7 @@ public class RestClient extends WSClient implements WSClientI,
      */
     boolean selExists = (av.getSelectionGroup() != null)
             && (av.getSelectionGroup().getSize() > 1);
-    // TODO: revise to full focus+context+dataset input data staging model
+    // TODO: JAL-715: refactor to alignViewport methods and revise to full focus+context+dataset input data staging model
     if (selExists)
     {
       if (service.partitiondata)
@@ -224,6 +228,7 @@ public class RestClient extends WSClient implements WSClientI,
                   av.hasHiddenColumns(), 
                   true, 
                   true);
+          viewTitle = "selected "+(av.hasHiddenColumns() ? "visible" : "") + " region of "+af.getTitle();
         }
         else
         {
@@ -235,7 +240,7 @@ public class RestClient extends WSClient implements WSClientI,
                   false, 
                   true);
         }
-        // TODO: verify that some kind of partition can be constructed from input
+        viewTitle = "select and unselected "+(av.hasHiddenColumns() ? "visible" : "") + " regions from "+af.getTitle();
       }
       else
       {
@@ -246,6 +251,7 @@ public class RestClient extends WSClient implements WSClientI,
                 av.hasHiddenColumns(), 
                 true, 
                 true);
+        viewTitle = "selected "+(av.hasHiddenColumns() ? "visible" : "") + " region of "+af.getTitle();
       }
     } else {
       // standard alignment view without selection present
@@ -255,6 +261,7 @@ public class RestClient extends WSClient implements WSClientI,
               av.hasHiddenColumns(), 
               false, 
               true);
+      viewTitle = ""+(av.hasHiddenColumns() ? "visible region of " : "") + af.getTitle();
     }
     
     RestJobThread jobsthread = new RestJobThread(this);
@@ -270,14 +277,14 @@ public class RestClient extends WSClient implements WSClientI,
     {
       // TODO: try to tell the user why the job couldn't be started.
       JOptionPane.showMessageDialog(Desktop.desktop,
-              "Unable to start web service analysis",
-              "Internal Jalview Error", JOptionPane.WARNING_MESSAGE);
+              (jobsthread.hasWarnings() ? jobsthread.getWarnings() : "The Job couldn't be started. Please check your input, and the Jalview console for any warning messages."),
+              "Unable to start web service analysis", JOptionPane.WARNING_MESSAGE);
     }
   }
 
   public static RestClient makeShmmrRestClient()
   {
-    String action = "Analyse", description = "Sequence Harmony and Multi-Relief (UNSTABLE!)", name = "Sequence Harmony";
+    String action = "Analysis", description = "Sequence Harmony and Multi-Relief (UNSTABLE!)", name = "Sequence Harmony";
     Hashtable<String, InputType> iparams = new Hashtable<String, InputType>();
     jalview.ws.rest.params.JobConstant toolp;
     //toolp = new jalview.ws.rest.JobConstant("tool","jalview");
@@ -298,7 +305,8 @@ public class RestClient extends WSClient implements WSClientI,
     //aliinput.writeAsFile=true;
     iparams.put(aliinput.token, aliinput);
     jalview.ws.rest.params.SeqGroupIndexVector sgroups = new jalview.ws.rest.params.SeqGroupIndexVector();
-    sgroups.minsize=2;
+    sgroups.setMinsize(2);
+    sgroups.min=2;// need at least two group defined to make a partition
     iparams.put("groups", sgroups);
     sgroups.token = "groups";
     sgroups.sep = " ";
index 82b157d..e04a681 100644 (file)
@@ -100,9 +100,11 @@ public class RestJob extends AWsJob
           // TODO: move validation of input data to SeqGroupIndexVector
           if ((prm.getValue() instanceof SeqGroupIndexVector)
                   && (_input.getGroups() != null && _input.getGroups()
-                          .size() > 0))
+                          .size() >= prm.getValue().min))
           {
             alinp.add(prm.getValue());
+          } else {
+            statMessage=("Not enough groups defined on the alignment - need at least "+prm.getValue().min);
           }
         }
       }
index 39f26ae..799c7b4 100644 (file)
@@ -177,6 +177,7 @@ public class RestJobThread extends AWSThread
   {
     String postUrl = rj.getPostUrl();
     doHttpReq(Stage.SUBMIT, rj, postUrl);
+    wsInfo.invalidate();
   }
 
   /**
@@ -404,7 +405,16 @@ public class RestJobThread extends AWSThread
     {
       System.err.println("Debug RestJob: Posting Job");
       doPost((RestJob) job);
-    } catch (Exception ex)
+    }
+    catch (NoValidInputDataException erex)
+    {
+      job.setSubjobComplete(true);
+      job.setSubmitted(true);
+      ((RestJob)job).statMessage="<br>It looks like there was a problem with the data sent to the service :<br>"+erex.getMessage()+"\n";
+      ((RestJob)job).error=true;
+      
+    }
+    catch (Exception ex)
     {
       job.setSubjobComplete(true);
       job.setAllowedServerExceptions(-1);
@@ -459,7 +469,8 @@ public class RestJobThread extends AWSThread
        */
       if (true)
       {
-        wsInfo.setViewResultsImmediatly(false);
+        // preserver current jalview behaviour
+        wsInfo.setViewResultsImmediatly(true);
       }
       else
       {
@@ -495,6 +506,8 @@ public class RestJobThread extends AWSThread
     else
     {
       // tell the user nothing was returned.
+      wsInfo.setStatus(wsInfo.STATE_STOPPED_ERROR);
+      wsInfo.setFinishedNoResults();
     }
   }
 
@@ -985,8 +998,7 @@ public class RestJobThread extends AWSThread
       AlignmentI destal;
       ColumnSelection destcs;
       String alTitle = restClient.service.details.Action + " using "
-              + restClient.service.details.Name + " on "
-              + " whatever you clicked on." + "(set " + als + ")";
+              + restClient.service.details.Name + " on "+restClient.viewTitle;
       switch (action)
       {
       case newAlignment:
@@ -1014,12 +1026,13 @@ public class RestJobThread extends AWSThread
          * i++) { af.addSortByOrderMenuItem( WebServiceName + ((String)
          * names.get(i)) + " Ordering", (AlignmentOrder) alorders.get(i)); } } }
          */
+        // TODO: modify this and previous alignment's title if many alignments have been returned.
         Desktop.addInternalFrame(destaf, alTitle, AlignFrame.DEFAULT_WIDTH,
                 AlignFrame.DEFAULT_HEIGHT);
 
         break;
       case newView:
-
+        // TODO: determine title for view
         break;
       case currentView:
         break;
@@ -1193,6 +1206,8 @@ public class RestJobThread extends AWSThread
    */
   public boolean isValid()
   {
+    ArrayList<String> _warnings=new ArrayList<String>();
+    boolean validt=true;
     if (jobs != null)
     {
       for (RestJob rj : (RestJob[]) jobs)
@@ -1201,14 +1216,42 @@ public class RestJobThread extends AWSThread
         {
           // invalid input for this job
           System.err.println("Job " + rj.getJobnum()
-                  + " has invalid input.");
-          return false;
+                  + " has invalid input. ( "+rj.getStatus()+")");
+          if (rj.hasStatus() && !_warnings.contains(rj.getStatus()))
+          {
+            _warnings.add(rj.getStatus());
+          }
+          validt=false;
+        }
+      }
+    }
+    if (!validt)
+    {
+      warnings = "";
+      for (String st : _warnings) {
+        if (warnings.length()>0) { warnings+="\n";
         }
+        warnings += st;
+        
       }
-      return true;
     }
+    return validt;
+  }
+
+  protected String warnings;
+  public boolean hasWarnings()
+  {
     // TODO Auto-generated method stub
-    return false;
+    return warnings!=null && warnings.length()>0;
+  }
+
+  /**
+   * get any informative messages about why the job thread couldn't start.
+   * @return
+   */
+  public String getWarnings()
+  {
+    return isValid() ? "Job can be started. No warnings." :  hasWarnings() ? warnings : "";
   }
 
 }
index 4e7026e..91b1fff 100644 (file)
@@ -68,6 +68,7 @@ public class SeqGroupIndexVector extends InputType implements
     // assume that alignment is properly ordered so groups form consecutive
     // blocks
     ArrayList<int[]> gl = new ArrayList<int[]>();
+    int p=0;
     for (SequenceGroup sg : (Vector<SequenceGroup>) al.getGroups())
     {
       if (sg.getSize()<minsize)
@@ -79,7 +80,7 @@ public class SeqGroupIndexVector extends InputType implements
       int[] se = null;
       for (SequenceI sq : sg.getSequencesInOrder(al))
       {
-        int p = al.findIndex(sq);
+        p = al.findIndex(sq);
         if (se == null)
         {
           se = new int[]
@@ -98,6 +99,41 @@ public class SeqGroupIndexVector extends InputType implements
         gl.add(se);
       }
     }
+    // are there any more sequences ungrouped that should be added as a single remaining group ? - these might be at the start or the end
+    if (gl.size()>0)
+    {
+      int[] tail=gl.get(0);
+      if (tail[0]>0) {
+        if (1+tail[0]>minsize)
+      {
+        gl.add(0,new int[] { 0,tail[0]-1});
+      } else {
+        // lets be intelligent here - if the remaining sequences aren't enough to make a final group, then don't make one.
+        // throw new NoValidInputDataException("Group from remaining ungrouped sequences in input contains less than "+minsize+" sequences.");       
+      }
+      } else {
+        tail=gl.get(gl.size()-1);
+        if (1+tail[1]<al.getHeight())
+        {
+          if (al.getHeight()-(1+tail[1])>minsize) {
+            gl.add(new int[] { tail[1]+1, al.getHeight()-1});            
+          } else {
+            // lets be intelligent here - if the remaining sequences aren't enough to make a final group, then don't make one.
+            //  throw new NoValidInputDataException("Group from remaining ungrouped sequences in input contains less than "+minsize+" sequences.");       
+          }
+        }
+      }
+    } else {
+      gl.add(new int[] { 0, al.getHeight()-1});
+    }
+    if (min>=0 && gl.size()<min)
+    {
+      throw new NoValidInputDataException("Not enough sequence groups for input. Need at least "+min+" groups (including ungrouped regions).");
+    }
+    if (max>0 && gl.size()>max)
+    {
+      throw new NoValidInputDataException("Too many sequence groups for input. Need at most "+max+" groups (including ungrouped regions).");
+    }
     int[][] vals = gl.toArray(new int[gl.size()][]);
     int[] srt = new int[gl.size()];
     for (int i = 0; i < vals.length; i++)
@@ -121,4 +157,17 @@ public class SeqGroupIndexVector extends InputType implements
     return new StringBody(idvector.toString());
   }
 
+  /**
+   * set minimum number of sequences allowed in a partition. Default is 1 sequence.
+   * @param i (number greater than 1)
+   */
+  public void setMinsize(int i)
+  {
+    if (minsize>=1)
+      {
+      minsize=i;
+      } else {
+        minsize=1;
+      }
+  }
 }
\ No newline at end of file