refactored to propery separate addToDocument,addFromDocument, updateToDocument, updat...
[jalview.git] / src / jalview / ws / DBRefFetcher.java
index c2d7ad5..96ac7e8 100644 (file)
@@ -1,17 +1,17 @@
 /*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)\r
+ * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
+ * \r
  * This program is free software; you can redistribute it and/or\r
  * modify it under the terms of the GNU General Public License\r
  * as published by the Free Software Foundation; either version 2\r
  * of the License, or (at your option) any later version.\r
- *\r
+ * \r
  * This program is distributed in the hope that it will be useful,\r
  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
  * GNU General Public License for more details.\r
- *\r
+ * \r
  * You should have received a copy of the GNU General Public License\r
  * along with this program; if not, write to the Free Software\r
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
@@ -31,7 +31,8 @@ import jalview.ws.dbsources.Uniprot;
 import jalview.ws.ebi.EBIFetchClient;\r
 \r
 /**\r
- * DOCUMENT ME!\r
+ * Implements a runnable for validating a sequence against external databases\r
+ * and then propagating references and features onto the sequence(s)\r
  * \r
  * @author $author$\r
  * @version $Revision$\r
@@ -40,7 +41,7 @@ public class DBRefFetcher implements Runnable
 {\r
   SequenceI[] dataset;\r
 \r
-  AlignFrame af;\r
+  IProgressIndicator af;\r
 \r
   CutAndPasteTransfer output = new CutAndPasteTransfer();\r
 \r
@@ -80,7 +81,8 @@ public class DBRefFetcher implements Runnable
         ds[i] = seqs[i];\r
     }\r
     this.dataset = ds;\r
-    sfetcher = new SequenceFetcher();\r
+    // TODO Jalview 2.5 lots of this code should be in the gui package!\r
+    sfetcher = jalview.gui.SequenceFetcher.getSequenceFetcherSingleton(af);\r
     // select appropriate databases based on alignFrame context.\r
     if (af.getViewport().getAlignment().isNucleotide())\r
     {\r
@@ -192,6 +194,10 @@ public class DBRefFetcher implements Runnable
         maxqlen = ((Integer) dbsource.getDbSourceProperties().get(\r
                 DBRefSource.MULTIACC)).intValue();\r
       }\r
+      else\r
+      {\r
+        maxqlen = 1;\r
+      }\r
       // iterate through db for each remaining un-verified sequence\r
       SequenceI[] currSeqs = new SequenceI[sdataset.size()];\r
       sdataset.copyInto(currSeqs);// seqs that are to be validated against\r
@@ -207,31 +213,38 @@ public class DBRefFetcher implements Runnable
         {\r
           // Still queries to make for current seqIndex\r
           StringBuffer queryString = new StringBuffer("");\r
-          int nqSize = (maxqlen > queries.size()) ? queries.size()\r
+          int numq=0,nqSize = (maxqlen > queries.size()) ? queries.size()\r
                   : maxqlen;\r
-          for (int nq = 0, numq = 0; nq < nqSize; nq++)\r
+          \r
+          while (queries.size()>0 && numq < nqSize)\r
           {\r
-            String query = (String) queries.elementAt(nq);\r
+            String query = (String) queries.elementAt(0);\r
             if (dbsource.isValidReference(query))\r
             {\r
-              queryString.append((nq == 0) ? "" : dbsource\r
+              queryString.append((numq == 0) ? "" : dbsource\r
                       .getAccessionSeparator());\r
               queryString.append(query);\r
               numq++;\r
             }\r
-          }\r
-          for (int nq = 0; nq < nqSize; nq++)\r
-          {\r
+            // remove the extracted query string\r
             queries.removeElementAt(0);\r
           }\r
           // make the queries and process the response\r
           AlignmentI retrieved = null;\r
           try\r
           {\r
+            if (jalview.bin.Cache.log.isDebugEnabled())\r
+            {\r
+              jalview.bin.Cache.log.debug("Querying "+dbsource.getDbName()+" with : '"+queryString.toString()+"'");\r
+            }\r
             retrieved = dbsource.getSequenceRecords(queryString.toString());\r
           } catch (Exception ex)\r
           {\r
             ex.printStackTrace();\r
+          } catch (OutOfMemoryError err)\r
+          {\r
+            new OOMWarning("retrieving database references ("\r
+                    + queryString.toString() + ")", err);\r
           }\r
           if (retrieved != null)\r
           {\r
@@ -249,7 +262,7 @@ public class DBRefFetcher implements Runnable
                     { dbSources[db] }); // jalview.datamodel.DBRefSource.UNIPROT\r
             // });\r
             // check for existing dbrefs to use\r
-            if (uprefs != null)\r
+            if (uprefs != null && uprefs.length>0)\r
             {\r
               for (int j = 0; j < uprefs.length; j++)\r
               {\r
@@ -346,14 +359,15 @@ public class DBRefFetcher implements Runnable
           }\r
         }\r
       }\r
-      if (sequenceMatches.size()==0)\r
+      if (sequenceMatches.size() == 0)\r
       {\r
-        // failed to match directly on accessionId==query so just compare all sequences to entry\r
+        // failed to match directly on accessionId==query so just compare all\r
+        // sequences to entry\r
         Enumeration e = seqRefs.keys();\r
         while (e.hasMoreElements())\r
         {\r
           Vector sqs = (Vector) seqRefs.get(e.nextElement());\r
-          if (sqs!=null && sqs.size()>0)\r
+          if (sqs != null && sqs.size() > 0)\r
           {\r
             Enumeration sqe = sqs.elements();\r
             while (sqe.hasMoreElements())\r
@@ -383,9 +397,12 @@ public class DBRefFetcher implements Runnable
       for (int m = 0; m < sequenceMatches.size(); m++)\r
       {\r
         sequence = (SequenceI) sequenceMatches.elementAt(m);\r
-        // only update start and end positions and shift features if there are no existing references\r
-        // TODO: test for legacy where uniprot or EMBL refs exist but no mappings are made (but content matches retrieved set)\r
-        boolean updateRefFrame = sequence.getDBRef()==null || sequence.getDBRef().length==0;\r
+        // only update start and end positions and shift features if there are\r
+        // no existing references\r
+        // TODO: test for legacy where uniprot or EMBL refs exist but no\r
+        // mappings are made (but content matches retrieved set)\r
+        boolean updateRefFrame = sequence.getDBRef() == null\r
+                || sequence.getDBRef().length == 0;\r
         // verify sequence against the entry sequence\r
 \r
         String nonGapped = AlignSeq.extractGaps("-. ",\r
@@ -405,20 +422,23 @@ public class DBRefFetcher implements Runnable
                     + " SEQUENCE NOT %100 MATCH \n");\r
             continue;\r
           }\r
-          \r
+\r
           sbuffer.append(sequence.getName() + " HAS " + absStart\r
-                + " PREFIXED RESIDUES COMPARED TO " + dbSource+"\n");\r
+                  + " PREFIXED RESIDUES COMPARED TO " + dbSource + "\n");\r
           //\r
-          //      + " - ANY SEQUENCE FEATURES"\r
-          //        + " HAVE BEEN ADJUSTED ACCORDINGLY \n");\r
+          // + " - ANY SEQUENCE FEATURES"\r
+          // + " HAVE BEEN ADJUSTED ACCORDINGLY \n");\r
           // absStart = 0;\r
           // create valid mapping between matching region of local sequence and\r
           // the mapped sequence\r
           mp = new Mapping(null, new int[]\r
-          { sequence.getStart()+absStart, sequence.getStart()+absStart+entrySeq.length()-1 }, new int[]\r
-          { entry.getStart(),\r
-              entry.getStart() + entrySeq.length() - 1 }, 1, 1);\r
-          updateRefFrame=false; // mapping is based on current start/end so don't modify start and end\r
+          { sequence.getStart() + absStart,\r
+              sequence.getStart() + absStart + entrySeq.length() - 1 },\r
+                  new int[]\r
+                  { entry.getStart(),\r
+                      entry.getStart() + entrySeq.length() - 1 }, 1, 1);\r
+          updateRefFrame = false; // mapping is based on current start/end so\r
+          // don't modify start and end\r
         }\r
         else\r
         {\r
@@ -438,13 +458,15 @@ public class DBRefFetcher implements Runnable
             SequenceFeature[] sf = sequence.getSequenceFeatures();\r
             int start = sequence.getStart();\r
             int end = sequence.getEnd();\r
+            int startShift = 1 - absStart - start; // how much the features are\r
+            // to be shifted by\r
             for (int sfi = 0; sfi < sf.length; sfi++)\r
             {\r
               if (sf[sfi].getBegin() >= start && sf[sfi].getEnd() <= end)\r
               {\r
                 // shift feature along by absstart\r
-                sf[sfi].setBegin(sf[sfi].getBegin() + absStart);\r
-                sf[sfi].setEnd(sf[sfi].getEnd() + absStart);\r
+                sf[sfi].setBegin(sf[sfi].getBegin() + startShift);\r
+                sf[sfi].setEnd(sf[sfi].getEnd() + startShift);\r
               }\r
             }\r
           }\r