updated to jalview 2.1 and begun ArchiveClient/VamsasClient/VamsasStore updates.
[jalview.git] / src / jalview / analysis / SequenceIdMatcher.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2006 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.analysis;
20
21 import java.util.*;
22
23 import jalview.datamodel.*;
24
25 /**
26  * <p>Title: </p>
27  * SequenceIdMatcher
28  * <p>Description: </p>
29  * Routine which does approximate Sequence Id resolution by name using
30  * string containment (on word boundaries) rather than equivalence
31  * <p>Copyright: Copyright (c) 2004</p>
32  *
33  * <p>Company: Dundee University</p>
34  *
35  * @author not attributable
36  * @version 1.0
37  */
38 public class SequenceIdMatcher
39 {
40   private Hashtable names;
41
42   public SequenceIdMatcher(SequenceI[] seqs)
43   {
44     names = new Hashtable();
45     for (int i = 0; i < seqs.length; i++)
46     {
47       names.put(new SeqIdName(seqs[i].getName()), seqs[i]);
48     }
49   }
50
51   SequenceI findIdMatch(SequenceI seq)
52   {
53     SeqIdName nam = new SeqIdName(seq.getName());
54
55     if (names.containsKey(nam))
56     {
57       return (SequenceI) names.get(nam);
58     }
59
60     return null;
61   }
62
63   SequenceI findIdMatch(String seqnam)
64   {
65     SeqIdName nam = new SeqIdName(seqnam);
66
67     if (names.containsKey(nam))
68     {
69       return (SequenceI) names.get(nam);
70     }
71
72     return null;
73   }
74
75   /**
76    * findIdMatch
77    *
78    * Return pointers to sequences (or sequence object containers)
79    * which have same Id as a given set of different sequence objects
80    *
81    * @param seqs SequenceI[]
82    * @return SequenceI[]
83    */
84   SequenceI[] findIdMatch(SequenceI[] seqs)
85   {
86     SequenceI[] namedseqs = null;
87     int i = 0;
88     SeqIdName nam;
89
90     if (seqs.length > 0)
91     {
92       namedseqs = new SequenceI[seqs.length];
93       do
94       {
95         nam = new SeqIdName(seqs[i].getName());
96
97         if (names.containsKey(nam))
98         {
99           namedseqs[i] = (SequenceI) names.get(nam);
100         }
101         else
102         {
103           namedseqs[i] = null;
104         }
105       }
106       while (++i < seqs.length);
107     }
108
109     return namedseqs;
110   }
111
112   private class SeqIdName
113   {
114     String id;
115
116     SeqIdName(String s)
117     {
118       if (s!=null)
119         id = new String(s);
120       else
121         id = "";
122     }
123
124     public int hashCode()
125     {
126       return ((id.length()>=4) ? id.substring(0, 4).hashCode() : id.hashCode());
127     }
128
129     public boolean equals(Object s)
130     {
131       if (s instanceof SeqIdName)
132       {
133         return this.equals( (SeqIdName) s);
134       }
135       else
136       {
137         if (s instanceof String)
138         {
139           return this.equals( (String) s);
140         }
141       }
142
143       return false;
144     }
145
146     /**
147      * Characters that define the end of a unique sequence ID at
148      * the beginning of an arbitrary ID string
149      * JBPNote: This is a heuristic that will fail for arbritrarily extended sequence id's
150      * (like portions of an aligned set of repeats from one sequence)
151      */
152     private String WORD_SEP="~. |#\\/<>!\"£$%^*)}[@',?";
153
154    /**
155     * matches if one ID properly contains another at a whitespace boundary.
156     * TODO: (JBPNote) These are not efficient. should use char[] for speed
157     * todo: (JBPNote) Set separator characters appropriately
158     * @param s SeqIdName
159     * @return boolean
160     */
161     public boolean equals(SeqIdName s)
162     {
163       if (id.length()>s.id.length()) {
164         return id.startsWith(s.id) ?
165             (WORD_SEP.indexOf(id.charAt(s.id.length()))>-1)
166             : false;
167       } else
168         return s.id.startsWith(id) ?
169             (s.id.equals(id) ? true :
170              (WORD_SEP.indexOf(s.id.charAt(id.length()))>-1))
171             : false;
172     }
173
174     public boolean equals(String s)
175     {
176       if (id.length()>s.length()) {
177         return id.startsWith(s) ?
178             (WORD_SEP.indexOf(id.charAt(s.length()))>-1)
179             : false;
180       } else
181         return s.startsWith(id) ?
182             (s.equals(id) ? true :
183              (WORD_SEP.indexOf(s.charAt(id.length()))>-1))
184             : false;
185     }
186   }
187 }