JAL-3210 Merge branch 'develop' into trialMerge
[jalview.git] / src / jalview / ws / DBRefFetcher.java
index 061e70c..6b8843d 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.ws;
 
 import jalview.analysis.AlignSeq;
+import jalview.api.FeatureSettingsModelI;
 import jalview.bin.Cache;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.DBRefEntry;
@@ -39,8 +40,10 @@ import jalview.ws.seqfetcher.DbSourceProxy;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Enumeration;
+import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Map;
 import java.util.StringTokenizer;
 import java.util.Vector;
 
@@ -134,8 +137,7 @@ public class DBRefFetcher implements Runnable
     }
     this.dataset = ds;
     // TODO Jalview 2.5 lots of this code should be in the gui package!
-    sfetcher = jalview.gui.SequenceFetcher
-            .getSequenceFetcherSingleton(progressIndicatorFrame);
+    sfetcher = jalview.gui.SequenceFetcher.getSequenceFetcherSingleton();
     // set default behaviour for transferring excess sequence data to the
     // dataset
     trimDsSeqs = Cache.getDefault(TRIM_RETRIEVED_SEQUENCES, true);
@@ -318,6 +320,9 @@ public class DBRefFetcher implements Runnable
             Arrays.asList(dataset));
     List<String> warningMessages = new ArrayList<>();
 
+    // clear any old feature display settings recorded from past sessions
+    featureDisplaySettings = null;
+
     int db = 0;
     while (sdataset.size() > 0 && db < dbSources.length)
     {
@@ -384,7 +389,7 @@ public class DBRefFetcher implements Runnable
           }
           if (retrieved != null)
           {
-            transferReferences(sdataset, dbsource.getDbSource(), retrieved,
+            transferReferences(sdataset, dbsource, retrieved,
                     trimDsSeqs, warningMessages);
           }
         }
@@ -395,18 +400,19 @@ public class DBRefFetcher implements Runnable
                   && (i < 50); seqIndex++, i++)
           {
             SequenceI sequence = dataset[seqIndex];
-            DBRefEntry[] uprefs = DBRefUtils
+            List<DBRefEntry> uprefs = DBRefUtils
                     .selectRefs(sequence.getDBRefs(), new String[]
                     { dbsource.getDbSource() }); // jalview.datamodel.DBRefSource.UNIPROT
             // });
             // check for existing dbrefs to use
-            if (uprefs != null && uprefs.length > 0)
+            if (uprefs != null && uprefs.size() > 0)
             {
-              for (int j = 0; j < uprefs.length; j++)
+              for (int j = 0, n = uprefs.size(); j < n; j++)
               {
-                addSeqId(sequence, uprefs[j].getAccessionId());
+               DBRefEntry upref = uprefs.get(j);
+                addSeqId(sequence, upref.getAccessionId());
                 queries.addElement(
-                        uprefs[j].getAccessionId().toUpperCase());
+                        upref.getAccessionId().toUpperCase());
               }
             }
             else
@@ -512,7 +518,8 @@ public class DBRefFetcher implements Runnable
    * @param warningMessages
    *          a list of messages to add to
    */
-  boolean transferReferences(Vector<SequenceI> sdataset, String dbSource,
+  boolean transferReferences(Vector<SequenceI> sdataset,
+          DbSourceProxy dbSourceProxy,
           AlignmentI retrievedAl, boolean trimDatasetSeqs,
           List<String> warningMessages)
   {
@@ -522,6 +529,7 @@ public class DBRefFetcher implements Runnable
       return false;
     }
 
+    String dbSource = dbSourceProxy.getDbName();
     boolean modified = false;
     SequenceI[] retrieved = recoverDbSequences(
             retrievedAl.getSequencesArray());
@@ -533,7 +541,7 @@ public class DBRefFetcher implements Runnable
       // taking into account all accessionIds and names in the file
       Vector<SequenceI> sequenceMatches = new Vector<>();
       // look for corresponding accession ids
-      DBRefEntry[] entryRefs = DBRefUtils
+      List<DBRefEntry> entryRefs = DBRefUtils
               .selectRefs(retrievedSeq.getDBRefs(), new String[]
               { dbSource });
       if (entryRefs == null)
@@ -543,9 +551,10 @@ public class DBRefFetcher implements Runnable
                         + dbSource + " on " + retrievedSeq.getName());
         continue;
       }
-      for (int j = 0; j < entryRefs.length; j++)
+      for (int j = 0, n = entryRefs.size(); j < n; j++)
       {
-        String accessionId = entryRefs[j].getAccessionId();
+       DBRefEntry ref = entryRefs.get(j);
+        String accessionId = ref.getAccessionId();
         // match up on accessionId
         if (seqRefs.containsKey(accessionId.toUpperCase()))
         {
@@ -583,7 +592,7 @@ public class DBRefFetcher implements Runnable
       // could be useful to extend this so we try to find any 'significant'
       // information in common between two sequence objects.
       /*
-       * DBRefEntry[] entryRefs =
+       * List<DBRefEntry> entryRefs =
        * jalview.util.DBRefUtils.selectRefs(entry.getDBRef(), new String[] {
        * dbSource }); for (int j = 0; j < entry.getName().size(); j++) { String
        * name = entry.getName().elementAt(j).toString(); if
@@ -592,6 +601,10 @@ public class DBRefFetcher implements Runnable
        * seqs.elementAt(jj); if (!sequenceMatches.contains(sequence)) {
        * sequenceMatches.addElement(sequence); } } } }
        */
+      if (sequenceMatches.size() > 0)
+      {
+        addFeatureSettings(dbSourceProxy);
+      }
       // sequenceMatches now contains the set of all sequences associated with
       // the returned db record
       final String retrievedSeqString = retrievedSeq.getSequenceAsString();
@@ -604,7 +617,7 @@ public class DBRefFetcher implements Runnable
         // TODO: test for legacy where uniprot or EMBL refs exist but no
         // mappings are made (but content matches retrieved set)
         boolean updateRefFrame = sequence.getDBRefs() == null
-                || sequence.getDBRefs().length == 0;
+                || sequence.getDBRefs().size() == 0;
         // TODO:
         // verify sequence against the entry sequence
 
@@ -670,7 +683,8 @@ public class DBRefFetcher implements Runnable
             int startShift = absStart - sequenceStart + 1;
             if (startShift != 0)
             {
-              modified |= sequence.getFeatures().shiftFeatures(startShift);
+              modified |= sequence.getFeatures().shiftFeatures(1,
+                      startShift);
             }
           }
         }
@@ -754,13 +768,38 @@ public class DBRefFetcher implements Runnable
         // and remove it from the rest
         // TODO: decide if we should remove annotated sequence from set
         sdataset.remove(sequence);
-        // TODO: should we make a note of sequences that have received new DB
-        // ids, so we can query all enabled DAS servers for them ?
       }
     }
     return modified;
   }
 
+  Map<String, FeatureSettingsModelI> featureDisplaySettings = null;
+
+  private void addFeatureSettings(DbSourceProxy dbSourceProxy)
+  {
+    FeatureSettingsModelI fsettings = dbSourceProxy
+            .getFeatureColourScheme();
+    if (fsettings != null)
+    {
+      if (featureDisplaySettings == null)
+      {
+        featureDisplaySettings = new HashMap<>();
+      }
+      featureDisplaySettings.put(dbSourceProxy.getDbName(), fsettings);
+    }
+  }
+
+  /**
+   * 
+   * @return any feature settings associated with sources that have provided sequences
+   */
+  public List<FeatureSettingsModelI>getFeatureSettingsModels()
+  {
+    return featureDisplaySettings == null
+            ? Arrays.asList(new FeatureSettingsModelI[0])
+            : Arrays.asList(featureDisplaySettings.values()
+                    .toArray(new FeatureSettingsModelI[1]));
+  }
   /**
    * Adds the message to the list unless it already contains it
    * 
@@ -783,28 +822,33 @@ public class DBRefFetcher implements Runnable
    */
   private SequenceI[] recoverDbSequences(SequenceI[] sequencesArray)
   {
-    Vector<SequenceI> nseq = new Vector<>();
-    for (int i = 0; sequencesArray != null
-            && i < sequencesArray.length; i++)
+       int n;
+       if (sequencesArray == null || (n = sequencesArray.length) == 0)
+         return sequencesArray;
+    ArrayList<SequenceI> nseq = new ArrayList<>();
+    for (int i = 0;i < n; i++)
     {
-      nseq.addElement(sequencesArray[i]);
-      DBRefEntry[] dbr = sequencesArray[i].getDBRefs();
+      nseq.add(sequencesArray[i]);
+      List<DBRefEntry> dbr = sequencesArray[i].getDBRefs();
       Mapping map = null;
-      for (int r = 0; (dbr != null) && r < dbr.length; r++)
+      if (dbr != null)
       {
-        if ((map = dbr[r].getMap()) != null)
+        for (int r = 0, rn = dbr.size(); r < rn; r++)
         {
-          if (map.getTo() != null && !nseq.contains(map.getTo()))
+          if ((map = dbr.get(r).getMap()) != null)
           {
-            nseq.addElement(map.getTo());
-          }
+            if (map.getTo() != null && !nseq.contains(map.getTo()))
+            {
+              nseq.add(map.getTo());
+            }
+          }  
         }
       }
     }
+    // BH 2019.01.25 question here if this is the right logic. Return the original if nothing found?
     if (nseq.size() > 0)
     {
-      sequencesArray = new SequenceI[nseq.size()];
-      nseq.toArray(sequencesArray);
+      return nseq.toArray(new SequenceI[nseq.size()]);
     }
     return sequencesArray;
   }