Clover icon

Coverage Report

  1. Project Clover database Wed Sep 17 2025 10:52:37 BST
  2. Package jalview.util

File DBRefUtils.java

 

Coverage histogram

../../img/srcFileCovDistChart6.png
37% of files have more coverage

Code metrics

132
180
22
2
829
507
155
0.86
8.18
11
7.05

Classes

Class Line # Actions
DBRefUtils 43 179 154
0.608433760.8%
DBRefUtils.DbRefComp 295 1 1
0.00%
 

Contributing tests

This file is covered by 278 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.util;
22   
23    import java.util.ArrayList;
24    import java.util.BitSet;
25    import java.util.HashMap;
26    import java.util.HashSet;
27    import java.util.List;
28    import java.util.Locale;
29    import java.util.Map;
30   
31    import com.stevesoft.pat.Regex;
32   
33    import jalview.bin.Console;
34    import jalview.datamodel.DBRefEntry;
35    import jalview.datamodel.DBRefSource;
36    import jalview.datamodel.Mapping;
37    import jalview.datamodel.PDBEntry;
38    import jalview.datamodel.SequenceI;
39   
40    /**
41    * Utilities for handling DBRef objects and their collections.
42    */
 
43    public class DBRefUtils
44    {
45    /*
46    * lookup from lower-case form of a name to its canonical (standardised) form
47    */
48    private static Map<String, String> canonicalSourceNameLookup = new HashMap<>();
49   
50    public final static int DB_SOURCE = 1;
51   
52    public final static int DB_VERSION = 2;
53   
54    public final static int DB_ID = 4;
55   
56    public final static int DB_MAP = 8;
57   
58    public final static int SEARCH_MODE_NO_MAP_NO_VERSION = DB_SOURCE | DB_ID;
59   
60    public final static int SEARCH_MODE_FULL = DB_SOURCE | DB_VERSION | DB_ID
61    | DB_MAP;
62   
 
63  50 toggle static
64    {
65    // TODO load these from a resource file?
66  50 canonicalSourceNameLookup.put("uniprotkb/swiss-prot",
67    DBRefSource.UNIPROT);
68  50 canonicalSourceNameLookup.put("uniprotkb/trembl", DBRefSource.UNIPROT);
69   
70    // Ensembl values for dbname in xref REST service:
71  50 canonicalSourceNameLookup.put("uniprot/sptrembl", DBRefSource.UNIPROT);
72  50 canonicalSourceNameLookup.put("uniprot/swissprot", DBRefSource.UNIPROT);
73   
74  50 canonicalSourceNameLookup.put("pdb", DBRefSource.PDB);
75    // PDBe is a 3D-Beacons provider
76  50 canonicalSourceNameLookup.put("pdbe", DBRefSource.PDB);
77   
78  50 canonicalSourceNameLookup.put("ensembl", DBRefSource.ENSEMBL);
79    // Ensembl Gn and Tr are for Ensembl genomic and transcript IDs as served
80    // from ENA.
81  50 canonicalSourceNameLookup.put("ensembl-tr", DBRefSource.ENSEMBL);
82  50 canonicalSourceNameLookup.put("ensembl-gn", DBRefSource.ENSEMBL);
83   
84    // guarantee we always have lowercase entries for canonical string lookups
85  50 for (String k : canonicalSourceNameLookup.keySet())
86    {
87  450 canonicalSourceNameLookup.put(k.toLowerCase(Locale.ROOT),
88    canonicalSourceNameLookup.get(k));
89    }
90    }
91   
92    /**
93    * Returns those DBRefEntry objects whose source identifier (once converted to
94    * Jalview's canonical form) is in the list of sources to search for. Returns
95    * null if no matches found.
96    *
97    * @param dbrefs
98    * DBRefEntry objects to search
99    * @param sources
100    * array of sources to select
101    * @return
102    */
 
103  14627 toggle public static List<DBRefEntry> selectRefs(List<DBRefEntry> dbrefs,
104    String[] sources)
105    {
106  14627 if (dbrefs == null || sources == null)
107    {
108  10628 return dbrefs;
109    }
110   
111    // BH TODO (what?)
112  3999 HashSet<String> srcs = new HashSet<String>();
113  3999 for (String src : sources)
114    {
115  17809 srcs.add(src.toUpperCase(Locale.ROOT));
116    }
117   
118  3999 int nrefs = dbrefs.size();
119  3999 List<DBRefEntry> res = new ArrayList<DBRefEntry>();
120  28162 for (int ib = 0; ib < nrefs; ib++)
121    {
122  24163 DBRefEntry dbr = dbrefs.get(ib);
123  24163 String source = getCanonicalName(dbr.getSource());
124  24163 if (srcs.contains(source.toUpperCase(Locale.ROOT)))
125    {
126  3761 res.add(dbr);
127    }
128    }
129  3999 if (res.size() > 0)
130    {
131    // List<DBRefEntry> reply = new DBRefEntry[res.size()];
132  2258 return res;// .toArray(reply);
133    }
134  1741 return null;
135    }
136   
 
137  23 toggle private static boolean selectRefsBS(List<DBRefEntry> dbrefs,
138    int sourceKeys, BitSet bsSelect)
139    {
140  23 if (dbrefs == null || sourceKeys == 0)
141    {
142  0 return false;
143    }
144  348 for (int i = 0, n = dbrefs.size(); i < n; i++)
145    {
146  325 DBRefEntry dbr = dbrefs.get(i);
147  325 if ((dbr.getSourceKey() & sourceKeys) != 0)
148    {
149  90 bsSelect.clear(i);
150    }
151    }
152  23 return !bsSelect.isEmpty();
153    }
154   
155    /**
156    * Returns a (possibly empty) list of those references that match the given
157    * entry, according to the given comparator.
158    *
159    * @param refs
160    * an array of database references to search
161    * @param entry
162    * an entry to compare against
163    * @param comparator
164    * @return
165    */
 
166  0 toggle static List<DBRefEntry> searchRefs(DBRefEntry[] refs, DBRefEntry entry,
167    DbRefComp comparator)
168    {
169  0 List<DBRefEntry> rfs = new ArrayList<>();
170  0 if (refs == null || entry == null)
171    {
172  0 return rfs;
173    }
174  0 for (int i = 0; i < refs.length; i++)
175    {
176  0 if (comparator.matches(entry, refs[i]))
177    {
178  0 rfs.add(refs[i]);
179    }
180    }
181  0 return rfs;
182    }
183   
184    /**
185    * look up source in an internal list of database reference sources and return
186    * the canonical jalview name for the source, or the original string if it has
187    * no canonical form.
188    *
189    * @param source
190    * @return canonical jalview source (one of jalview.datamodel.DBRefSource.*)
191    * or original source
192    */
 
193  265818 toggle public static String getCanonicalName(String source)
194    {
195  265818 if (source == null)
196    {
197  1 return null;
198    }
199  265817 String canonical = canonicalSourceNameLookup
200    .get(source.toLowerCase(Locale.ROOT));
201  265817 return canonical == null ? source : canonical;
202    }
203   
204    /**
205    * Returns a (possibly empty) list of those references that match the given
206    * entry. Currently uses a comparator which matches if
207    * <ul>
208    * <li>database sources are the same</li>
209    * <li>accession ids are the same</li>
210    * <li>both have no mapping, or the mappings are the same</li>
211    * </ul>
212    *
213    * @param ref
214    * Set of references to search
215    * @param entry
216    * pattern to match
217    * @param mode
218    * SEARCH_MODE_FULL for all; SEARCH_MODE_NO_MAP_NO_VERSION optional
219    * @return
220    */
 
221  5048 toggle public static List<DBRefEntry> searchRefs(List<DBRefEntry> ref,
222    DBRefEntry entry, int mode)
223    {
224  5048 return searchRefs(ref, entry,
225    matchDbAndIdAndEitherMapOrEquivalentMapList, mode);
226    }
227   
228    /**
229    * Returns a list of those references that match the given accession id
230    * <ul>
231    * <li>database sources are the same</li>
232    * <li>accession ids are the same</li>
233    * <li>both have no mapping, or the mappings are the same</li>
234    * </ul>
235    *
236    * @param refs
237    * Set of references to search
238    * @param accId
239    * accession id to match
240    * @return
241    */
 
242  6 toggle public static List<DBRefEntry> searchRefs(List<DBRefEntry> refs,
243    String accId)
244    {
245  6 List<DBRefEntry> rfs = new ArrayList<DBRefEntry>();
246  6 if (refs == null || accId == null)
247    {
248  0 return rfs;
249    }
250  22 for (int i = 0, n = refs.size(); i < n; i++)
251    {
252  16 DBRefEntry e = refs.get(i);
253  16 if (accId.equals(e.getAccessionId()))
254    {
255  8 rfs.add(e);
256    }
257    }
258  6 return rfs;
259    // return searchRefs(refs, new DBRefEntry("", "", accId), matchId,
260    // SEARCH_MODE_FULL);
261    }
262   
263    /**
264    * Returns a (possibly empty) list of those references that match the given
265    * entry, according to the given comparator.
266    *
267    * @param refs
268    * an array of database references to search
269    * @param entry
270    * an entry to compare against
271    * @param comparator
272    * @param mode
273    * SEARCH_MODE_FULL for all; SEARCH_MODE_NO_MAP_NO_VERSION optional
274    * @return
275    */
 
276  5048 toggle static List<DBRefEntry> searchRefs(List<DBRefEntry> refs,
277    DBRefEntry entry, DbRefComp comparator, int mode)
278    {
279  5048 List<DBRefEntry> rfs = new ArrayList<DBRefEntry>();
280  5048 if (refs == null || entry == null)
281    {
282  1 return rfs;
283    }
284  106882 for (int i = 0, n = refs.size(); i < n; i++)
285    {
286  101835 DBRefEntry e = refs.get(i);
287  101835 if (comparator.matches(entry, e, SEARCH_MODE_FULL))
288    {
289  889 rfs.add(e);
290    }
291    }
292  5047 return rfs;
293    }
294   
 
295    interface DbRefComp
296    {
 
297  0 toggle default public boolean matches(DBRefEntry refa, DBRefEntry refb)
298    {
299  0 return matches(refa, refb, SEARCH_MODE_FULL);
300    };
301   
302    public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode);
303    }
304   
305    /**
306    * match on all non-null fields in refa
307    */
308    // TODO unused - remove? would be broken by equating "" with null
309    public static DbRefComp matchNonNullonA = new DbRefComp()
310    {
 
311  0 toggle @Override
312    public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode)
313    {
314  0 if ((mode & DB_SOURCE) != 0 && (refa.getSource() == null
315    || DBRefUtils.getCanonicalName(refb.getSource()).equals(
316    DBRefUtils.getCanonicalName(refa.getSource()))))
317    {
318  0 if ((mode & DB_VERSION) != 0 && (refa.getVersion() == null
319    || refb.getVersion().equals(refa.getVersion())))
320    {
321  0 if ((mode & DB_ID) != 0 && (refa.getAccessionId() == null
322    || refb.getAccessionId().equals(refa.getAccessionId())))
323    {
324  0 if ((mode & DB_MAP) != 0
325    && (refa.getMap() == null || (refb.getMap() != null
326    && refb.getMap().equals(refa.getMap()))))
327    {
328  0 return true;
329    }
330    }
331    }
332    }
333  0 return false;
334    }
335    };
336   
337    /**
338    * either field is null or field matches for all of source, version, accession
339    * id and map.
340    */
341    // TODO unused - remove?
342    public static DbRefComp matchEitherNonNull = new DbRefComp()
343    {
 
344  0 toggle @Override
345    public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode)
346    {
347  0 if (nullOrEqualSource(refa.getSource(), refb.getSource())
348    && nullOrEqual(refa.getVersion(), refb.getVersion())
349    && nullOrEqual(refa.getAccessionId(), refb.getAccessionId())
350    && nullOrEqual(refa.getMap(), refb.getMap()))
351    {
352  0 return true;
353    }
354  0 return false;
355    }
356   
357    };
358   
359    /**
360    * Parses a DBRefEntry and adds it to the sequence, also a PDBEntry if the
361    * database is PDB.
362    * <p>
363    * Used by file parsers to generate DBRefs from annotation within file (eg
364    * Stockholm)
365    *
366    * @param dbname
367    * @param version
368    * @param acn
369    * @param seq
370    * where to annotate with reference
371    * @return parsed version of entry that was added to seq (if any)
372    */
 
373  1557 toggle public static DBRefEntry parseToDbRef(SequenceI seq, String dbname,
374    String version, String acn)
375    {
376  1557 DBRefEntry ref = null;
377  1557 if (dbname != null)
378    {
379  1557 String locsrc = DBRefUtils.getCanonicalName(dbname);
380  1557 if (locsrc.equals(DBRefSource.PDB))
381    {
382    /*
383    * Check for PFAM style stockhom PDB accession id citation e.g.
384    * "1WRI A; 7-80;"
385    */
386  27 Regex r = new com.stevesoft.pat.Regex(
387    "([0-9][0-9A-Za-z]{3})\\s*(.?)\\s*;\\s*([0-9]+)-([0-9]+)");
388  27 if (r.search(acn.trim()))
389    {
390  27 String pdbid = r.stringMatched(1);
391  27 String chaincode = r.stringMatched(2);
392  27 if (chaincode == null)
393    {
394  0 chaincode = " ";
395    }
396    // String mapstart = r.stringMatched(3);
397    // String mapend = r.stringMatched(4);
398  27 if (chaincode.equals(" "))
399    {
400  0 chaincode = "_";
401    }
402    // construct pdb ref.
403  27 ref = new DBRefEntry(locsrc, version, pdbid + chaincode);
404  27 PDBEntry pdbr = new PDBEntry();
405  27 pdbr.setId(pdbid);
406  27 pdbr.setType(PDBEntry.Type.PDB);
407  27 pdbr.setChainCode(chaincode);
408  27 seq.addPDBId(pdbr);
409    }
410    else
411    {
412  0 jalview.bin.Console.errPrintln("Malformed PDB DR line:" + acn);
413    }
414    }
415    else
416    {
417    // default:
418  1530 ref = new DBRefEntry(locsrc, version, acn.trim());
419    }
420    }
421  1557 if (ref != null)
422    {
423  1557 seq.addDBRef(ref);
424    }
425  1557 return ref;
426    }
427   
428    /**
429    * accession ID and DB must be identical. Version is ignored. Map is either
430    * not defined or is a match (or is compatible?)
431    */
432    // TODO unused - remove?
433    public static DbRefComp matchDbAndIdAndEitherMap = new DbRefComp()
434    {
 
435  0 toggle @Override
436    public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode)
437    {
438  0 if (refa.getSource() != null && refb.getSource() != null
439    && DBRefUtils.getCanonicalName(refb.getSource()).equals(
440    DBRefUtils.getCanonicalName(refa.getSource())))
441    {
442    // We dont care about version
443  0 if (refa.getAccessionId() != null && refb.getAccessionId() != null
444    // FIXME should be && not || here?
445    || refb.getAccessionId().equals(refa.getAccessionId()))
446    {
447  0 if ((refa.getMap() == null || refb.getMap() == null)
448    || (refa.getMap() != null && refb.getMap() != null
449    && refb.getMap().equals(refa.getMap())))
450    {
451  0 return true;
452    }
453    }
454    }
455  0 return false;
456    }
457    };
458   
459    /**
460    * accession ID and DB must be identical. Version is ignored. No map on either
461    * or map but no maplist on either or maplist of map on a is the complement of
462    * maplist of map on b.
463    */
464    // TODO unused - remove?
465    public static DbRefComp matchDbAndIdAndComplementaryMapList = new DbRefComp()
466    {
 
467  0 toggle @Override
468    public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode)
469    {
470  0 if (refa.getSource() != null && refb.getSource() != null
471    && DBRefUtils.getCanonicalName(refb.getSource()).equals(
472    DBRefUtils.getCanonicalName(refa.getSource())))
473    {
474    // We dont care about version
475  0 if (refa.getAccessionId() != null && refb.getAccessionId() != null
476    || refb.getAccessionId().equals(refa.getAccessionId()))
477    {
478  0 if ((refa.getMap() == null && refb.getMap() == null)
479    || (refa.getMap() != null && refb.getMap() != null))
480    {
481  0 if ((refb.getMap().getMap() == null
482    && refa.getMap().getMap() == null)
483    || (refb.getMap().getMap() != null
484    && refa.getMap().getMap() != null
485    && refb.getMap().getMap().getInverse()
486    .equals(refa.getMap().getMap())))
487    {
488  0 return true;
489    }
490    }
491    }
492    }
493  0 return false;
494    }
495    };
496   
497    /**
498    * accession ID and DB must be identical. Version is ignored. No map on both
499    * or or map but no maplist on either or maplist of map on a is equivalent to
500    * the maplist of map on b.
501    */
502    // TODO unused - remove?
503    public static DbRefComp matchDbAndIdAndEquivalentMapList = new DbRefComp()
504    {
 
505  0 toggle @Override
506    public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode)
507    {
508  0 if (refa.getSource() != null && refb.getSource() != null
509    && DBRefUtils.getCanonicalName(refb.getSource()).equals(
510    DBRefUtils.getCanonicalName(refa.getSource())))
511    {
512    // We dont care about version
513    // if ((refa.getVersion()==null || refb.getVersion()==null)
514    // || refb.getVersion().equals(refa.getVersion()))
515    // {
516  0 if (refa.getAccessionId() != null && refb.getAccessionId() != null
517    || refb.getAccessionId().equals(refa.getAccessionId()))
518    {
519  0 if (refa.getMap() == null && refb.getMap() == null)
520    {
521  0 return true;
522    }
523  0 if (refa.getMap() != null && refb.getMap() != null
524    && ((refb.getMap().getMap() == null
525    && refa.getMap().getMap() == null)
526    || (refb.getMap().getMap() != null
527    && refa.getMap().getMap() != null
528    && refb.getMap().getMap()
529    .equals(refa.getMap().getMap()))))
530    {
531  0 return true;
532    }
533    }
534    }
535  0 return false;
536    }
537    };
538   
539    /**
540    * accession ID and DB must be identical, or null on a. Version is ignored. No
541    * map on either or map but no maplist on either or maplist of map on a is
542    * equivalent to the maplist of map on b.
543    */
544    public static DbRefComp matchDbAndIdAndEitherMapOrEquivalentMapList = new DbRefComp()
545    {
 
546  101835 toggle @Override
547    public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode)
548    {
549  101835 if (refa.getSource() != null && refb.getSource() != null
550    && DBRefUtils.getCanonicalName(refb.getSource()).equals(
551    DBRefUtils.getCanonicalName(refa.getSource())))
552    {
553    // We dont care about version
554  11597 if (refa.getAccessionId() == null
555    || refa.getAccessionId().equals(refb.getAccessionId()))
556    {
557  912 if (refa.getMap() == null || refb.getMap() == null)
558    {
559  888 return true;
560    }
561  24 if ((refa.getMap() != null && refb.getMap() != null)
562    && (refb.getMap().getMap() == null
563    && refa.getMap().getMap() == null)
564    || (refb.getMap().getMap() != null
565    && refa.getMap().getMap() != null
566    && (refb.getMap().getMap()
567    .equals(refa.getMap().getMap()))))
568    {
569  1 return true;
570    }
571    }
572    }
573  100946 return false;
574    }
575    };
576   
577    /**
578    * Returns the (possibly empty) list of those supplied dbrefs which have the
579    * specified source database, with a case-insensitive match of source name
580    *
581    * @param dbRefs
582    * @param source
583    * @return
584    */
 
585  0 toggle public static List<DBRefEntry> searchRefsForSource(DBRefEntry[] dbRefs,
586    String source)
587    {
588  0 List<DBRefEntry> matches = new ArrayList<>();
589  0 if (dbRefs != null && source != null)
590    {
591  0 for (DBRefEntry dbref : dbRefs)
592    {
593  0 if (source.equalsIgnoreCase(dbref.getSource()))
594    {
595  0 matches.add(dbref);
596    }
597    }
598    }
599  0 return matches;
600    }
601   
602    /**
603    * Returns true if either object is null, or they are equal
604    *
605    * @param o1
606    * @param o2
607    * @return
608    */
 
609  0 toggle public static boolean nullOrEqual(Object o1, Object o2)
610    {
611  0 if (o1 == null || o2 == null)
612    {
613  0 return true;
614    }
615  0 return o1.equals(o2);
616    }
617   
618    /**
619    * canonicalise source string before comparing. null is always wildcard
620    *
621    * @param o1
622    * - null or source string to compare
623    * @param o2
624    * - null or source string to compare
625    * @return true if either o1 or o2 are null, or o1 equals o2 under
626    * DBRefUtils.getCanonicalName
627    * (o1).equals(DBRefUtils.getCanonicalName(o2))
628    */
 
629  0 toggle public static boolean nullOrEqualSource(String o1, String o2)
630    {
631  0 if (o1 == null || o2 == null)
632    {
633  0 return true;
634    }
635  0 return DBRefUtils.getCanonicalName(o1)
636    .equals(DBRefUtils.getCanonicalName(o2));
637    }
638   
639    /**
640    * Selects just the DNA or protein references from a set of references
641    *
642    * @param selectDna
643    * if true, select references to 'standard' DNA databases, else to
644    * 'standard' peptide databases
645    * @param refs
646    * a set of references to select from
647    * @return
648    */
 
649  14530 toggle public static List<DBRefEntry> selectDbRefs(boolean selectDna,
650    List<DBRefEntry> refs)
651    {
652  14530 return selectRefs(refs,
653  14530 selectDna ? DBRefSource.DNACODINGDBS : DBRefSource.PROTEINDBS);
654    // could attempt to find other cross
655    // refs here - ie PDB xrefs
656    // (not dna, not protein seq)
657    }
658   
659    /**
660    * Returns the (possibly empty) list of those supplied dbrefs which have the
661    * specified source database, with a case-insensitive match of source name
662    *
663    * @param dbRefs
664    * @param source
665    * @return
666    */
 
667  48 toggle public static List<DBRefEntry> searchRefsForSource(
668    List<DBRefEntry> dbRefs, String source)
669    {
670  48 List<DBRefEntry> matches = new ArrayList<DBRefEntry>();
671  48 if (dbRefs != null && source != null)
672    {
673  46 for (DBRefEntry dbref : dbRefs)
674    {
675  129 if (source.equalsIgnoreCase(dbref.getSource()))
676    {
677  48 matches.add(dbref);
678    }
679    }
680    }
681  48 return matches;
682    }
683   
684    /**
685    * promote direct database references to primary for nucleotide or protein
686    * sequences if they have an appropriate primary ref
687    * <table>
688    * <tr>
689    * <th>Seq Type</th>
690    * <th>Primary DB</th>
691    * <th>Direct which will be promoted</th>
692    * </tr>
693    * <tr align=center>
694    * <td>peptides</td>
695    * <td>Ensembl</td>
696    * <td>Uniprot</td>
697    * </tr>
698    * <tr align=center>
699    * <td>peptides</td>
700    * <td>Ensembl</td>
701    * <td>Uniprot</td>
702    * </tr>
703    * <tr align=center>
704    * <td>dna</td>
705    * <td>Ensembl</td>
706    * <td>ENA</td>
707    * </tr>
708    * </table>
709    *
710    * @param sequence
711    */
 
712  288 toggle public static void ensurePrimaries(SequenceI sequence,
713    List<DBRefEntry> pr)
714    {
715  288 if (pr.size() == 0)
716    {
717    // nothing to do
718  268 return;
719    }
720  20 int sstart = sequence.getStart();
721  20 int send = sequence.getEnd();
722  20 boolean isProtein = sequence.isProtein();
723  20 BitSet bsSelect = new BitSet();
724   
725    // List<DBRefEntry> selfs = new ArrayList<DBRefEntry>();
726    // {
727   
728    // List<DBRefEntry> selddfs = selectDbRefs(!isprot, sequence.getDBRefs());
729    // if (selfs == null || selfs.size() == 0)
730    // {
731    // // nothing to do
732    // return;
733    // }
734   
735  20 List<DBRefEntry> dbrefs = sequence.getDBRefs();
736  20 bsSelect.set(0, dbrefs.size());
737   
738  20 if (!selectRefsBS(dbrefs, isProtein ? DBRefSource.PROTEIN_MASK
739    : DBRefSource.DNA_CODING_MASK, bsSelect))
740  2 return;
741   
742    // selfs.addAll(selfArray);
743    // }
744   
745    // filter non-primary refs
746  42 for (int ip = pr.size(); --ip >= 0;)
747    {
748  24 DBRefEntry p = pr.get(ip);
749  268 for (int i = bsSelect.nextSetBit(0); i >= 0; i = bsSelect
750    .nextSetBit(i + 1))
751    {
752  244 if (dbrefs.get(i) == p)
753  3 bsSelect.clear(i);
754    }
755    // while (selfs.contains(p))
756    // {
757    // selfs.remove(p);
758    // }
759    }
760    // List<DBRefEntry> toPromote = new ArrayList<DBRefEntry>();
761   
762  20 for (int ip = pr.size(), keys = 0; --ip >= 0
763    && keys != DBRefSource.PRIMARY_MASK;)
764    {
765  19 DBRefEntry p = pr.get(ip);
766  19 if (isProtein)
767    {
768  5 switch (getCanonicalName(p.getSource()))
769    {
770  3 case DBRefSource.UNIPROT:
771  3 keys |= DBRefSource.UNIPROT_MASK;
772  3 break;
773  0 case DBRefSource.ENSEMBL:
774  0 keys |= DBRefSource.ENSEMBL_MASK;
775  0 break;
776    }
777    }
778    else
779    {
780    // TODO: promote transcript refs ??
781    }
782  19 if (keys == 0 || !selectRefsBS(dbrefs, keys, bsSelect))
783  17 return;
784    // if (candidates != null)
785    {
786  8 for (int ic = bsSelect.nextSetBit(0); ic >= 0; ic = bsSelect
787    .nextSetBit(ic + 1))
788    // for (int ic = 0, n = candidates.size(); ic < n; ic++)
789    {
790  6 DBRefEntry cand = dbrefs.get(ic);// candidates.get(ic);
791  6 if (cand.hasMap())
792    {
793  0 Mapping map = cand.getMap();
794  0 SequenceI cto = map.getTo();
795  0 if (cto != null && cto != sequence)
796    {
797    // can't promote refs with mappings to other sequences
798  0 continue;
799    }
800  0 MapList mlist = map.getMap();
801  0 if (mlist.getFromLowest() != sstart
802    && mlist.getFromHighest() != send)
803    {
804    // can't promote refs with mappings from a region of this sequence
805    // - eg CDS
806  0 continue;
807    }
808    }
809    // and promote - not that version must be non-null here,
810    // as p must have passed isPrimaryCandidate()
811  6 cand.setVersion(cand.getVersion() + " (promoted)");
812  6 bsSelect.clear(ic);
813    // selfs.remove(cand);
814    // toPromote.add(cand);
815  6 if (!cand.isPrimaryCandidate())
816    {
817  3 if (Console.isDebugEnabled())
818    {
819  0 Console.debug(
820    "Warning: Couldn't promote dbref " + cand.toString()
821    + " for sequence " + sequence.toString());
822    }
823    }
824    }
825    }
826    }
827    }
828   
829    }