added a more general DBRef search interface
[jalview.git] / src / jalview / util / DBRefUtils.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19 package jalview.util;
20
21 import java.util.*;
22
23 import jalview.datamodel.*;
24
25 public class DBRefUtils
26 {
27   /**
28    * Utilities for handling DBRef objects and their collections.
29    */
30   /**
31    *
32    * @param dbrefs Vector of DBRef objects to search
33    * @param sources String[] array of source DBRef IDs to retrieve
34    * @return Vector
35    */
36   public static DBRefEntry[] selectRefs(DBRefEntry[] dbrefs, String[] sources)
37   {
38     if (dbrefs == null)
39     {
40       return null;
41     }
42     if (sources == null)
43     {
44       return dbrefs;
45     }
46     Hashtable srcs = new Hashtable();
47     Vector res = new Vector();
48
49     for (int i = 0; i < sources.length; i++)
50     {
51       srcs.put(new String(sources[i]), new Integer(i));
52     }
53     for (int i = 0, j = dbrefs.length; i < j; i++)
54     {
55       if (srcs.containsKey(dbrefs[i].getSource()))
56       {
57         res.addElement(dbrefs[i]);
58       }
59     }
60
61     if (res.size() > 0)
62     {
63       DBRefEntry[] reply = new DBRefEntry[res.size()];
64       for (int i = 0; i < res.size(); i++)
65       {
66         reply[i] = (DBRefEntry) res.elementAt(i);
67       }
68       return reply;
69     }
70     res = null;
71     // there are probable  memory leaks in the hashtable!
72     return null;
73   }
74
75   /**
76    * isDasCoordinateSystem
77    *
78    * @param string String
79    * @param dBRefEntry DBRefEntry
80    * @return boolean true if Source DBRefEntry is compatible with DAS CoordinateSystem name
81    */
82   public static Hashtable DasCoordinateSystemsLookup = null;
83   public static boolean isDasCoordinateSystem(String string,
84                                               DBRefEntry dBRefEntry)
85   {
86     if (DasCoordinateSystemsLookup == null)
87     { // Initialise
88       DasCoordinateSystemsLookup = new Hashtable();
89       DasCoordinateSystemsLookup.put("pdbresnum",
90                                      jalview.datamodel.DBRefSource.PDB);
91       DasCoordinateSystemsLookup.put("uniprot",
92                                      jalview.datamodel.DBRefSource.UNIPROT);
93       DasCoordinateSystemsLookup.put("EMBL",
94               jalview.datamodel.DBRefSource.EMBL);
95       //DasCoordinateSystemsLookup.put("EMBL",
96       //        jalview.datamodel.DBRefSource.EMBLCDS);
97     }
98
99     String coordsys = (String) DasCoordinateSystemsLookup.get(string.
100         toLowerCase());
101     if (coordsys != null)
102     {
103       return coordsys.equals(dBRefEntry.getSource());
104     }
105     return false;
106   }
107   public static Hashtable CanonicalSourceNameLookup=null;
108   /**
109    * look up source in an internal list of database reference sources
110    * and return the canonical jalview name for the source, or the original
111    * string if it has no canonical form.
112    * @param source
113    * @return canonical jalview source (one of jalview.datamodel.DBRefSource.*) or original source
114    */
115   public static String getCanonicalName(String source)
116   {
117     if (CanonicalSourceNameLookup==null) {
118       CanonicalSourceNameLookup = new Hashtable();
119       CanonicalSourceNameLookup.put("uniprotkb/swiss-prot", jalview.datamodel.DBRefSource.UNIPROT);
120       CanonicalSourceNameLookup.put("uniprotkb/trembl", jalview.datamodel.DBRefSource.UNIPROT);
121       CanonicalSourceNameLookup.put("pdb", jalview.datamodel.DBRefSource.PDB);
122     }
123     String canonical = (String) CanonicalSourceNameLookup.get(source.
124         toLowerCase());
125     if (canonical==null)
126     {
127       return source;
128     }
129     return canonical;
130   }
131   /**
132    * find RefEntry corresponding to a particular pattern
133    * the equals method of each entry is used, from String attributes right down to Mapping attributes.
134    * @param ref Set of references to search
135    * @param entry pattern to collect - null any entry for wildcard match
136    * @return
137    */
138   public static DBRefEntry[] searchRefs(DBRefEntry[] ref, DBRefEntry entry)
139   {
140     return searchRefs(ref, entry, matchDbAndIdAndEitherMapOrEquivalentMapList);
141   }
142   public static DBRefEntry[] searchRefs(DBRefEntry[] ref, DBRefEntry entry, DbRefComp comparator)
143   {
144     if (ref==null || entry==null)
145       return null;
146     Vector rfs = new Vector();
147     for (int i=0; i<ref.length;i++)
148     {
149       if (comparator.matches(entry, ref[i]))
150       {
151               rfs.addElement(ref[i]);
152       }
153     }
154     // TODO Auto-generated method stub
155     if (rfs.size()>0)
156     {
157       DBRefEntry[] rf = new DBRefEntry[rfs.size()];
158       rfs.copyInto(rf);
159       return rf;
160     }
161     return null;
162   }
163   public interface DbRefComp {
164     public boolean matches(DBRefEntry refa, DBRefEntry refb);
165   }
166   public static DbRefComp matchNonNullonA = new DbRefComp()
167     {
168           public boolean matches(DBRefEntry refa, DBRefEntry refb)
169           {
170             if (refa.getSource()==null || refb.getSource().equals(refa.getSource()))
171             {
172               if (refa.getVersion()==null || refb.getVersion().equals(refa.getVersion()))
173               {
174                 if (refa.getAccessionId()==null || refb.getAccessionId().equals(refa.getAccessionId()))
175                 {
176                   if (refa.getMap()==null || (refb.getMap()!=null && refb.getMap().equals(refa.getMap())))
177                   {
178                     return true; 
179                   }
180                 }
181               }
182             }
183             return false;
184           }
185     };
186     /**
187      * either field is null or field matches for all of source, version, accession id and map.
188      */
189     public static DbRefComp matchEitherNonNull = new DbRefComp()
190     {
191           public boolean matches(DBRefEntry refa, DBRefEntry refb)
192           {
193             if ((refa.getSource()==null || refb.getSource()==null) 
194                     || refb.getSource().equals(refa.getSource()))
195             {
196               if ((refa.getVersion()==null || refb.getVersion()==null) 
197                       || refb.getVersion().equals(refa.getVersion()))
198               {
199                 if ((refa.getAccessionId()==null || refb.getAccessionId()==null) 
200                         || refb.getAccessionId().equals(refa.getAccessionId()))
201                 {
202                   if ((refa.getMap()==null || refb.getMap()==null) 
203                           || (refb.getMap()!=null && refb.getMap().equals(refa.getMap())))
204                   {
205                     return true; 
206                   }
207                 }
208               }
209             }
210             return false;
211           }
212     };
213     /**
214      * accession ID and DB must be identical. Version is ignored. Map is either not defined or is a match (or is compatible?)
215      */
216     public static DbRefComp matchDbAndIdAndEitherMap = new DbRefComp()
217     {
218           public boolean matches(DBRefEntry refa, DBRefEntry refb)
219           {
220             if (refa.getSource()!=null && refb.getSource()!=null 
221                     && refb.getSource().equals(refa.getSource()))
222             {
223               // We dont care about version
224               //if ((refa.getVersion()==null || refb.getVersion()==null) 
225               //        || refb.getVersion().equals(refa.getVersion()))
226               //{
227               if (refa.getAccessionId()!=null && refb.getAccessionId()!=null 
228                       || refb.getAccessionId().equals(refa.getAccessionId()))
229                 {
230                   if ((refa.getMap()==null || refb.getMap()==null) 
231                           || (refa.getMap()!=null && refb.getMap()!=null && refb.getMap().equals(refa.getMap())))
232                   {
233                     return true; 
234                   }
235                 }
236               }
237             return false;
238           }
239     };
240     /**
241      * accession ID and DB must be identical. Version is ignored. 
242      * No map on either or map but no maplist on either or maplist of map on a is the complement of maplist of map on b.
243      */
244     public static DbRefComp matchDbAndIdAndComplementaryMapList = new DbRefComp()
245     {
246           public boolean matches(DBRefEntry refa, DBRefEntry refb)
247           {
248             if (refa.getSource()!=null && refb.getSource()!=null 
249                     && refb.getSource().equals(refa.getSource()))
250             {
251               // We dont care about version
252               //if ((refa.getVersion()==null || refb.getVersion()==null) 
253               //        || refb.getVersion().equals(refa.getVersion()))
254               //{
255               if (refa.getAccessionId()!=null && refb.getAccessionId()!=null 
256                       || refb.getAccessionId().equals(refa.getAccessionId()))
257                 {
258                   if ((refa.getMap()==null && refb.getMap()==null) 
259                           || (refa.getMap()!=null && refb.getMap()!=null))
260                     if ((refb.getMap().getMap()==null && refa.getMap().getMap()==null)
261                             || (refb.getMap().getMap()!=null && refa.getMap().getMap()!=null
262                             && refb.getMap().getMap().getInverse().equals(refa.getMap().getMap())))
263                   {
264                     return true; 
265                   }
266                 }
267               }
268             return false;
269           }
270     };
271     /**
272      * accession ID and DB must be identical. Version is ignored. 
273      * No map on both or or map but no maplist on either or maplist of map on a is equivalent to the maplist of map on b.
274      */
275     public static DbRefComp matchDbAndIdAndEquivalentMapList = new DbRefComp()
276     {
277           public boolean matches(DBRefEntry refa, DBRefEntry refb)
278           {
279             if (refa.getSource()!=null && refb.getSource()!=null 
280                     && refb.getSource().equals(refa.getSource()))
281             {
282               // We dont care about version
283               //if ((refa.getVersion()==null || refb.getVersion()==null) 
284               //        || refb.getVersion().equals(refa.getVersion()))
285               //{
286               if (refa.getAccessionId()!=null && refb.getAccessionId()!=null 
287                       || refb.getAccessionId().equals(refa.getAccessionId()))
288                 {
289                   if (refa.getMap()==null && refb.getMap()==null)
290                   {
291                     return true;
292                   }
293                   if (refa.getMap()!=null && refb.getMap()!=null
294                           && ((refb.getMap().getMap()==null && refa.getMap().getMap()==null)
295                             || (refb.getMap().getMap()!=null && refa.getMap().getMap()!=null
296                             && refb.getMap().getMap().equals(refa.getMap().getMap()))))
297                   {
298                     return true; 
299                   }
300                 }
301               }
302             return false;
303           }
304     };
305     /**
306      * accession ID and DB must be identical. Version is ignored. 
307      * No map on either or map but no maplist on either or maplist of map on a is equivalent to the maplist of map on b.
308      */
309     public static DbRefComp matchDbAndIdAndEitherMapOrEquivalentMapList = new DbRefComp()
310     {
311           public boolean matches(DBRefEntry refa, DBRefEntry refb)
312           {
313             if (refa.getSource()!=null && refb.getSource()!=null 
314                     && refb.getSource().equals(refa.getSource()))
315             {
316               // We dont care about version
317               //if ((refa.getVersion()==null || refb.getVersion()==null) 
318               //        || refb.getVersion().equals(refa.getVersion()))
319               //{
320               if (refa.getAccessionId()!=null && refb.getAccessionId()!=null 
321                       && refb.getAccessionId().equals(refa.getAccessionId()))
322                 {
323                   if (refa.getMap()==null || refb.getMap()==null)
324                   {
325                     return true;
326                   }
327                   if ((refa.getMap()!=null && refb.getMap()!=null)
328                           && (refb.getMap().getMap()==null && refa.getMap().getMap()==null)
329                             || (refb.getMap().getMap()!=null && refa.getMap().getMap()!=null
330                             && refb.getMap().getMap().equals(refa.getMap().getMap())))
331                   {
332                     return true; 
333                   }
334                 }
335               }
336             return false;
337           }
338     };
339         
340           
341 }