*experimental use of picr* apply gpl development license
[jalview.git] / src / jalview / ws / DBRefFetcher.java
index 76e73e4..5400d4e 100644 (file)
@@ -1,6 +1,6 @@
 /*\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
+ * Jalview - A Sequence Alignment Editor and Viewer (Development Version 2.4.1)\r
+ * Copyright (C) 2009 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
  */\r
 package jalview.ws;\r
 \r
-import java.io.*;\r
-import java.util.*;\r
-\r
-import org.exolab.castor.mapping.*;\r
-import org.exolab.castor.xml.*;\r
-import jalview.analysis.*;\r
-import jalview.datamodel.*;\r
+import jalview.analysis.AlignSeq;\r
+import jalview.datamodel.AlignmentI;\r
+import jalview.datamodel.DBRefEntry;\r
+import jalview.datamodel.DBRefSource;\r
 import jalview.datamodel.Mapping;\r
-import jalview.gui.*;\r
-import jalview.ws.dbsources.Uniprot;\r
-import jalview.ws.ebi.EBIFetchClient;\r
+import jalview.datamodel.SequenceFeature;\r
+import jalview.datamodel.SequenceI;\r
+import jalview.gui.AlignFrame;\r
+import jalview.gui.CutAndPasteTransfer;\r
+import jalview.gui.Desktop;\r
+import jalview.gui.IProgressIndicator;\r
+import jalview.gui.OOMWarning;\r
+\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+import java.util.StringTokenizer;\r
+import java.util.Vector;\r
+\r
+import org.biojava.dasobert.dasregistry.DasSource;\r
+\r
+import uk.ac.ebi.picr.model.UPEntry;\r
 \r
 /**\r
  * Implements a runnable for validating a sequence against external databases\r
@@ -48,6 +58,10 @@ public class DBRefFetcher implements Runnable
   StringBuffer sbuffer = new StringBuffer();\r
 \r
   boolean running = false;\r
+  /**\r
+   * picr client instance\r
+   */\r
+  uk.ac.ebi.www.picr.AccessionMappingService.AccessionMapperInterface picrClient = null;\r
 \r
   // /This will be a collection of Vectors of sequenceI refs.\r
   // The key will be the seq name or accession id of the seq\r
@@ -62,7 +76,8 @@ public class DBRefFetcher implements Runnable
   }\r
 \r
   /**\r
-   * Creates a new SequenceFeatureFetcher object.\r
+   * Creates a new SequenceFeatureFetcher object and fetches from the\r
+   * currently selected set of databases.\r
    * \r
    * @param seqs\r
    *                fetch references for these sequences\r
@@ -71,6 +86,20 @@ public class DBRefFetcher implements Runnable
    */\r
   public DBRefFetcher(SequenceI[] seqs, AlignFrame af)\r
   {\r
+    this(seqs, af, null);\r
+  }\r
+  /**\r
+   * Creates a new SequenceFeatureFetcher object and fetches from the\r
+   * currently selected set of databases.\r
+   * \r
+   * @param seqs\r
+   *                fetch references for these sequences\r
+   * @param af\r
+   *                the parent alignframe for progress bar monitoring.\r
+   * @param sources array of database source strings to query references from\r
+   */\r
+  public DBRefFetcher(SequenceI[] seqs, AlignFrame af, String[] sources)\r
+  {\r
     this.af = af;\r
     SequenceI[] ds = new SequenceI[seqs.length];\r
     for (int i = 0; i < seqs.length; i++)\r
@@ -83,17 +112,71 @@ public class DBRefFetcher implements Runnable
     this.dataset = ds;\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
+    if (sources==null)\r
     {\r
-      dbSources = DBRefSource.DNACODINGDBS;\r
+      // af.featureSettings_actionPerformed(null);\r
+      String[] defdb=null,otherdb = sfetcher.getDbInstances(jalview.ws.dbsources.DasSequenceSource.class);\r
+      Vector selsources = new Vector(), dasselsrc= (af.featureSettings!=null) ? af.featureSettings.getSelectedSources()\r
+              : new jalview.gui.DasSourceBrowser().getSelectedSources();\r
+      Enumeration en = dasselsrc.elements();\r
+      while (en.hasMoreElements())\r
+      {\r
+        DasSource src = (DasSource) en.nextElement();\r
+        selsources.addElement(src.getNickname());\r
+      }\r
+      int osel = 0;\r
+      for (int o=0;otherdb!=null && o<otherdb.length;o++)\r
+      {\r
+        if (!selsources.contains(otherdb[o]))\r
+        {\r
+          otherdb[o] = null;\r
+        } else {\r
+          osel++;\r
+        }\r
+      }\r
+      // select appropriate databases based on alignFrame context.\r
+      if (af.getViewport().getAlignment().isNucleotide())\r
+      {\r
+        defdb = DBRefSource.DNACODINGDBS;\r
+      }\r
+      else\r
+      {\r
+        defdb = DBRefSource.PROTEINDBS;\r
+      }\r
+      // append the selected sequence sources to the default dbs \r
+      dbSources = new String[defdb.length+osel];\r
+      System.arraycopy(defdb, 0, dbSources, 0, defdb.length);\r
+      for (int o=0,op=defdb.length; otherdb!=null && o<otherdb.length; o++)\r
+      {\r
+        if (otherdb[o]!=null)\r
+        {\r
+          dbSources[op++] = otherdb[o];\r
+        }\r
+      }\r
+    } else {\r
+      // we assume the caller knows what they're doing and ensured that all the db source names are valid\r
+      dbSources = sources;\r
     }\r
-    else\r
+  }\r
+  /**\r
+   * retrieve all the das sequence sources and add them to the list of db sources to retrieve from \r
+   */\r
+  public void appendAllDasSources()\r
+  {\r
+    if (dbSources == null)\r
     {\r
-      dbSources = DBRefSource.PROTEINDBS;\r
+      dbSources = new String[] {};\r
+    }\r
+    // append additional sources\r
+    String[] otherdb = sfetcher.getDbInstances(jalview.ws.dbsources.DasSequenceSource.class);\r
+    if (otherdb!=null && otherdb.length>0)\r
+    {\r
+      String[] newsrc = new String[dbSources.length+otherdb.length];\r
+      System.arraycopy(dbSources, 0, newsrc,0,dbSources.length);\r
+      System.arraycopy(otherdb, 0, newsrc,dbSources.length, otherdb.length);\r
+      dbSources = newsrc;\r
     }\r
   }\r
-\r
   /**\r
    * start the fetcher thread\r
    * \r
@@ -167,9 +250,16 @@ public class DBRefFetcher implements Runnable
     {\r
       throw new Error("Implementation error. Must initialise dbSources");\r
     }\r
+    running = true;\r
     long startTime = System.currentTimeMillis();\r
     af.setProgressBar("Fetching db refs", startTime);\r
-    running = true;\r
+    try {\r
+      picrClient = new uk.ac.ebi.www.picr.AccessionMappingService.AccessionMapperServiceLocator().getAccessionMapperPort(); \r
+    } catch (Exception e)\r
+    {\r
+      System.err.println("Couldn't locate PICR service instance.\n");\r
+      e.printStackTrace();\r
+    }\r
     int db = 0;\r
     Vector sdataset = new Vector();\r
     for (int s = 0; s < dataset.length; s++)\r
@@ -213,27 +303,30 @@ 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
@@ -259,7 +352,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
@@ -277,8 +370,27 @@ public class DBRefFetcher implements Runnable
               while (st.hasMoreTokens())\r
               {\r
                 String token = st.nextToken();\r
-                addSeqId(sequence, token);\r
-                queries.addElement(token.toUpperCase());\r
+                UPEntry[] presp = null;\r
+                try {\r
+                  presp=picrClient.getUPIForAccession(token, null, picrClient.getMappedDatabaseNames(), null, true);\r
+                } catch (Exception e) {\r
+                  System.err.println("Exception with Picr for '"+token+"'\n");\r
+                  e.printStackTrace();\r
+                }\r
+                if (presp!=null && presp.length>0)\r
+                {\r
+                  for (int id=0;id<presp.length; id++)\r
+                  {\r
+                    // construct sequences from response if sequences are present, and do a transferReferences\r
+                    // otherwise transfer non sequence x-references directly.\r
+                  }\r
+                  addSeqId(sequence, token);\r
+                  queries.addElement(token.toUpperCase());\r
+                } else {\r
+                  System.out.println("Not querying source with token="+token+"\n");\r
+                  //addSeqId(sequence, token);\r
+                  //queries.addElement(token.toUpperCase());\r
+                }\r
               }\r
             }\r
           }\r
@@ -484,6 +596,7 @@ public class DBRefFetcher implements Runnable
         // and remove it from the rest\r
         // TODO: decide if we should remove annotated sequence from set\r
         sdataset.remove(sequence);\r
+        // TODO: should we make a note of sequences that have received new DB ids, so we can query all enabled DAS servers for them ?\r
       }\r
     }\r
   }\r