Clover icon

Coverage Report

  1. Project Clover database Thu Dec 4 2025 16:11:35 GMT
  2. Package jalview.util

File DBRefUtils.java

 

Coverage histogram

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

Code metrics

134
181
23
2
837
513
157
0.87
7.87
11.5
6.83

Classes

Class Line # Actions
DBRefUtils 43 180 156
0.613095261.3%
DBRefUtils.DbRefComp 295 1 1
0.00%
 

Contributing tests

This file is covered by 290 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  54 toggle static
64    {
65    // TODO load these from a resource file?
66  54 canonicalSourceNameLookup.put("uniprotkb/swiss-prot",
67    DBRefSource.UNIPROT);
68  54 canonicalSourceNameLookup.put("uniprotkb/trembl", DBRefSource.UNIPROT);
69   
70    // Ensembl values for dbname in xref REST service:
71  54 canonicalSourceNameLookup.put("uniprot/sptrembl", DBRefSource.UNIPROT);
72  54 canonicalSourceNameLookup.put("uniprot/swissprot", DBRefSource.UNIPROT);
73   
74  54 canonicalSourceNameLookup.put("pdb", DBRefSource.PDB);
75    // PDBe is a 3D-Beacons provider
76  54 canonicalSourceNameLookup.put("pdbe", DBRefSource.PDB);
77   
78  54 canonicalSourceNameLookup.put("ensembl", DBRefSource.ENSEMBL);
79    // Ensembl Gn and Tr are for Ensembl genomic and transcript IDs as served
80    // from ENA.
81  54 canonicalSourceNameLookup.put("ensembl-tr", DBRefSource.ENSEMBL);
82  54 canonicalSourceNameLookup.put("ensembl-gn", DBRefSource.ENSEMBL);
83   
84    // guarantee we always have lowercase entries for canonical string lookups
85  54 for (String k : canonicalSourceNameLookup.keySet())
86    {
87  486 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  14514 toggle public static List<DBRefEntry> selectRefs(List<DBRefEntry> dbrefs,
104    String[] sources)
105    {
106  14514 if (dbrefs == null || sources == null)
107    {
108  10517 return dbrefs;
109    }
110   
111    // BH TODO (what?)
112  3997 HashSet<String> srcs = new HashSet<String>();
113  3997 for (String src : sources)
114    {
115  17800 srcs.add(src.toUpperCase(Locale.ROOT));
116    }
117   
118  3997 int nrefs = dbrefs.size();
119  3997 List<DBRefEntry> res = new ArrayList<DBRefEntry>();
120  28328 for (int ib = 0; ib < nrefs; ib++)
121    {
122  24331 DBRefEntry dbr = dbrefs.get(ib);
123  24331 String source = getCanonicalName(dbr.getSource());
124  24331 if (srcs.contains(source.toUpperCase(Locale.ROOT)))
125    {
126  3776 res.add(dbr);
127    }
128    }
129  3997 if (res.size() > 0)
130    {
131    // List<DBRefEntry> reply = new DBRefEntry[res.size()];
132  2268 return res;// .toArray(reply);
133    }
134  1729 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  337228 toggle public static String getCanonicalName(String source)
194    {
195  337229 if (source == null)
196    {
197  1 return null;
198    }
199  337228 String canonical = canonicalSourceNameLookup
200    .get(source.toLowerCase(Locale.ROOT));
201  337227 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    private static Regex PARSE_REGEX;
360   
 
361  27 toggle private static Regex getParseRegex()
362    {
363  27 return (PARSE_REGEX == null ? PARSE_REGEX = Platform.newRegex(
364    "([0-9][0-9A-Za-z]{3})\\s*(.?)\\s*;\\s*([0-9]+)-([0-9]+)")
365    : PARSE_REGEX);
366    }
367   
368    /**
369    * Parses a DBRefEntry and adds it to the sequence, also a PDBEntry if the
370    * database is PDB.
371    * <p>
372    * Used by file parsers to generate DBRefs from annotation within file (eg
373    * Stockholm)
374    *
375    * @param dbname
376    * @param version
377    * @param acn
378    * @param seq
379    * where to annotate with reference
380    * @return parsed version of entry that was added to seq (if any)
381    */
 
382  1563 toggle public static DBRefEntry parseToDbRef(SequenceI seq, String dbname,
383    String version, String acn)
384    {
385  1563 DBRefEntry ref = null;
386  1563 if (dbname != null)
387    {
388  1563 String locsrc = DBRefUtils.getCanonicalName(dbname);
389  1563 if (locsrc.equals(DBRefSource.PDB))
390    {
391    /*
392    * Check for PFAM style stockhom PDB accession id citation e.g.
393    * "1WRI A; 7-80;"
394    */
395  27 Regex r = getParseRegex();
396  27 if (r.search(acn.trim()))
397    {
398  27 String pdbid = r.stringMatched(1);
399  27 String chaincode = r.stringMatched(2);
400  27 if (chaincode == null)
401    {
402  0 chaincode = " ";
403    }
404    // String mapstart = r.stringMatched(3);
405    // String mapend = r.stringMatched(4);
406  27 if (chaincode.equals(" "))
407    {
408  0 chaincode = "_";
409    }
410    // construct pdb ref.
411  27 ref = new DBRefEntry(locsrc, version, pdbid + chaincode);
412  27 PDBEntry pdbr = new PDBEntry();
413  27 pdbr.setId(pdbid);
414  27 pdbr.setType(PDBEntry.Type.PDB);
415  27 pdbr.setChainCode(chaincode);
416  27 seq.addPDBId(pdbr);
417    }
418    else
419    {
420  0 jalview.bin.Console.errPrintln("Malformed PDB DR line:" + acn);
421    }
422    }
423    else
424    {
425    // default:
426  1536 ref = new DBRefEntry(locsrc, version, acn.trim());
427    }
428    }
429  1563 if (ref != null)
430    {
431  1563 seq.addDBRef(ref);
432    }
433  1563 return ref;
434    }
435   
436    /**
437    * accession ID and DB must be identical. Version is ignored. Map is either
438    * not defined or is a match (or is compatible?)
439    */
440    // TODO unused - remove?
441    public static DbRefComp matchDbAndIdAndEitherMap = new DbRefComp()
442    {
 
443  0 toggle @Override
444    public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode)
445    {
446  0 if (refa.getSource() != null && refb.getSource() != null
447    && DBRefUtils.getCanonicalName(refb.getSource()).equals(
448    DBRefUtils.getCanonicalName(refa.getSource())))
449    {
450    // We dont care about version
451  0 if (refa.getAccessionId() != null && refb.getAccessionId() != null
452    // FIXME should be && not || here?
453    || refb.getAccessionId().equals(refa.getAccessionId()))
454    {
455  0 if ((refa.getMap() == null || refb.getMap() == null)
456    || (refa.getMap() != null && refb.getMap() != null
457    && refb.getMap().equals(refa.getMap())))
458    {
459  0 return true;
460    }
461    }
462    }
463  0 return false;
464    }
465    };
466   
467    /**
468    * accession ID and DB must be identical. Version is ignored. No map on either
469    * or map but no maplist on either or maplist of map on a is the complement of
470    * maplist of map on b.
471    */
472    // TODO unused - remove?
473    public static DbRefComp matchDbAndIdAndComplementaryMapList = new DbRefComp()
474    {
 
475  0 toggle @Override
476    public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode)
477    {
478  0 if (refa.getSource() != null && refb.getSource() != null
479    && DBRefUtils.getCanonicalName(refb.getSource()).equals(
480    DBRefUtils.getCanonicalName(refa.getSource())))
481    {
482    // We dont care about version
483  0 if (refa.getAccessionId() != null && refb.getAccessionId() != null
484    || refb.getAccessionId().equals(refa.getAccessionId()))
485    {
486  0 if ((refa.getMap() == null && refb.getMap() == null)
487    || (refa.getMap() != null && refb.getMap() != null))
488    {
489  0 if ((refb.getMap().getMap() == null
490    && refa.getMap().getMap() == null)
491    || (refb.getMap().getMap() != null
492    && refa.getMap().getMap() != null
493    && refb.getMap().getMap().getInverse()
494    .equals(refa.getMap().getMap())))
495    {
496  0 return true;
497    }
498    }
499    }
500    }
501  0 return false;
502    }
503    };
504   
505    /**
506    * accession ID and DB must be identical. Version is ignored. No map on both
507    * or or map but no maplist on either or maplist of map on a is equivalent to
508    * the maplist of map on b.
509    */
510    // TODO unused - remove?
511    public static DbRefComp matchDbAndIdAndEquivalentMapList = new DbRefComp()
512    {
 
513  0 toggle @Override
514    public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode)
515    {
516  0 if (refa.getSource() != null && refb.getSource() != null
517    && DBRefUtils.getCanonicalName(refb.getSource()).equals(
518    DBRefUtils.getCanonicalName(refa.getSource())))
519    {
520    // We dont care about version
521    // if ((refa.getVersion()==null || refb.getVersion()==null)
522    // || refb.getVersion().equals(refa.getVersion()))
523    // {
524  0 if (refa.getAccessionId() != null && refb.getAccessionId() != null
525    || refb.getAccessionId().equals(refa.getAccessionId()))
526    {
527  0 if (refa.getMap() == null && refb.getMap() == null)
528    {
529  0 return true;
530    }
531  0 if (refa.getMap() != null && refb.getMap() != null
532    && ((refb.getMap().getMap() == null
533    && refa.getMap().getMap() == null)
534    || (refb.getMap().getMap() != null
535    && refa.getMap().getMap() != null
536    && refb.getMap().getMap()
537    .equals(refa.getMap().getMap()))))
538    {
539  0 return true;
540    }
541    }
542    }
543  0 return false;
544    }
545    };
546   
547    /**
548    * accession ID and DB must be identical, or null on a. Version is ignored. No
549    * map on either or map but no maplist on either or maplist of map on a is
550    * equivalent to the maplist of map on b.
551    */
552    public static DbRefComp matchDbAndIdAndEitherMapOrEquivalentMapList = new DbRefComp()
553    {
 
554  101835 toggle @Override
555    public boolean matches(DBRefEntry refa, DBRefEntry refb, int mode)
556    {
557  101835 if (refa.getSource() != null && refb.getSource() != null
558    && DBRefUtils.getCanonicalName(refb.getSource()).equals(
559    DBRefUtils.getCanonicalName(refa.getSource())))
560    {
561    // We dont care about version
562  11597 if (refa.getAccessionId() == null
563    || refa.getAccessionId().equals(refb.getAccessionId()))
564    {
565  912 if (refa.getMap() == null || refb.getMap() == null)
566    {
567  888 return true;
568    }
569  24 if ((refa.getMap() != null && refb.getMap() != null)
570    && (refb.getMap().getMap() == null
571    && refa.getMap().getMap() == null)
572    || (refb.getMap().getMap() != null
573    && refa.getMap().getMap() != null
574    && (refb.getMap().getMap()
575    .equals(refa.getMap().getMap()))))
576    {
577  1 return true;
578    }
579    }
580    }
581  100946 return false;
582    }
583    };
584   
585    /**
586    * Returns the (possibly empty) list of those supplied dbrefs which have the
587    * specified source database, with a case-insensitive match of source name
588    *
589    * @param dbRefs
590    * @param source
591    * @return
592    */
 
593  0 toggle public static List<DBRefEntry> searchRefsForSource(DBRefEntry[] dbRefs,
594    String source)
595    {
596  0 List<DBRefEntry> matches = new ArrayList<>();
597  0 if (dbRefs != null && source != null)
598    {
599  0 for (DBRefEntry dbref : dbRefs)
600    {
601  0 if (source.equalsIgnoreCase(dbref.getSource()))
602    {
603  0 matches.add(dbref);
604    }
605    }
606    }
607  0 return matches;
608    }
609   
610    /**
611    * Returns true if either object is null, or they are equal
612    *
613    * @param o1
614    * @param o2
615    * @return
616    */
 
617  0 toggle public static boolean nullOrEqual(Object o1, Object o2)
618    {
619  0 if (o1 == null || o2 == null)
620    {
621  0 return true;
622    }
623  0 return o1.equals(o2);
624    }
625   
626    /**
627    * canonicalise source string before comparing. null is always wildcard
628    *
629    * @param o1
630    * - null or source string to compare
631    * @param o2
632    * - null or source string to compare
633    * @return true if either o1 or o2 are null, or o1 equals o2 under
634    * DBRefUtils.getCanonicalName
635    * (o1).equals(DBRefUtils.getCanonicalName(o2))
636    */
 
637  0 toggle public static boolean nullOrEqualSource(String o1, String o2)
638    {
639  0 if (o1 == null || o2 == null)
640    {
641  0 return true;
642    }
643  0 return DBRefUtils.getCanonicalName(o1)
644    .equals(DBRefUtils.getCanonicalName(o2));
645    }
646   
647    /**
648    * Selects just the DNA or protein references from a set of references
649    *
650    * @param selectDna
651    * if true, select references to 'standard' DNA databases, else to
652    * 'standard' peptide databases
653    * @param refs
654    * a set of references to select from
655    * @return
656    */
 
657  14426 toggle public static List<DBRefEntry> selectDbRefs(boolean selectDna,
658    List<DBRefEntry> refs)
659    {
660  14426 return selectRefs(refs,
661  14426 selectDna ? DBRefSource.DNACODINGDBS : DBRefSource.PROTEINDBS);
662    // could attempt to find other cross
663    // refs here - ie PDB xrefs
664    // (not dna, not protein seq)
665    }
666   
667    /**
668    * Returns the (possibly empty) list of those supplied dbrefs which have the
669    * specified source database, with a case-insensitive match of source name
670    *
671    * @param dbRefs
672    * @param source
673    * @return
674    */
 
675  48 toggle public static List<DBRefEntry> searchRefsForSource(
676    List<DBRefEntry> dbRefs, String source)
677    {
678  48 List<DBRefEntry> matches = new ArrayList<DBRefEntry>();
679  48 if (dbRefs != null && source != null)
680    {
681  46 for (DBRefEntry dbref : dbRefs)
682    {
683  129 if (source.equalsIgnoreCase(dbref.getSource()))
684    {
685  48 matches.add(dbref);
686    }
687    }
688    }
689  48 return matches;
690    }
691   
692    /**
693    * promote direct database references to primary for nucleotide or protein
694    * sequences if they have an appropriate primary ref
695    * <table>
696    * <tr>
697    * <th>Seq Type</th>
698    * <th>Primary DB</th>
699    * <th>Direct which will be promoted</th>
700    * </tr>
701    * <tr align=center>
702    * <td>peptides</td>
703    * <td>Ensembl</td>
704    * <td>Uniprot</td>
705    * </tr>
706    * <tr align=center>
707    * <td>peptides</td>
708    * <td>Ensembl</td>
709    * <td>Uniprot</td>
710    * </tr>
711    * <tr align=center>
712    * <td>dna</td>
713    * <td>Ensembl</td>
714    * <td>ENA</td>
715    * </tr>
716    * </table>
717    *
718    * @param sequence
719    */
 
720  288 toggle public static void ensurePrimaries(SequenceI sequence,
721    List<DBRefEntry> pr)
722    {
723  288 if (pr.size() == 0)
724    {
725    // nothing to do
726  268 return;
727    }
728  20 int sstart = sequence.getStart();
729  20 int send = sequence.getEnd();
730  20 boolean isProtein = sequence.isProtein();
731  20 BitSet bsSelect = new BitSet();
732   
733    // List<DBRefEntry> selfs = new ArrayList<DBRefEntry>();
734    // {
735   
736    // List<DBRefEntry> selddfs = selectDbRefs(!isprot, sequence.getDBRefs());
737    // if (selfs == null || selfs.size() == 0)
738    // {
739    // // nothing to do
740    // return;
741    // }
742   
743  20 List<DBRefEntry> dbrefs = sequence.getDBRefs();
744  20 bsSelect.set(0, dbrefs.size());
745   
746  20 if (!selectRefsBS(dbrefs, isProtein ? DBRefSource.PROTEIN_MASK
747    : DBRefSource.DNA_CODING_MASK, bsSelect))
748  2 return;
749   
750    // selfs.addAll(selfArray);
751    // }
752   
753    // filter non-primary refs
754  42 for (int ip = pr.size(); --ip >= 0;)
755    {
756  24 DBRefEntry p = pr.get(ip);
757  268 for (int i = bsSelect.nextSetBit(0); i >= 0; i = bsSelect
758    .nextSetBit(i + 1))
759    {
760  244 if (dbrefs.get(i) == p)
761  3 bsSelect.clear(i);
762    }
763    // while (selfs.contains(p))
764    // {
765    // selfs.remove(p);
766    // }
767    }
768    // List<DBRefEntry> toPromote = new ArrayList<DBRefEntry>();
769   
770  20 for (int ip = pr.size(), keys = 0; --ip >= 0
771    && keys != DBRefSource.PRIMARY_MASK;)
772    {
773  19 DBRefEntry p = pr.get(ip);
774  19 if (isProtein)
775    {
776  5 switch (getCanonicalName(p.getSource()))
777    {
778  3 case DBRefSource.UNIPROT:
779  3 keys |= DBRefSource.UNIPROT_MASK;
780  3 break;
781  0 case DBRefSource.ENSEMBL:
782  0 keys |= DBRefSource.ENSEMBL_MASK;
783  0 break;
784    }
785    }
786    else
787    {
788    // TODO: promote transcript refs ??
789    }
790  19 if (keys == 0 || !selectRefsBS(dbrefs, keys, bsSelect))
791  17 return;
792    // if (candidates != null)
793    {
794  8 for (int ic = bsSelect.nextSetBit(0); ic >= 0; ic = bsSelect
795    .nextSetBit(ic + 1))
796    // for (int ic = 0, n = candidates.size(); ic < n; ic++)
797    {
798  6 DBRefEntry cand = dbrefs.get(ic);// candidates.get(ic);
799  6 if (cand.hasMap())
800    {
801  0 Mapping map = cand.getMap();
802  0 SequenceI cto = map.getTo();
803  0 if (cto != null && cto != sequence)
804    {
805    // can't promote refs with mappings to other sequences
806  0 continue;
807    }
808  0 MapList mlist = map.getMap();
809  0 if (mlist.getFromLowest() != sstart
810    && mlist.getFromHighest() != send)
811    {
812    // can't promote refs with mappings from a region of this sequence
813    // - eg CDS
814  0 continue;
815    }
816    }
817    // and promote - not that version must be non-null here,
818    // as p must have passed isPrimaryCandidate()
819  6 cand.setVersion(cand.getVersion() + " (promoted)");
820  6 bsSelect.clear(ic);
821    // selfs.remove(cand);
822    // toPromote.add(cand);
823  6 if (!cand.isPrimaryCandidate())
824    {
825  3 if (Console.isDebugEnabled())
826    {
827  0 Console.debug(
828    "Warning: Couldn't promote dbref " + cand.toString()
829    + " for sequence " + sequence.toString());
830    }
831    }
832    }
833    }
834    }
835    }
836   
837    }