Jalview.isJS() --> Platform.isJS(), DBRefEntry[] --> List<DBRefEntry>
[jalview.git] / src / jalview / analysis / CrossRef.java
index 1a56393..4f01cea 100644 (file)
@@ -99,7 +99,7 @@ public class CrossRef
    */
   public List<String> findXrefSourcesForSequences(boolean dna)
   {
-    List<String> sources = new ArrayList<String>();
+    List<String> sources = new ArrayList<>();
     for (SequenceI seq : fromSeqs)
     {
       if (seq != null)
@@ -143,15 +143,15 @@ public class CrossRef
     /*
      * first find seq's xrefs (dna-to-peptide or peptide-to-dna)
      */
-    DBRefEntry[] rfs = DBRefUtils.selectDbRefs(!fromDna, seq.getDBRefs());
+    List<DBRefEntry> rfs = DBRefUtils.selectDbRefs(!fromDna, seq.getDBRefs());
     addXrefsToSources(rfs, sources);
     if (dataset != null)
     {
       /*
        * find sequence's direct (dna-to-dna, peptide-to-peptide) xrefs
        */
-      DBRefEntry[] lrfs = DBRefUtils.selectDbRefs(fromDna, seq.getDBRefs());
-      List<SequenceI> foundSeqs = new ArrayList<SequenceI>();
+      List<DBRefEntry> lrfs = DBRefUtils.selectDbRefs(fromDna, seq.getDBRefs());
+      List<SequenceI> foundSeqs = new ArrayList<>();
 
       /*
        * find sequences in the alignment which xref one of these DBRefs
@@ -164,7 +164,7 @@ public class CrossRef
        */
       for (SequenceI rs : foundSeqs)
       {
-        DBRefEntry[] xrs = DBRefUtils.selectDbRefs(!fromDna,
+        List<DBRefEntry> xrs = DBRefUtils.selectDbRefs(!fromDna,
                 rs.getDBRefs());
         addXrefsToSources(xrs, sources);
       }
@@ -178,7 +178,7 @@ public class CrossRef
    * @param xrefs
    * @param sources
    */
-  void addXrefsToSources(DBRefEntry[] xrefs, List<String> sources)
+  void addXrefsToSources(List<DBRefEntry> xrefs, List<String> sources)
   {
     if (xrefs != null)
     {
@@ -218,7 +218,7 @@ public class CrossRef
   public Alignment findXrefSequences(String source, boolean fromDna)
   {
 
-    rseqs = new ArrayList<SequenceI>();
+    rseqs = new ArrayList<>();
     AlignedCodonFrame cf = new AlignedCodonFrame();
     matcher = new SequenceIdMatcher(dataset.getSequences());
 
@@ -230,18 +230,18 @@ public class CrossRef
         dss = dss.getDatasetSequence();
       }
       boolean found = false;
-      DBRefEntry[] xrfs = DBRefUtils.selectDbRefs(!fromDna,
+      List<DBRefEntry> xrfs = DBRefUtils.selectDbRefs(!fromDna,
               dss.getDBRefs());
       // ENST & ENSP comes in to both Protein and nucleotide, so we need to
       // filter them
       // out later.
-      if ((xrfs == null || xrfs.length == 0) && dataset != null)
+      if ((xrfs == null || xrfs.size() == 0) && dataset != null)
       {
         /*
          * found no suitable dbrefs on sequence - look for sequences in the
          * alignment which share a dbref with this one
          */
-        DBRefEntry[] lrfs = DBRefUtils.selectDbRefs(fromDna,
+        List<DBRefEntry> lrfs = DBRefUtils.selectDbRefs(fromDna,
                 seq.getDBRefs());
 
         /*
@@ -370,7 +370,7 @@ public class CrossRef
         {
           // do a bit more work - search for sequences with references matching
           // xrefs on this sequence.
-          found = searchDataset(fromDna, dss, xref, rseqs, cf, false);
+          found = searchDataset(fromDna, dss, xref, rseqs, cf, false, DBRefUtils.SEARCH_MODE_FULL);
         }
         if (found)
         {
@@ -400,7 +400,7 @@ public class CrossRef
   }
 
   private void retrieveCrossRef(List<DBRefEntry> sourceRefs, SequenceI seq,
-          DBRefEntry[] xrfs, boolean fromDna, AlignedCodonFrame cf)
+          List<DBRefEntry> xrfs, boolean fromDna, AlignedCodonFrame cf)
   {
     ASequenceFetcher sftch = SequenceFetcherFactory.getSequenceFetcher();
     SequenceI[] retrieved = null;
@@ -430,8 +430,8 @@ public class CrossRef
     if (retrieved != null)
     {
       boolean addedXref = false;
-      List<SequenceI> newDsSeqs = new ArrayList<SequenceI>(),
-              doNotAdd = new ArrayList<SequenceI>();
+      List<SequenceI> newDsSeqs = new ArrayList<>(),
+              doNotAdd = new ArrayList<>();
 
       for (SequenceI retrievedSequence : retrieved)
       {
@@ -483,19 +483,24 @@ public class CrossRef
   private void removeAlreadyRetrievedSeqs(List<DBRefEntry> sourceRefs,
           boolean fromDna)
   {
-    DBRefEntry[] dbrSourceSet = sourceRefs.toArray(new DBRefEntry[0]);
-    for (SequenceI sq : dataset.getSequences())
+    List<DBRefEntry> dbrSourceSet = new ArrayList<DBRefEntry>(sourceRefs);
+    List<SequenceI> dsSeqs = dataset.getSequences();
+    for (int ids = dsSeqs.size(); --ids >= 0;)
     {
+      SequenceI sq = dsSeqs.get(ids);
       boolean dupeFound = false;
       // !fromDna means we are looking only for nucleotide sequences, not
       // protein
       if (sq.isProtein() == fromDna)
       {
-        for (DBRefEntry dbr : sq.getPrimaryDBRefs())
+       List<DBRefEntry> sqdbrefs = sq.getPrimaryDBRefs();
+        for (int idb = sqdbrefs.size(); --idb >= 0;)
         {
-          for (DBRefEntry found : DBRefUtils.searchRefs(dbrSourceSet, dbr))
+          DBRefEntry dbr = sqdbrefs.get(idb);  
+          List<DBRefEntry> searchrefs = DBRefUtils.searchRefs(dbrSourceSet, dbr, DBRefUtils.SEARCH_MODE_FULL);
+          for (int isr = searchrefs.size(); --isr >= 0;)
           {
-            sourceRefs.remove(found);
+            sourceRefs.remove(searchrefs.get(isr));
             dupeFound = true;
           }
         }
@@ -503,7 +508,8 @@ public class CrossRef
       if (dupeFound)
       {
         // rebuild the search array from the filtered sourceRefs list
-        dbrSourceSet = sourceRefs.toArray(new DBRefEntry[0]);
+        dbrSourceSet.clear();
+        dbrSourceSet.addAll(sourceRefs);
       }
     }
   }
@@ -526,11 +532,13 @@ public class CrossRef
      * sourceSequence
      */
     boolean imported = false;
-    DBRefEntry[] dbr = retrievedSequence.getDBRefs();
+    List<DBRefEntry> dbr = retrievedSequence.getDBRefs();
     if (dbr != null)
     {
-      for (DBRefEntry dbref : dbr)
+       for (int ib = 0, nb = dbr.size(); ib < nb; ib++)
       {
+
+       DBRefEntry dbref = dbr.get(ib);
         SequenceI matched = findInDataset(dbref);
         if (matched == sourceSequence)
         {
@@ -542,9 +550,10 @@ public class CrossRef
         Mapping map = dbref.getMap();
         if (map != null)
         {
-          if (map.getTo() != null && map.getMap() != null)
+               SequenceI ms = map.getTo();
+          if (ms != null && map.getMap() != null)
           {
-            if (map.getTo() == sourceSequence)
+            if (ms == sourceSequence)
             {
               // already called to import once, and most likely this sequence
               // already imported !
@@ -555,7 +564,7 @@ public class CrossRef
               /*
                * sequence is new to dataset, so save a reference so it can be added. 
                */
-              newDsSeqs.add(map.getTo());
+              newDsSeqs.add(ms);
               continue;
             }
 
@@ -567,7 +576,6 @@ public class CrossRef
             {
               // compare ms with dss and replace with dss in mapping
               // if map is congruent
-              SequenceI ms = map.getTo();
               // TODO findInDataset requires exact sequence match but
               // 'congruent' test is only for the mapped part
               // maybe not a problem in practice since only ENA provide a
@@ -589,7 +597,7 @@ public class CrossRef
                         + matched.getName();
                 System.out.println(msg);
 
-                DBRefEntry[] toRefs = map.getTo().getDBRefs();
+                List<DBRefEntry> toRefs = map.getTo().getDBRefs();
                 if (toRefs != null)
                 {
                   /*
@@ -619,28 +627,25 @@ public class CrossRef
                  * duplication (e.g. same variation from two 
                  * transcripts)
                  */
-                SequenceFeature[] sfs = ms.getSequenceFeatures();
-                if (sfs != null)
+                List<SequenceFeature> sfs = ms.getFeatures()
+                        .getAllFeatures();
+                for (SequenceFeature feat : sfs)
                 {
-                  for (SequenceFeature feat : sfs)
+                  /*
+                   * make a flyweight feature object which ignores Parent
+                   * attribute in equality test; this avoids creating many
+                   * otherwise duplicate exon features on genomic sequence
+                   */
+                  SequenceFeature newFeature = new SequenceFeature(feat)
                   {
-                    /*
-                     * make a flyweight feature object which ignores Parent
-                     * attribute in equality test; this avoids creating many
-                     * otherwise duplicate exon features on genomic sequence
-                     */
-                    SequenceFeature newFeature = new SequenceFeature(feat)
+                    @Override
+                    public boolean equals(Object o)
                     {
-                      @Override
-                      public boolean equals(Object o)
-                      {
-                        return super.equals(o, true);
-                      }
-                    };
-                    matched.addSequenceFeature(newFeature);
-                  }
+                      return super.equals(o, true);
+                    }
+                  };
+                  matched.addSequenceFeature(newFeature);
                 }
-
               }
               cf.addMap(retrievedSequence, map.getTo(), map.getMap());
             } catch (Exception e)
@@ -685,7 +690,7 @@ public class CrossRef
     {
       return;
     }
-    DBRefEntry[] dbrefs = mapTo.getDBRefs();
+    List<DBRefEntry> dbrefs = mapTo.getDBRefs();
     if (dbrefs == null)
     {
       return;
@@ -742,7 +747,7 @@ public class CrossRef
     {
       // first check primary refs.
       List<DBRefEntry> match = DBRefUtils.searchRefs(
-              seq.getPrimaryDBRefs().toArray(new DBRefEntry[0]), template);
+              seq.getPrimaryDBRefs(), template, DBRefUtils.SEARCH_MODE_FULL);
       if (match != null && match.size() == 1 && sameSequence(seq, dss))
       {
         return seq;
@@ -785,15 +790,15 @@ public class CrossRef
     {
       return false;
     }
-    char[] c1 = seq1.getSequence();
-    char[] c2 = seq2.getSequence();
-    if (c1.length != c2.length)
+
+    if (seq1.getLength() != seq2.getLength())
     {
       return false;
     }
-    for (int i = 0; i < c1.length; i++)
+    int length = seq1.getLength();
+    for (int i = 0; i < length; i++)
     {
-      int diff = c1[i] - c2[i];
+      int diff = seq1.getCharAt(i) - seq2.getCharAt(i);
       /*
        * same char or differ in case only ('a'-'A' == 32)
        */
@@ -815,7 +820,7 @@ public class CrossRef
    * @param retrieved
    * @param acf
    */
-  void updateDbrefMappings(SequenceI mapFrom, DBRefEntry[] xrefs,
+  void updateDbrefMappings(SequenceI mapFrom, List<DBRefEntry> xrefs,
           SequenceI[] retrieved, AlignedCodonFrame acf, boolean fromDna)
   {
     SequenceIdMatcher idMatcher = new SequenceIdMatcher(retrieved);
@@ -949,7 +954,7 @@ public class CrossRef
    * @return true if matches were found.
    */
   private boolean searchDatasetXrefs(boolean fromDna, SequenceI sequenceI,
-          DBRefEntry[] lrfs, List<SequenceI> foundSeqs,
+          List<DBRefEntry> lrfs, List<SequenceI> foundSeqs,
           AlignedCodonFrame cf)
   {
     boolean found = false;
@@ -957,14 +962,14 @@ public class CrossRef
     {
       return false;
     }
-    for (int i = 0; i < lrfs.length; i++)
+    for (int i = 0, n = lrfs.size(); i < n; i++)
     {
-      DBRefEntry xref = new DBRefEntry(lrfs[i]);
-      // add in wildcards
-      xref.setVersion(null);
-      xref.setMap(null);
-      found |= searchDataset(fromDna, sequenceI, xref, foundSeqs, cf,
-              false);
+//      DBRefEntry xref = new DBRefEntry(lrfs.get(i));
+//      // add in wildcards
+//      xref.setVersion(null);
+//      xref.setMap(null);
+      found |= searchDataset(fromDna, sequenceI, lrfs.get(i), foundSeqs, cf,
+              false, DBRefUtils.SEARCH_MODE_NO_MAP_NO_VERSION);
     }
     return found;
   }
@@ -995,11 +1000,12 @@ public class CrossRef
    *          sequenceI or all the returned sequences (eg a genomic reference
    *          associated with a locus and one or more transcripts)</li>
    *          </ul>
+   * @param mode   SEARCH_MODE_FULL for all; SEARCH_MODE_NO_MAP_NO_VERSION optional
    * @return true if relationship found and sequence added.
    */
   boolean searchDataset(boolean fromDna, SequenceI fromSeq, DBRefEntry xrf,
           List<SequenceI> foundSeqs, AlignedCodonFrame mappings,
-          boolean direct)
+          boolean direct, int mode)
   {
     boolean found = false;
     if (dataset == null)
@@ -1011,8 +1017,8 @@ public class CrossRef
       System.err.println("Empty dataset sequence set - NO VECTOR");
       return false;
     }
-    List<SequenceI> ds;
-    synchronized (ds = dataset.getSequences())
+    List<SequenceI> ds = dataset.getSequences();
+    synchronized (ds)
     {
       for (SequenceI nxt : ds)
       {
@@ -1044,13 +1050,13 @@ public class CrossRef
           }
 
           // look for direct or indirect references in common
-          DBRefEntry[] poss = nxt.getDBRefs();
+          List<DBRefEntry> poss = nxt.getDBRefs();
           List<DBRefEntry> cands = null;
 
           // todo: indirect specifies we select either direct references to nxt
           // that match xrf which is indirect to sequenceI, or indirect
           // references to nxt that match xrf which is direct to sequenceI
-          cands = DBRefUtils.searchRefs(poss, xrf);
+          cands = DBRefUtils.searchRefs(poss, xrf, mode);
           // else
           // {
           // poss = DBRefUtils.selectDbRefs(nxt.isProtein()!fromDna, poss);