reinstated proper case insensitive searching for both upper and lower case
[jalview.git] / src / jalview / analysis / Finder.java
1 package jalview.analysis;
2
3 import java.util.*;
4
5 import jalview.datamodel.*;
6
7 public class Finder
8 {
9   /**
10    * Implements the search algorithms for the Find dialog box.
11    */
12   SearchResults searchResults;
13   AlignmentI alignment;
14   jalview.datamodel.SequenceGroup selection = null;
15   Vector idMatch = null;
16   boolean caseSensitive = false;
17   boolean findAll = false;
18   com.stevesoft.pat.Regex regex = null;
19   /**
20    * hold's last-searched position between calles to find(false)
21    */
22   int seqIndex = 0, resIndex = 0;
23   public Finder(AlignmentI alignment, SequenceGroup selection)
24   {
25     this.alignment = alignment;
26     this.selection = selection;
27   }
28
29   public Finder(AlignmentI alignment, SequenceGroup selectionGroup,
30                 int seqIndex, int resIndex)
31   {
32     this(alignment, selectionGroup);
33     this.seqIndex = seqIndex;
34     this.resIndex = resIndex;
35   }
36
37   public boolean find(String searchString)
38   {
39     boolean hasResults = false;
40     if (!caseSensitive)
41     {
42       searchString = searchString.toUpperCase();
43     }
44     regex = new com.stevesoft.pat.Regex(searchString);
45     searchResults = new SearchResults();
46     idMatch = new Vector();
47     Sequence seq;
48     String item = null;
49     boolean found = false;
50
51     ////// is the searchString a residue number?
52     try
53     {
54       int res = Integer.parseInt(searchString);
55       found = true;
56       if (selection == null || selection.getSize() < 1)
57       {
58         seq = (Sequence) alignment.getSequenceAt(0);
59       }
60       else
61       {
62         seq = (Sequence) (selection.getSequenceAt(0));
63       }
64
65       searchResults.addResult(seq, res, res);
66       hasResults = true;
67     }
68     catch (NumberFormatException ex)
69     {
70     }
71
72     ///////////////////////////////////////////////
73
74     int end = alignment.getHeight();
75
76     if (selection != null)
77     {
78       if ( (selection.getSize() < 1) ||
79           ( (selection.getEndRes() - selection.getStartRes()) < 2))
80       {
81         selection = null;
82       }
83     }
84
85     while (!found && (seqIndex < end))
86     {
87       seq = (Sequence) alignment.getSequenceAt(seqIndex);
88
89       if ( (selection != null) && !selection.getSequences(null).contains(seq))
90       {
91         seqIndex++;
92         resIndex = 0;
93
94         continue;
95       }
96
97       item = seq.getSequenceAsString();
98       if(!caseSensitive)
99         item = item.toUpperCase();
100
101       if ( (selection != null) &&
102           (selection.getEndRes() < alignment.getWidth() - 1))
103       {
104         item = item.substring(0, selection.getEndRes() + 1);
105       }
106
107       ///Shall we ignore gaps???? - JBPNote: Add Flag for forcing this or not
108       StringBuffer noGapsSB = new StringBuffer();
109       int insertCount = 0;
110       Vector spaces = new Vector();
111
112       for (int j = 0; j < item.length(); j++)
113       {
114         if (!jalview.util.Comparison.isGap(item.charAt(j)))
115         {
116           noGapsSB.append(item.charAt(j));
117           spaces.addElement(new Integer(insertCount));
118         }
119         else
120         {
121           insertCount++;
122         }
123       }
124
125       String noGaps = noGapsSB.toString();
126
127       for (int r = resIndex; r < noGaps.length(); r++)
128       {
129
130         if (regex.searchFrom(noGaps, r))
131         {
132           resIndex = regex.matchedFrom();
133
134           if ( (selection != null) &&
135               ( (resIndex +
136                  Integer.parseInt(spaces.elementAt(resIndex).toString())) <
137                selection.getStartRes()))
138           {
139             continue;
140           }
141
142           int sres = seq.findPosition(resIndex +
143                                       Integer.parseInt(spaces.elementAt(
144               resIndex)
145               .toString()));
146           int eres = seq.findPosition(regex.matchedTo() - 1 +
147                                       Integer.parseInt(spaces.elementAt(regex.
148               matchedTo() -
149               1).toString()));
150
151           searchResults.addResult(seq, sres, eres);
152           hasResults = true;
153           if (!findAll)
154           {
155             // thats enough, break and display the result
156             found = true;
157             resIndex++;
158
159             break;
160           }
161
162           r = resIndex;
163         }
164         else
165         {
166           break;
167         }
168       }
169
170       if (!found)
171       {
172         seqIndex++;
173         resIndex = 0;
174       }
175     }
176
177     for (int id = 0; id < alignment.getHeight(); id++)
178     {
179       if (regex.search(alignment.getSequenceAt(id).getName()))
180       {
181         idMatch.addElement(alignment.getSequenceAt(id));
182         hasResults = true;
183       }
184     }
185     return hasResults;
186   }
187
188   /**
189    * @return the alignment
190    */
191   public AlignmentI getAlignment()
192   {
193     return alignment;
194   }
195
196   /**
197    * @param alignment the alignment to set
198    */
199   public void setAlignment(AlignmentI alignment)
200   {
201     this.alignment = alignment;
202   }
203
204   /**
205    * @return the caseSensitive
206    */
207   public boolean isCaseSensitive()
208   {
209     return caseSensitive;
210   }
211
212   /**
213    * @param caseSensitive the caseSensitive to set
214    */
215   public void setCaseSensitive(boolean caseSensitive)
216   {
217     this.caseSensitive = caseSensitive;
218   }
219
220   /**
221    * @return the findAll
222    */
223   public boolean isFindAll()
224   {
225     return findAll;
226   }
227
228   /**
229    * @param findAll the findAll to set
230    */
231   public void setFindAll(boolean findAll)
232   {
233     this.findAll = findAll;
234   }
235
236   /**
237    * @return the selection
238    */
239   public jalview.datamodel.SequenceGroup getSelection()
240   {
241     return selection;
242   }
243
244   /**
245    * @param selection the selection to set
246    */
247   public void setSelection(jalview.datamodel.SequenceGroup selection)
248   {
249     this.selection = selection;
250   }
251
252   /**
253    * @return the idMatch
254    */
255   public Vector getIdMatch()
256   {
257     return idMatch;
258   }
259
260   /**
261    * @return the regex
262    */
263   public com.stevesoft.pat.Regex getRegex()
264   {
265     return regex;
266   }
267
268   /**
269    * @return the searchResults
270    */
271   public SearchResults getSearchResults()
272   {
273     return searchResults;
274   }
275
276   /**
277    * @return the resIndex
278    */
279   public int getResIndex()
280   {
281     return resIndex;
282   }
283
284   /**
285    * @param resIndex the resIndex to set
286    */
287   public void setResIndex(int resIndex)
288   {
289     this.resIndex = resIndex;
290   }
291
292   /**
293    * @return the seqIndex
294    */
295   public int getSeqIndex()
296   {
297     return seqIndex;
298   }
299
300   /**
301    * @param seqIndex the seqIndex to set
302    */
303   public void setSeqIndex(int seqIndex)
304   {
305     this.seqIndex = seqIndex;
306   }
307 }